64

I have a symlink with these permissions:

lrwxrwxrwx 1 myuser myuser       38 Aug 18 00:36 npm -> ../lib/node_modules/npm/bin/npm-cli.js*

The symlink is located in a .tar.gz archive. Now when I unpack the tar.gz archive using maven the symlink is no longer valid. I'm therefore trying to reconstruct the symlink. First I create the symlink using ln but how do I set the same permissions as the original symlink?

4 Answers 4

93

You can make a new symlink and move it to the location of the old link.

ln -s <new_location> npm2
mv -f npm2 npm

That will preserve the link ownership. Alternatively, you can use chown to set the link's ownership manually.

chown -h myuser:myuser npm

On most systems, symlink permissions don't matter. When using the symlink, the permissions of the components of symlink's target will be checked. However, on some systems they do matter. MacOS requires read permission on the link for readlink, and NetBSD's symperm mount option forces link permissions checks on read and traversal. On those systems (and their relatives, including FreeBSD and OpenBSD) there is a equivalent -h option to chmod.

chmod -h 777 npm
5
  • 2
    I just ran into a permission problem with symlinks on a CentOS 6.8 server. The symlinks had owner:group of root:root. When the owner and group were changed to the user that owned the directory they were in, as shown in this answer, the permission problem went away.
    – Night Owl
    Dec 4, 2016 at 6:12
  • 3
    Just providing a clarification. To change ownership or rights on a symlink, the -h flag will affect the symlink file instead of the dereferenced file. Jul 15, 2019 at 14:11
  • 6
    I get told that -h doesn't exist on chmod as an option!
    – J86
    Oct 17, 2021 at 11:13
  • 2
    -h doesnt seem to exist in debian Mar 10, 2022 at 11:02
  • See also the very surprising effects of symbolic links with restrictive permissions on BSD/macOS systems described here -- you may not be able to resolve the link target, but you can still read and write to it! Jun 9, 2022 at 14:05
20

When you try to use chmod to set the link's permissions, the actually you do is to set the permissions of the link's target.The link's permissions are meaningless.

3
  • 3
    What if someone changes the link to a malicious code? The original code can even be something that root can only access. For example in crontap scripts.
    – aliqandil
    Nov 15, 2018 at 6:39
  • @aliqandil Generally a user can delete and recreate any file in a directory for which they have write access. In bash, for a file test with -rw-rw-r-- root root, for rm test I receive the prompt rm: remove write-protected regular empty file 'test'? The solution is to place sensitive files in directories for which users have read-only access. Feb 12, 2019 at 4:54
  • this applies to Gnu chmod only Jun 9, 2022 at 13:45
8

When you have a link like:

link -> foo/bar

and want to change it to:

link -> new/target

There are two cases to consider:

  1. foo/bar is not a directory or doesn't exist or you don't have search access to foo. Then

    ln -s new/target link
    

    will fail because link already exists, but you can overcome that by using the standard:

    ln -fs new/target link
    
  2. foo/bar is a directory (and you have search permission to foo to be able to determine that foo/bar is a directory). In that case, when you do:

    ln -s new/target link
    

    or

    ln -fs new/target link
    

    That's understood as creating a new target symlink inside the link directory (link is a directory because it's a symlink to the foo/bar directory). So you'll actually create a:

    foo/bar/target -> new/target
    

    To overcome that, GNU ln has a -T option for the link name to always be considered as link name, and not as a directory to create the link(s) in. So, with GNU ln:

    ln -fsT new/target link
    

    will work. Like before, it will remove the original link symlink and create it anew with new/target as the target (and the process' euid and egid as the owner).

    GNU ln also has a -n option. It works like -T except when link is actually a real directory in which case it will still create the symlink inside that directory (instead of failing with an error).

    Portably, your best option is to remove the link first and then recreate it:

    rm -f link && ln -s new/target link
    

On most systems, permissions on symlinks are ignored and generally fixed to rwxrwxrwx.

On systems where symlink permissions matter (like OS/X where you need read permission to a symlink to be able to resolve its target), there's generally a way to change them (chmod -h on OS/X).

Ownership, while like above not relevant for access to the file pointed to by the symlink on most systems, can have some other relevance wrt the t bit of the parent directory or quotas...) and there's a standard command to change it:

chown -h user[:group] the-link
chgrp -h group the-link
-1

If you really need to change symlinks permission (usually meaningless, as written in other answers), I was successful with using -R option of chown:

chown -R myuser:mygroup link

If -R was not used, the permissions were not changed.

1
  • 1
    That will work with GNU chown because -R implied -P there, however that's not guaranteed and won't work in some other chown implementations. The standard way to change the symlink ownership is with the -h option. I've just updated the accepted answer which was incorrect. Oct 23, 2015 at 8:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .