Subject: RE: LINK a symbolic link?

From: "Noveck, Dave" <[email-masked]>
Date: Tue, 27 Nov 2001 13:37:22 -0800

I think a number of UNIX's (but not Solaris) have decided,
since there is no real need for this anymore, that nobody 
has permission to make a hard link to a directory.

So the Open Group's Unix spec says this about link (at http://www.opengroup.org/onlinepubs/007908799/xsh/link.html)

[EPERM]
The file named by path1 is a directory and either the calling 
process does not have appropriate privileges or the implementation 
prohibits using link() on directories.

-----Original Message-----
From: Peter Staubach [mailto:[email-masked]]
Sent: Tuesday, November 27, 2001 4:22 PM
To: [email-masked]; [email-masked]
Subject: Re: LINK a symbolic link?

> 
> > It is unfortunate,
> > but the UNIX link(2) system will allow a link to a directory.
> 
> The FreeBSD and GNU/Linux manpages for link(2) both claim you'll get
> EPERM if you try to link to a directory (probably so that every
> directory has one parent--no other types of entries are similarly
> restricted), and FreeBSD's /bin/ln reports "is a directory".  Does
> POSIX specify this one way or the other, or is it a SysV feature?

Do you know what happens if you try the link(2) as root?  Typically,
linking to directories has been restricted to being root.

I believe that the ability to link to directories was required before
the mkdir(2) system call was introduced.  Directories were created by
doing a mknod(2) followed by two link(2) operations to create the "."
and ".." entries.  The functionality was not removed or disabled when
mkdir(2) was introduced.

		ps

---

From: Eric Werme USG <[email-masked]>
Date: Tue, 27 Nov 2001 16:53:37 -0500

Tru64 concurs:

	if (error = namei(ndp))
		return (error);
	vp = ndp->ni_vp;
	type = vp->v_type;
	if (type == VDIR) {
		error = EPERM;
		goto out1;
	}

That implies we can link to special files.  Indeed:

# ls -l /dev/tty
crw-rw-rw-   1 root     system     1,  0 May 14  2001 /dev/tty

# ln /dev/tty /tmp/foo 

# ls -l /dev/tty /tmp/foo 
crw-rw-rw-   2 root     system     1,  0 May 14  2001 /dev/tty
crw-rw-rw-   2 root     system     1,  0 May 14  2001 /tmp/foo

I think I saw a suggestion to limit link to regular files.  Too restrictive.

Curiously, ln(1) a directory doesn't report a permission failure:

# ln /tmp /tmp/foo
/tmp is a directory.

   - Ric Werme

---

From: Mike Eisler <[email-masked]>
Date: Tue, 27 Nov 2001 14:16:57 -0800

>    has permission to make a hard link to a directory.
...

> I think I saw a suggestion to limit link to regular files.  Too restrictive.

Agreed. I see no reason to make it illegal to have hard links to
any file type, nor do I see any reason to make it
required to support hard links to all file types.
Instead I think the NFS server should simply reflect the
capabilities of the underlying filesystem it is
implemented over.

> Curiously, ln(1) a directory doesn't report a permission failure:

Perhaps ln() doesn't attempt the call to link().

The Solaris ln command does not attempt the link()
call either; Solaris 8 has link and unlink
commands that work, at least over tmpfs. I'm
not going to run such a test on my ufs filesystem.

I'm told that Veritas's vxfs disallows hardlinks to
directories.

The wg can decide that hard links to directories are
required; if so there will be lots of
non-compliant servers and non-compliant combinations of 
servers and filesystems. And I doubt many users will care.

Hard links to directories make the following challenging:

	- lookup ("a/b/c"), where c is a hard link of a
	- establishing a locking order when descending
		a pathname

For a local filesystem implementor, it is far simpler to
say no to directory hard links.

	-mre

---

From: Ric Werme <[email-masked]>
Date: Tue, 27 Nov 2001 19:11:09 -0500

> 	- establishing a locking order when descending

Loops in directories can do interesting things to pwd and du.  Worse, if you
also permit unlinks, you could do:

$ mkdir a a/b a/b/c
$ ln a/b/c a/b/c/b
$ rm a/b (or whatever the unlink would be)

so b would be disconnected from the hierarchy, but would would still have
a link count >1 (and more, if it still has .).  b and c would point to each
other.

	-Ric