How to use setuid() from root to become user, with the possibility of becoming root again later?

10,027

Solution 1

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

Solution 2

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
$ 

Solution 3

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.

Solution 4

Fork() before you drop privileges. Wait in the parent task until the child with reduced privileges is done, then resume in the parent with root.

seteuid is not portable to all unices and has other drawbacks too.

Share:
10,027
Florian
Author by

Florian

Updated on June 05, 2022

Comments

  • Florian
    Florian almost 2 years

    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?

  • Douglas Leeder
    Douglas Leeder about 14 years
    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?
  • dashesy
    dashesy about 11 years
    How do you make sure that uid=100 is not in sudoers group?
  • user253751
    user253751 over 7 years
    Of course, there's a chance that the random UID you switch to just happens to be the sysadmin's UID.
  • wheredidthatnamecomefrom
    wheredidthatnamecomefrom about 6 years
    sudo creates environment variables containing the UID and GID of the calling user. You can switch to "nobody" read the variable and switch to that user. I don't recommend reading environment variables as root. "nobody" is restricted account present on most unix systems.
  • wheredidthatnamecomefrom
    wheredidthatnamecomefrom about 6 years
    That matters only for sudo itself. The only special privilege the sudoers group grants is the ability to use the sudo command. It doesn't make the user id have root access.