I want to create a Unix domain socket which is restricted to a particular group. So what I'd ideally do is (ignoring error checking) something like:
// Set the "address" (ie filesystem path)
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "./my.sock");
int fd = socket(AF_UNIX, SOCK_DGRAM, 0); // create the socket
// Set the group owner and permissions
fchmod(fd, 0770); // This seems to succeed
fchown(fd, -1, wanted_group_id); // Silently fails
// Create the filesystem entry
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
However, fchown
on a socket has no effect, so it seems that chown
afterwards is the only way to set the group. I want to avoid having the socket temporarily accessible to processes which shouldn't be permitted to access it.
The best idea I have is:
int fd = socket(...);
fchmod(fd, 0700); // Remove group permissions
bind(fd, ...); // Create fs entry
chown("./my.sock", -1, wanted_group_id); // set the correct group owner
fchmod(fd, 0770); // And restore group permissions
Surely this is a common thing to want to do with Unix sockets, and there's a canonical way of achieving this, but I haven't found any clear answers.
I'm only really interested in Linux, but bonus points for something that only relies on POSIX.