views:

133

answers:

2

I'm writing a program in C that binds to a port < 1024. I'd like it to run at non-root privileges thereafter.

I know I need to call setuid(), but with what argument? UID's vary from system to system.

+1  A: 

More than you'll want to know http://www.eecs.berkeley.edu/~daw/papers/setuid-usenix02.pdf

alinrus
nice link. the state machine drawings are especially amusing. funny how such a system just sort of evolves :-)
asveikau
A: 

You can use getpwnam() to look up a users uid/gid by name:

#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>

int changepriv(const char *user) {
  struct passwd *pw;
  int rv;

  pw = getpwnam(user);
  if (!pw)
    return -1;

  rv = setgid(pw->pw_gid);
  if (rv == -1)
    return -2;

  rv = setuid(pw->pw_uid);
  if (rv == -1)
    return -3;

  return 0;
}
sth
But user names vary by system as well. Every system has a uid 0 w/ username=root. but will every system have a username=www? If someone on a different systems runs this, I'd like for them not to have to change the source code
Derrick
try an account like "nobody", but normally this would be a configuration option.
sharth
Hmm thanks guys. I used pretty much this idea with a twist. Use the getlogin() to find the user name.
Derrick
You should also read alinrus's response. Under certain conditions this code might not be secure; you should test that the low-privilege daemon can't setuid() back to 0.
asveikau