It _always_ kills the sgid/suid bits on a file, despite the fact that the
comments indicated that it should only kill them when the uid or gid
changes. I have included a patch to make this work as the comments would
indicated.
However, I feel _VERY_ strongly that this is an incorrect
behaviour.
chown is chown, it changes ownership. chmod is chmod, it changes the
rights. They are seperate system calls because they do seperate jobs. One
of the great things about Unix is that you can make it do exactly what you
tell it without ever having to repeat yourself...usually. But if the only
way to make chown() act _only_ as chown() involves getting the rights,
calling chown(), then restoring the rights, there is something very clearly
wrong here.
Standard Unix V7 behavior, which was inherited by System V, allows
*anyone*, not just root, to use the chown call. That is, a user is
allowed to "give away" a file to someone else. BSD took away this
behavior because they didn't want to deal with the mess that this caused
when they added filesystem quotas.
That's the historical reason for why chown took away the setuid and
setgid bits. The opportunities for mistakes are huge here; suppose a
file which is setuid to some user gets chown'ed to be root. Even if
only the superuser can do this, the result that there is now a setuid
root file can be very surprising, and cause a massive security hole.
- Ted