I have a simple init.d script which starts and stops a process. I call the init.d as root, but I'd like the process it controls to run as a specific user.

The most common suggestion online seems to be to do

su myuser -c "my_process args"

However, this creates a second process space, new shell etc. and is somewhat inelegant.

I'd prefer to use exec(), since it replaces the shell, but this doesn't take a user as argument. Is this a case where I should use setuid() first? What about setting the gid? Are there any gotchas to be aware of?

Alternatively, are there distro-specific solutions to running the init.d as a different user? My environment is Centos 6.4.

  • If the service only needs to be started when first connected to via tcp or udp, using inetd or xinetd might work for you. Their config files let you specify the user to run the server as. – Mark Plotnick Mar 28 '14 at 22:06
  • The simplest solution imho is the setuidgid program, available at cr.yp.to/daemontools/setuidgid.html and included in some versions of the coreutils – loreb Mar 28 '14 at 22:47

Depends on the distribution but RHEL-based distros use a Bash function they source from /etc/rc.d/init.d/functions that's called daemon which is itself just a wrapper around the runuser command. From what I can tell in the source files, it's functionally identical to su in most cases, it just doesn't go through PAM (probably to avoid some chicken and egg problems in certain cases).

That's not really going to answer your objections, but it's how services do it. The cleanliness and overall conformity to logic that you're wanting is part of the motivation for things like systemd


The use of su someuser -c ... is what is needed. For starters, setuid() is a system call not available to shell code. Don't make this more difficult than need be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.