22

I have a personal folder /a/b on the server with permission 700. I don't want others to list the contents in /a/b. The owner of /a is root.

Now I need to open the full authorities of directory /a/b/c to all users.

I changed the permission of /a/b/c to 777 but it is still inaccessible for others.

wsdzbm
  • 2,836
  • 2
    You need to set the 'execute bit' to allow directory traversal (to traverse /a and /a/b), this might solve your problem: chmod +x /a/b – ex0ns Aug 07 '15 at 14:09

3 Answers3

38

You can. You just have to set the executable bit on the /a/b directory. That will prevent being able to see anything in b, but you can still do everything if you go directly to a/b/c.

% mkdir -p a/b/c
% chmod 711 a/b
% sudo chown root a/b
% ll a/b
  ls: cannot open directory a/b: Permission denied
% touch a/b/c/this.txt
% ls a/b/c
  this.txt

Beware that while others cannot list the contents of /a/b, they can access files in that directory if they guess the name of the file.

% echo hello | sudo tee a/b/f
% cat a/b/f
hello
% cat a/b/doesntexist
cat: a/b/doesntexist: No such file or directory

So be sure to maintain proper permissions (no group/world) on all other files/directories within the b directory, as this will avoid this caveat.

stevieb
  • 886
  • As an alternative to setting the executiable bit, could you also provide a hard link to a/b/c that resides in another location? – Moby Disk Aug 07 '15 at 17:29
  • 2
    @MobyDisk You can't hard link to a directory. – Michael Hampton Aug 07 '15 at 17:53
  • It wouldn't work, because no matter what, you still need to read into b to link to c – stevieb Aug 07 '15 at 17:54
  • 3
    Note that there are some important caveats to this. If any of the files in a/b have nonzero group/other permissions, and an adversary knows or can guess their names, said adversary can interact with those files. – Kevin Aug 07 '15 at 20:57
  • True @Kevin, the perms for everything under b should have perms set to protect against this prior to creating c, and then diligence is needed when other items are populated into b to ensure perms are secure for only owner. – stevieb Aug 07 '15 at 21:03
9

With those permissions, you can't reach your goal. In order to get to directory c, you must allow all other users to traverse directory b which is done by giving execute permission for that directory. With /a/b set to mode 711, you can achieve what you want since you are granting directory traversal but denying read and write. But do keep in mind that while other users can't list files in /a/b, they may be access files if they guess the name and the files have sufficiently open permissions.

John
  • 17,011
3

If a user can't access /a/b, then they can't access any file under /a/b/c. The permissions on /a/b/c are irrelevant since directory traversal stops at /a/b.

If all you want is to prevent the directory /a/b from being listed, but you're fine with users accessing files in /a/b if they guess a file name, then you can make /a/b executable but not readable. On a directory, the read permission only controls listing the directory contents, while the execute permission controls access to the entries of that directory.

# chmod u=rwx,go=x /a/b
# chmod u=rwx,go=rx /a/b/c
# echo 'hello' >/a/b/existingfile
# su bob -c 'ls -l /a/b'
ls: /a/b: Permission denied
# su bob -c 'cat /a/b/nosuchfile'
cat: /a/b/nosuchfile: No such file or directory
# su bob -c 'cat /a/b/existingfile'
hello
# su bob -c 'ls -l /a/b/c'
… contents of /a/b/c …

If you don't want other users to be able to access files in /a/b except for /a/b/c, you can expose /a/b/c via another view, through a bind mount.

# chmod u=rwx,go=x /a/b
# chmod u=rwx,go=rx /a/b/c
# mkdir /c
# mount --bind /a/b/c /c
# su bob -c 'ls /a/b/c'
ls: /a/b/c: Permission denied
# su bob -c 'ls -l /c'
… contents of /a/b/c …