11

If a directory "foo" is owned by user A and contains a directory "bar", which is owned by root, user A can simply remove it with rmdir, which is logical, because "foo" is writable by user A.

But if the directory "bar" contains another root-owned file, the directory can't be removed, because files in it must be removed first, so it becomes empty. But "bar" itself is not writable, so it's not possible to remove files in it.

Is there a way around it? Or, convince me otherwise why it's necessary.

2 Answers 2

7

Interpretation 1: a directory is a subspace of the filesystem. It can be further subdivided into subsubspaces by creating subdirectories in it. The owner of the directory foo should have control over everything inside the subspace: foo/bar, foo/bar/qux, etc.

Interpretation 2: a directory is a subspace of the filesystem. Every directory is attached to some other directory, called its parent. The owner of the directory foo has control over everything inside the subspace; however, for a subdirectory foo/bar, the owner of foo has control over whether bar can be attached to foo but not over what goes inside bar: only the owner of bar has control over that.

Evidence in favor of interpretation 2: as you've noted, the way permissions work. Also, the fact that some Unix filesystems allow a directory to be attached to more than one parent: this is called having multiple hard links. (Having multiple hard links is common for regular files, but it's usually discouraged or forbidden for directories mainly because of the risk of creating loops, where a directory is its own grandparent N times removed — so you can't get to it from the root directory, which is a very common expectation. There's also the problem of what to do if a directory has 0 hard links but is not empty: since the directory is unattached, you'd want to delete it, but what do you do with its contents?)

Evidence in favor of interpretation 1: in practice, directories do have a single parent and so form a tree structure. And you can't access foo/bar/qux unless you have execute permission on foo as well as bar (well, except that there are somewhat obscure ways to be given access to bar without being given access to foo). So the upper levels do matter.

On a more practical note, in your situation, user A can do

mkdir garbage
mv foo/bar garbage/
rmdir foo
6
  • 2
    This is a great answer (rec'ed), but the apparent inconsistency remains frustrating to me. And while the practical example of moving bar to garbage does work, we're left with a directory called garbage that can't be removed. I've got this same issue, except that it's user A and user B, where B stuck something in a directory owned by A, which A wants to remove. Aug 17, 2010 at 16:27
  • This is a good explanation, but the example at the end using mv to circumvent the issue doesn't work for me on Raspbian (haven't tried on any other systems). Furthermore, having researched this issue, I haven't seen the use of mv as a solution mentioned anywhere else. Indeed, based on my understanding of how the permissions work, it makes sense that the mv fails when I've attempted it. Am I missing something? Or has this functionality perhaps changed? @Gilles @PaulHooper
    – fvgs
    Dec 28, 2016 at 18:25
  • @fvgs Nothing has changed, but your situation may have different permissions from this one. I suggest that you ask a new question (on Unix & Linux rather than Server Fault as this question would probably be considered off-topic if it was asked on SF now) and give all the details of your situation. Dec 28, 2016 at 19:13
  • @Gilles Could you please point me to some documentation, reference, or mention of the behavior you described for mv? I'm able to use mv to rename the bar directory. Meaning that the mv succeeds as long as I don't try to move bar outside of the current directory or into any other directory. But the example you gave (which moves bar up a directory) doesn't work for me (permission denied). Does the example you gave assume specific conditions other than those specified in the question?
    – fvgs
    Dec 28, 2016 at 21:00
  • @fvgs My example doesn't move bar up a directory, it moves it to a directory that you own. garbage can be anywhere on the same filesystem, not necessarily a sibling of foo. Dec 28, 2016 at 22:48
0

The only way around this would be to use either a setgid or setuid on the parent directory or use an ACL.

Set the directory setgid with

chmod g+s foo

Set a default ACL on it with

setfacl -d -R -m g:group:rwx foo

This sets it as the default ACL on this path. You must mount the filesystem that contains this path with the acl option!

Now tell me why you think you want this.

8
  • Well, the problem is one of consistency. Nothing stops me from deleting a file or an empty directory owned by another user in a directory I own, but if it's not empty, I'm locked out from deleting my own directory.
    – Alex B
    Jun 11, 2010 at 8:33
  • If that's the case, I'd use one of the options I supplied. They'll work fine for you.
    – wzzrd
    Jun 11, 2010 at 9:08
  • I often use multiple accounts on my desktop (one of which is "main non-root" account). I can also get such situation when make install started from root starts building something.
    – Vi.
    Jun 14, 2010 at 13:48
  • setgid on the parent directory doesn't help. After done as root cd ~user && mkdir qqq && touch qqq/qqq I can't get rid of qqq from user by chmod g+s . and rm -Rf qqq.
    – Vi.
    Jun 14, 2010 at 13:54
  • Mmh. That's probably a umask matter then. If your directory is 775, it's setgid and your umask is 0002, then files are writable for group and therefore removable for you. But, true, it does not work with umask 0022 (which is mostly the default). Should have said that. Have you tested the acl option?
    – wzzrd
    Jun 14, 2010 at 14:01

You must log in to answer this question.

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