views:

485

answers:

3

Hello all,

I'm trying to do the safe thing, and have a program that needs to runs as root to drop its privileges when it doesn't need them. This works well if I chmod my binary with the SUID bit, and make it belong to root, as now I have UID = some user, and EUID = root, so I can use seteuid(0) and seteuid(getuid()) to respectively raise and drop admin rights.

But if I use sudo instead of setting the SUID, then UID == EUID == 0, and so calling seteuid(getuid()) won't have any effect. And I can't just change UID to some value from some random user, as the setuid() man page clearly states that if it is called from a program running as root, one loses the privileges for good, with no hope of getting them back.

So, how do I make my program lose temporarily its privileges when run using sudo ?

+6  A: 

seteuid(some random uid) to drop privileges, seteuid(0) to get them back, when running as root.

Aidan Cully
Of course - that leaves the problem of getting the original UID of the user who called `sudo` - if the OP needs to go back to that user?
Douglas Leeder
+3  A: 

Not a direct answer, just would like to point you to the idea of privilege separation. Here's a great presentation by OpenBSD founder Theo de Raadt.

Nikolai N Fetissov
+4  A: 

It seems like seteuid(x) should work to drop and re-raise privs...

$ cat > t12.c
#include <stdio.h>
#include <unistd.h>

void p(void) { printf("euid=%4d uid=%4d\n", geteuid(), getuid()); }

int main(void) { p(); seteuid(100); p(); seteuid(0); p(); return 0; }
$ cc -Wall t12.c
$ sudo chown root a.out && sudo chmod 4555 a.out
$ sudo ./a.out
euid=   0 uid=   0
euid= 100 uid=   0
euid=   0 uid=   0
$ ./a.out
euid=   0 uid= 501
euid= 100 uid= 501
euid=   0 uid= 501
$ 
DigitalRoss
what a sick geek world we are in that I (any many others) can read that answer and understand it. we have got to get lives
pm100