Why `Permission denied` for `ls` and `touch` when folder have `r` and `w` permissions for everybody? [duplicate]

I am having a bit of trouble understanding what the execute permission means for directories. Do I understand it correctly that anything in a directory for which a user does not have x-rights is inaccessible even if the things inside the directory gives specific rights to the user?

Or will the user still have direct access to the things in the directory, but simply cannot list what is in the directory?

(What I am really trying to understand is how safe a directory is from access from other users if they do not have x-permission for it.)


Solution 1:

x bit for directory is also called as search bit. Actually, it enables you to access the inodes of the files listed inside the folder. So if you want to access /home/user/foo/bar.txt then you must have search access on every ancestor of bar.txt

Quoting from the page

Because directories are not used in the same way as regular files, the permissions work slightly (but only slightly) differently. An attempt to list the files in a directory requires read permission for the directory, but not on the files within. An attempt to add a file to a directory, delete a file from a directory, or to rename a file, all require write permission for the directory, but (perhaps surprisingly) not for the files within. Execute permission doesn't apply to directories (a directory can't also be a program). But that permission bit is reused for directories for other purposes.

Execute permission is needed on a directory to be able to cd into it (that is, to make some directory your current working directory).

Execute is needed on a directory to access the inode information of the files within. You need this to search a directory to read the inodes of the files within. For this reason the execute permission on a directory is often called search permission instead.

Search permission is required in many common situations. Consider the command cat /home/user/foo. This command clearly requires read permission for the file foo. But unless you have search permission on /, /home, and /home/user directories, cat can't locate the inode of foo and thus can't read it! You need search permission on every ancestor directory to access the inode of any file (or directory), and you can't read a file unless you can get to its inode.

Please read more at file permission directory section.

Update: Leo raised a very good question. If we know the inode then can we access a file from a directory having it's x bit unset? I believe, we should not be able to do so. I did not test it by c program but rather used some handy bash commands to confirm it.

user@user-desktop:~/test$ ls -lart
total 12
drwxr-xr-x 49 user user 4096 2011-11-30 22:37 ..
drwxr-xr-x  3 user user 4096 2011-11-30 22:37 .
drwxr-xr-x  2 user user 4096 2011-11-30 22:38 level1
user@user-desktop:~/test$ ls -lart level1/
total 12
drwxr-xr-x 3 user user 4096 2011-11-30 22:37 ..
drwxr-xr-x 2 user user 4096 2011-11-30 22:38 .
-rw-r--r-- 1 user user    8 2011-11-30 22:38 file1
user@user-desktop:~/test$ stat level1
  File: `level1'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 808h/2056d  Inode: 95494       Links: 2
Access: (0755/drwxr-xr-x)  Uid: ( 1000/    user)   Gid: ( 1000/    user)
Access: 2011-11-30 22:46:16.576702105 +0530
Modify: 2011-11-30 22:38:12.386701913 +0530
Change: 2011-11-30 22:46:08.876702102 +0530
user@user-desktop:~/test$ stat level1/file1 
  File: `level1/file1'
  Size: 8           Blocks: 8          IO Block: 4096   regular file
Device: 808h/2056d  Inode: 60775       Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    user)   Gid: ( 1000/    user)
Access: 2011-11-30 22:38:19.846701917 +0530
Modify: 2011-11-30 22:38:16.366701915 +0530
Change: 2011-11-30 22:38:16.366701915 +0530
user@user-desktop:~/test$ chmod -x level1
user@user-desktop:~/test$ stat level1/file1 
stat: cannot stat `level1/file1': Permission denied
user@user-desktop:~/test$ ls -lart level1/
ls: cannot access level1/..: Permission denied
ls: cannot access level1/.: Permission denied
ls: cannot access level1/file1: Permission denied
total 0
-????????? ? ? ? ?                ? file1
d????????? ? ? ? ?                ? ..
d????????? ? ? ? ?                ? .
user@user-desktop:~/test$ cat level1/file1
cat: level1/file1: Permission denied
user@user-desktop:~/test$ find . -inum 95494
./level1
user@user-desktop:~/test$ find . -inum 60775
user@user-desktop:~/test$ find ./level -inum 60775
find: `./level': No such file or directory
user@user-desktop:~/test$ find ./level1 -inum 60775

Solution 2:

Since you are asking for directories:

read means: read the contents, ie listing them with ls.

write means: write into the director. ie creating files or subdirectories.

execute means: enter into that directory.

read and execute permissions could be a bit tricky for directories.

For instance if you have read permissions but not execute, you can list the contents of the directory but can not drop into it. Also you can not list specific files or directories even though you know its names.

If you have execute permission but not read, you can drop into it but can not list the files directly. But, if you know names of the files or directories you can list them.

Solution 3:

The execute permission on directories mean:

The ability to cd into this directory, and access the files in this directory.

If you do not have the x right on your directory you cannot:

  • Enter into the directory (i.e: cd)
  • Cannot access any file in this directory (even if you know the name).

Example:

$ ls -ld testdir
drw------- 2 xxxxxx xxxxxx 14 2011-11-29 19:38 testdir

$ cd testdir
bash: cd: testdir: Permission denied

$ cat testdir/a
cat: testdir/a: Permission denied

$ chmod 700 testdir
$ cat testdir/a
Some text.

Read Linux File Permission Confusion pt 2 for a good introduction on the topic.

The only thing that the x permission does not seem to prevent is to access the names of the files in that directory.

Example:

$ ls -ld testdir
drw------- 2 xxxxxx xxxxxx 14 2011-11-29 19:38 testdir

$ ls testdir
ls: cannot access testdir/a: Permission denied
ls: cannot access testdir/b: Permission denied
a  b