166

I am facing some issue with creating soft links. Following is the original file.

$ ls -l /etc/init.d/jboss
-rwxr-xr-x 1 askar admin 4972 Mar 11  2014 /etc/init.d/jboss

Link creation is failing with a permission issue for the owner of the file:

ln -sv  jboss /etc/init.d/jboss1
ln: creating symbolic link `/etc/init.d/jboss1': Permission denied

$ id
uid=689(askar) gid=500(admin) groups=500(admin)

So, I created the link with sudo privileges:

$ sudo ln -sv  jboss /etc/init.d/jboss1
`/etc/init.d/jboss1' -> `jboss'

$ ls -l /etc/init.d/jboss1
  lrwxrwxrwx 1 root root 11 Jul 27 17:24 /etc/init.d/jboss1 -> jboss

Next I tried to change the ownership of the soft link to the original user.

$ sudo chown askar.admin /etc/init.d/jboss1

$ ls -l /etc/init.d/jboss1
lrwxrwxrwx 1 root root 11 Jul 27 17:24 /etc/init.d/jboss1 -> jboss

But the permission of the soft link is not getting changed.

What am I missing here to change the permission of the link?

Zama Ques
  • 3,276

3 Answers3

258

On a Linux system, when changing the ownership of a symbolic link using chown, by default it changes the target of the symbolic link (ie, whatever the symbolic link is pointing to).

If you'd like to change ownership of the link itself, you need to use the -h option to chown:

-h, --no-dereference affect each symbolic link instead of any referenced file (useful only on systems that can change the ownership of a symlink)

For example:

$ touch test
$ ls -l test*
-rw-r--r-- 1 mj   mj   0 Jul 27 08:47 test
$ sudo ln -s test test1
$ ls -l test*
-rw-r--r-- 1 mj   mj   0 Jul 27 08:47 test
lrwxrwxrwx 1 root root 4 Jul 27 08:47 test1 -> test
$ sudo chown root:root test1
$ ls -l test*
-rw-r--r-- 1 root root 0 Jul 27 08:47 test
lrwxrwxrwx 1 root root 4 Jul 27 08:47 test1 -> test

Note that the target of the link is now owned by root.

$ sudo chown mj:mj test1
$ ls -l test*
-rw-r--r-- 1 mj   mj   0 Jul 27 08:47 test
lrwxrwxrwx 1 root root 4 Jul 27 08:47 test1 -> test

And again, the link test1 is still owned by root, even though test has changed.

$ sudo chown -h mj:mj test1
$ ls -l test*
-rw-r--r-- 1 mj mj 0 Jul 27 08:47 test
lrwxrwxrwx 1 mj mj 4 Jul 27 08:47 test1 -> test

And finally we change the ownership of the link using the -h option.

mjturner
  • 7,300
  • As a disappointing tangential: neither cp -as nor install nor ln can directly create symlinks with a specified user/group. – Ulrich Schwarz Jul 31 '18 at 06:51
  • Any option to change the permission of the link and target at the same time? – Astora Feb 08 '21 at 20:18
  • THANK YOU so much for including "--no-dereference" and not just assuming everybody knows what "-h" is. some of us are not born knowing what the cryptic switches mean! – edwardsmarkf Sep 20 '21 at 22:59
32

When acting on symlinks, you must tell most of the tools (chown, chmod, ls...) not to dereference the link: you must add the -h parameter, as stated in the manpage :

-h, --no-dereference
          affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)

So try : sudo chown -h askar.admin /etc/init.d/jboss1

Adrien M.
  • 3,566
  • 4
    The most concise answer. Most people come here because chown by its own doesn't work - the "-h" fixes this. – itoctopus Feb 28 '19 at 10:58
4

Also note that the error you gave above

ln: creating symbolic link `/etc/init.d/jboss1': Permission denied

is not due to the owner of the symlink being somebody else than the owner of the original file. It is (most probably) caused by user askar not having write access to the directory /etc/init.d.