The Wanderer wrote: > Bob Proulx wrote: > > jimmy wrote: > > >> // --- remove (delete) a file owned by root, should not be > >> allowed, but is allowed. Here, it says the file is 'read-only' > >> so it warns about it, but of course "rm -f " would work, too: > > > > Why do you think it should not be allowed? It is allowed. > > > > If you don't want a user to modify the directory then change the > > permissions of the directory. > > In this case, however, the user isn't just modifying the directory; the > user is modifying a file in the directory, by deleting that file.
Deleting a file does not modify the file contents. Really! :-) Try this: mkdir /tmp/testdir1 /tmp/testdir2 date -R >/tmp/testdir1/testfile1 ln /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 md5sum /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 16dccbc3809d0e5051f1b73bf9ca5687 /tmp/testdir1/testfile1 Obviously at that time there will appear to be two files with the same contents. I say appear to be two files because it is one file that is linked in two places. But there is really only one file. Now remove one file. We would say "unlink" that file. man 2 unlink The reason you "unlink" a file to remove it is due to the above situation. Removing a file simply unlinks it from a directory. rm /tmp/testdir1/testfile1 Okay. It is gone. It is removed from /tmp/testdir1. Was the file modified? Let's check the file. md5sum /tmp/testdir2/testfile2 16dccbc3809d0e5051f1b73bf9ca5687 /tmp/testdir2/testfile2 No modification was made to the file by removing it from the directory. And then as others pointed out the file system is reference counted. When the reference count to a file is reduced to zero then the space is actually freed. As long as the reference count is non-zero the file is not modified by removing it (unlinking it) from a directory. Therefore you do not need write permission to a file to remove it. You need write permission to the directory holding it. > >> $ rm -v /tmp/testing/newjunk1.txt > >> rm: remove write-protected regular file ‘/tmp/testing/newjunk1.txt’? y > >> removed ‘/tmp/testing/newjunk1.txt’ > > > > Sure. Because tst1 owns /tmp/testing. > > I'm confused as to why that's enough. I mis-wrote the above when I said it was because tst1 owns /tmp/testing. I had tried to be careful about talking about permissions elsewhere. But I had originally written my response saying owns. I went back and edited my response and changed most of those to write permission but missed that one. You caught me there on the one I missed editing. I should have said because tst1 has write permission to the directory. > Yes, moving a file affects only data stored in the directory node which > contains the file (and the directory node where the file is being moved > to, which may be the same one). > > But deleting a file does not affect only data stored in the directory > node which contains the file; it affects data stored in the file itself. > (Assuming that there is only one hardlink to the file and the file is > not presently open in any currently running process, which is often a > reasonable assumption - and even when it is not, I don't think the > permissions behavior of 'rm' should be different depending on the number > of hardlinks to the file.) Think of the case I presented above. Let's change it slightly. mkdir /tmp/testdir1 /tmp/testdir2 date -R >/tmp/testdir1/testfile1 ln /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 md5sum /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 16dccbc3809d0e5051f1b73bf9ca5687 /tmp/testdir1/testfile1 16dccbc3809d0e5051f1b73bf9ca5687 /tmp/testdir2/testfile2 ls -ldog /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 -rw-rw-r-- 2 32 Jun 8 18:32 /tmp/testdir1/testfile1 -rw-rw-r-- 2 32 Jun 8 18:32 /tmp/testdir2/testfile2 chmod a-w /tmp/testdir2/testfile2 ls -ldog /tmp/testdir1/testfile1 /tmp/testdir2/testfile2 -r--r--r-- 2 32 Jun 8 18:32 /tmp/testdir1/testfile1 -r--r--r-- 2 32 Jun 8 18:32 /tmp/testdir2/testfile2 Only one chmod needed because there really is only one file. There are two links. Now how should it be handled if you remove one? rm -f /tmp/testdir1/testfile1 That must work. Right? Because we have not actually deleted the file. Not yet anyway. The file is still there. The file hasn't been modified at all. ls -ldog /tmp/testdir2/testfile2 -r--r--r-- 1 32 Jun 8 18:32 /tmp/testdir2/testfile2 md5sum /tmp/testdir2/testfile2 16dccbc3809d0e5051f1b73bf9ca5687 /tmp/testdir2/testfile2 So if the paradigm you are exploring existed the above would be allowed. But now unlinking the testfile2 case would not be allowed. rm -f /tmp/testdir2/testfile2 In the case you are exploring the above would fail because it was the last reference to the file. It is only at that time that the file would actually be freed. There just isn't any reasonable way to make the behavior consistent between the case where the file has additional links to it and the case when they don't. And the whole purpose of links is to be transparent. Causing different behavior would defeat much of the purpose of hard links. Also the reference count applies to open file descriptors inside programs too. Open file descriptors are part of the reference count too. The file is not actually freed up until the last open file descriptor is closed. That would mean that there would be yet again a difference between that last "rm -f /tmp/testdir2/testfile2" where it frees up the file and having: sleep 300 < /tmp/testdir2/testfile2 & rm -f /tmp/testdir2/testfile2 In this case the reference count is non-zero due to the sleep 300 having an open file descriptor to the file. In the paradigm case you are exploring rm would not be the last unlink of the file due to the open file descriptor being at least one more. Only when the sleep exits does the last reference to the file to go zero and the file freed. What would happen in that case? Would the file exist forever taking up space because it is marked read-only even though it is not referenced from anywhere in the file system? And so things are not done that way. > As such, it seems as if deleting a file *should* require write > permission to that file. I agree that it *feels* like a read-only file should never be possible to be freed. But there isn't any practical way to make that happen. And it is worse for root. Root always has write permission even if the file does not have write bits. The superuser has super user permissions. > Is there something I'm missing here? Hopefully the discussion above makes sense and explains some of the issues. Bob
signature.asc
Description: Digital signature