How does 'mv' rename directories?

Richard Todd rmtodd at servalan.uucp
Sun Sep 17 07:36:00 AEST 1989


In article <4195 at buengc.BU.EDU> bph at buengc.bu.edu (Blair P. Houghton) writes:
>You only want mv(1) to be able to seteuid(2) to you, so you can move
>your own files.  If mv(1) was setuid-root, you could move files all
>over the place, without a care.  Hence, mv(1) is most definitely
>not setuid-root.
  mv(1) can only move files about without a care if mv(1) wasn't
written to check the destination mode and ownership to see if you're
allowed to move it.  On some systems, mv(1) is setuid-root, and it
does check permissions itself.  On some systems, mv isn't setuid. 

>I've been told that mv(1) may call mv_dir(?) (which doesn't exist
>on this machine... Encore's Umax is a vanilla BSD...) which is
>setuid-root (it is claimed).  If this is how it's done, then the
>reason for the setuid-root could be to allow the moving of a
>directory across partition boundaries when the directory may
>contain files with an owner different from the directory-owner.

  Uh, not quite.  First of all, I don't know of *any* version of the
mv command that allows moving directories across partition boundaries.

  Secondly, there are at least three different ways mv(1) can be
implemented on Unix systems, and different systems use different ones.  

  1. The mv command may be setuid root, and check to see if the real
user has appropriate permissions on the target directory.  The reason
root privileges are needed is not, as you say, to do directory moves
from one partition to another, since mv doesn't do that sort of move.
The real reason is this: Suppose we want to move directory foo from
/usr/bin to /usr/lib.  Not only must a link be made to foo in /usr/lib
and the existing link to foo in /usr/bin be removed, but the entry for
".." in the foo directory must be unlinked and a new link for ".."
must be made pointing to the new parent.  Ordinary (non-root) users
aren't allowed to unlink "..", for the simple reason that one could
accidentally make a tremendous mess of the filesystem.  Thus the power
to unlink ".." (or, for that matter, any directory) is restricted to
root.  On such systems, mkdir and rmdir have to be setuid-root, too,
for the same reasons.
  I believe V7 used the above scheme; perhaps System III did as well.
Minix, the V7 clone for PCs, definitely uses this scheme.

  2. Same as above, except that mv is non-setuid, and whenever mv
needs to move a directory, it calls mv_dir, a setuid program which
does the actual directory move.  mv itself doesn't call mv_dir when
ordinary files are moved.  System V systems without NFS apparently use
this scheme.  

  3. The operation of moving a file/directory from one place to
another (making the new link and unlinking the old one) can be done
inside a system call, rename(2), which does all the grotty work of
checking permissions, linking and unlinking, and making sure that ".."
in the moved directory is set correctly.  BSD systems and systems that
have client-mode NFS have this system call, and mv on such systems
uses this call; basically, mv just calls rename(2) directly for
intra-partition moves, and does the copy of files for moves between
partitions.  mv is not setuid, and needs no setuid program to assist
it.  The reason you didn't find mv_dir on your Encore system is that
it isn't needed there.  Putting the functionality of "move" in the
kernel has two advantages: 1, it removes the need for programs that
move directories to mess with the ".." business and be setuid-root,
and 2. the whole operation of moving the file/directory can be made
atomic inside the kernel, thus avoiding certain race conditions.
Also, it's useful on NFS systems, where the server you're mounting
your filesystem from may not be a Unix system and may require some
other (server-specific) technique to move files/directories; with
rename(2), moves on remote-mounted filesystems are simply translated
to appropriate calls to the NFS server.  Mkdir and rmdir are also
system calls on BSD or NFS systems, for much the same reasons.

>But, basically, there's no need to become uid 0 when you're just moving
>files around in a partition.
  Agreed.  It's the business of moving directories around that
sometimes causes problems.
--
Richard Todd	rmtodd at uokmax.ecn.uoknor.edu  rmtodd at chinet.chi.il.us
	rmtodd at servalan.uucp
Motorola Skates On Intel's Head!



More information about the Comp.unix.wizards mailing list