Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

In this article, we’ll be learning about how permissions apply to symbolic links.

We first will go over the relevant permissions of symbolic links. Then we’ll see how chmod and chown operate upon them.

To understand relevant symbolic link permissions, we can start by taking a look at their access permissions and ownership.

Let’s begin by creating a symbolic link pointing to a file on our Desktop. We can use su to execute the command ln as user1, which will make sure they have ownership of the created symlink.

$ su user1 -c 'ln -s "/home/user1/Desktop/subdir/file.txt" "/home/user1/links/user1_symlink"'

Then let’s use stat to print the permissions and ownership of the symlink we just created.

$ stat -c "%n | %A | %G:%U" '/home/user1/links/user1_symlink'
/home/user1/links/user1_symlink | lrwxrwxrwx | user1:user1

The symbolic notation, lrwxrwxrwx, is the only set of access permissions a symbolic link can have. Additionally, these permissions are only representative as they are never used for any operation.

Instead, it is up to the parent directory to determine how users may interact with a symlink.

Let’s see if we can access this symbolic link using the readlink command. 

$ su user2 -c 'readlink -v "/home/user1/links/user1_symlink"'
readlink: /home/user1/links/user1_symlink: Permission denied

We don’t have the correct permissions to access the symbolic link, so let’s try adding execute permissions to the directories in its path. Then we can re-execute our previous command using fc to see if we get different results.

$ chmod +x "/home/user1/links/" "/home/user1/"; fc -s -1
...
/home/user1/Desktop/subdir/file.txt

The user must have permission to access a symbolic link’s parent directory to be able to access the symlink itself.

If we want readlink to follow a symbolic link instead of just accessing it, we can use the -f flag.

$ su user2 -c 'readlink -v -f "/home/user1/links/user1_symlink"'
readlink: /home/user1/links/user1_symlink: Permission denied
$ chmod +x "/home/user1/Desktop" "/home/user1/Desktop/subdir/"; fc -s -1
...
/home/user1/Desktop/subdir/file.txt

Following a symbolic link requires us to be able to access the target file’s parent directory. If we want to actually operate on the file the symbolic link points to, we need to have the correct permissions on that file as well.

Any user may remove a symbolic link if they have execute and write privileges of its parent directory with one exception. When a symbolic link is inside a sticky directory, only its owner may delete it. This is the default behavior for any file inside a sticky directory.

There is also a rule unique to symlinks inside sticky directories that are world-writable.

$ su user1 -c 'ln -s "/home/user1/Desktop/subdir" "/tmp/user1_tmp_symlink"'
$ su user2 -c 'cd "/tmp/user1_tmp_symlink"'
bash: line 1: cd: /tmp/user1_tmp_symlink: Permission denied
$ su user2 -c 'cd "/home/user1/Desktop/subdir" && echo "${PWD}"'
/home/user1/Desktop/subdir

Here we have a user who has the correct permissions to access the target file and the symbolic link. However, when trying to dereference the symlink, they get denied.

This occurs because only the symlink’s owner may follow a symbolic link in world-writable sticky directories.

Two important commands used to apply permissions are chmod and chown. In this section, we go over how they apply to symbolic links.

Let’s start by running these commands on a symlink pointed to our Desktop directory.

$ su user1 -c 'ln -s "/home/user1/Desktop/" "/home/user1/links/user1_symlink2"'
$ chmod 740 '/home/user1/links/user1_symlink2'; chown user2:user2 "$_"
$ stat -c "%n - %a - %U:%G" '/home/user1/Desktop/' 
"/home/user1/Desktop/" - 740 - user2:user2

Symbolic links passed to chmod or chown from the command line will be followed. This will cause only the target file to be modified, not the symbolic link.

We may also modify the ownership of a symbolic link with chown.

$ chown -h user2:user2 '/home/user1/links/user1_symlink2'
$ stat -c "%n %U:%G" "$_"
/home/user1/links/user1_symlink2 - user2:user2

The -h flag prevents any symbolic link from being followed when used with chown. There is no equivalent flag for chmod since access permissions can not be edited on symbolic links.

If we want to use recursion with chmod or chown, we can use the -R flag.

$ chmod -R 740 '/home/user1/links'; chown -R user2:user2 "$_"
$ stat -c "%n - %a - %U:%G" '/home/user1/Desktop/subdir/file.txt'
/home/user1/Desktop/subdir/file.txt - 700 - user1:user1
$ chmod 740 -R '/home/user1/links'{/,/*}; chown user1:user1 -R "$_"; fc -s -1
...
/home/user1/Desktop/subdir/file.txt - 740 - user1:user1

As we can see, chmod does not traverse symbolic links that are found using recursion unless they are explicitly passed through the command line. This works with passing a specific file manually but also works with Bash filename expansion.

chown, on the other hand, will not traverse any symbolic link during recursion, even when passed as an argument on the command line. Instead, if we want chown to traverse symbolic links during recursion, we can use the -H flag.

$ chown -R -H user2:user2 '/home/user1/links/'*
$ stat -c "%n - %U:%G" '/home/user1/Desktop/subdir/file.txt'
/home/user1/Desktop/subdir/file.txt - user2:user2

When using -H with chown symbolic links passed on the command line will be traversed.

This flag is just one of three flags used with -R when applying permissions using chown.

The second flag is the -L flag and causes all symlinks to be traversed during recursion. Finally, the -P flag is the default behavior when using -R and prevents any symbolic link from being dereferenced during recursion.

4. Conclusion

In conclusion, symbolic links have irrelevant access permissions. Users are only prevented from operating on a symlink by the permissions of its parent directory and the target file.

Passing a symlink specifically to chown or chmod will cause the target file to be operated on. If we want to traverse symbolic links recursively, we must use the -H or -L flag with chown or pass them as command-line arguments to chmod.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!