I'll start by presenting this rather interesting and puzzling failure in illustrated form:
; mkdir /tmp/newdir ; chmod g+s /tmp/newdir chmod: /tmp/newdir: Operation not permitted
How can I not be able to make this chmod change when I just made the directory and I own it? For extra fun, some people on this particular system won't experience this problem, and in fact many of them are the people you might report this problem to, namely the sysadmins.
At first I wondered if this particular
/tmp
filesystem disallowed setuid and setgid entirely, but it turned out to be not that straightforward:
; ls -ld /tmp/newdir drwxr-xr-x 2 cks wheel 512 May 3 00:35 /tmp/newdir
This at least explains why my chmod attempt failed. I'm not in group
wheel
, and for good reasons you can't make a file setgid to a group that you're not a member of. But how on earth did my newly created directory in
/tmp
wind up in group wheel, a group I'm not a member of? Well, perhaps someone made
/tmp
setgid, so all directories created in it inherited its group (presumably group
wheel
). Let's see:
; ld -ld /tmp drwxrwxrwt 157 root wheel 11776 May 3 00:41 /tmp
Although
/tmp
is indeed group
wheel
, it has perfectly ordinary permissions (mode 777 and sticky ('
t
'), so you can only delete or rename your own files). There's no setgid to be seen.
The answer to this mystery is that this is a FreeBSD machine, and on FreeBSD, well, let's quote the
mkdir(2)
manpage :
The directory's owner ID is set to the process's effective user ID. The directory's group ID is set to that of the parent directory in which it is created .
And also the section of the
open(2)
manpage that deals with creation of new files:
When a new file is created it is given the group of the directory which contains it.
In other words, on FreeBSD all directories have an implicit setgid bit. Everything created inside them (whether directories or files) inherits the directory's group. Normally this is not a problem and you'll probably never notice, but
/tmp
(and
/var/tmp
) are special because they allow everyone to create files and directories in them, and so there are a lot of people making things there who are not a member of the directory's group.
(The sysadmins usually are members of group
wheel
, though, so things will work for them. This should add extra fun if a user reports the general chmod issue as a problem, since sysadmins can't reproduce it as themselves.)
You might think that this is an obscure issue that no one will ever care about, but actually it caused a Go build failure on FreeBSD for a while . Tracking down the problem took me a while and a bunch of head scratching.
PS: arguably GID 0 should not be group
wheel
but instead something else that only
root
is a member of and
wheel
should be a completely separate group. To have group
wheel
used for group ownership as well as
su
access to
root
is at least confusing.