acl: Fix WALK_TREE_RECURSIVE for the WALK_TREE_DEREFERENCE case
PATCH 1/1 acl: Fix WALK_TREE_RECURSIVE for the WALK_TREE_DEREFERENCE case
NOTE: Sending to [email protected] instead of acl-devel since it doesn't seem active anymore.
getfacl.c calls walk_tree() with WALK_TREE_DEREFERENCE. This causes a stat() of symlinks which in turn causes S_ISDIR(st.st_mode) to be true on symlinks.
This causes getfacl -P to return the contents of symlinks...
e.g.
$ mkdir -p test/sub $ mkdir test/link $ touch test/link/file $ ln -s `pwd`/test/link test/sub/link $ getfacl -P -R test/sub
# file: test/sub
# owner: philips
# group: usersuser::rwx
group::r-x
other::r-x
# file: test/sub/link/file
# owner: philips
# group: users
user::rw-
group::r--
other::r--
After the fix:
$ getfacl -R -P test/sub/ # file: test/sub/ # owner: philips # group: users user::rwx group::r-x other::r-x
Signed-off-by Brandon Philips <[email protected]>
--- libmisc/walk_tree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
libmisc/walk_tree.c +8 -1
@@ -93,8 +93,15 @@ static int walk_tree_rec(const char *pat have_dir_stat =1 ; } err =func (path, &st, flags, arg); + +/* +* Recurse if WALK_TREE_RECURSIVE and the path is: +* a dir not from a symlink +* a link and follow_symlinks +*/ if ((flags &WALK_TREE_RECURSIVE ) && - (S_ISDIR (st.st_mode) || (S_ISLNK (st.st_mode) && follow_symlinks))) { + (!(flags &WALK_TREE_SYMLINK ) &&S_ISDIR (st.st_mode)) || + ((flags &WALK_TREE_SYMLINK ) && follow_symlinks)) {struct dirent *entry;/*