feature request: std::os::unix::process::CommandExt.groups() · Issue #38527 · rust-lang/rust (original) (raw)

std::os::unix::process::CommandExt already offers .uid() and .gid() methods to control the user identity of the child process (calling setuid and setgid respectively).

For complete control of Unix credentials, there should also be a way to call setgroups in the child. (setgroups is not in POSIX, but getgroups and the concept of the supplementary group list are; I would expect this not to be a portability concern.)

This feature would eliminate a use of before_exec and an unsafe block (to call libc::setgroups) from the program I'm currently writing, which is a port to Rust of a setuid C program. For illustration, this function exists in the C version:

/* A process which is setuid - that is, getuid() != 0, geteuid() == 0 -
   behaves differently than one which holds _only_ root credentials.
   We don't want the scripts acting up because of that.  This is done
   only for child processes because one of the differences is that a
   setuid program can be killed by the invoking (real) UID, which we
   do want to allow.  */
static void
become_only_root(void)
{
  if (geteuid() != 0)
    fatal("must be run as root");

  /* Discard all supplementary groups. */
  if (setgroups(0, 0))
    fatal_perror("setgroups");

  /* Set the real GID and UID to zero. This _should_ also set the
     saved GID and UID, divorcing the process completely from its
     original invoking user. */
  if (setgid(0))
    fatal_perror("setgid");
  if (setuid(0))
    fatal_perror("setuid");
}

This issue has been assigned to @slo1 via this comment.