2010-02-16 16 views
11

Estoy tratando de hacer lo seguro, y tengo un programa que necesita ejecutarse como root para eliminar sus privilegios cuando no los necesita. Esto funciona bien si chmod mi binario con el bit SUID y lo hago pertenecer a root, ya que ahora tengo UID = algún usuario y EUID = root, entonces puedo usar seteuid(0) y seteuid(getuid()) para subir y bajar derechos de administrador, respectivamente.¿Cómo se usa setuid() desde root para convertirse en usuario, con la posibilidad de volver a ser root más tarde?

Pero si uso sudo en lugar de establecer el SUID, entonces UID == EUID == 0, y por lo tanto llamar a seteuid(getuid()) no tendrá ningún efecto. Y no puedo simplemente cambiar UID a algún valor de algún usuario aleatorio, ya que la página del manual setuid() indica claramente que si se llama desde un programa que se ejecuta como raíz, uno pierde los privilegios para siempre, sin esperanza de recuperarlos.

Entonces, ¿cómo hago que mi programa pierda temporalmente sus privilegios cuando se ejecuta usando sudo?

+0

¿Necesita volver al UID del usuario que ejecutó 'sudo', o simplemente a un usuario aleatorio, menos privilegiado? –

+0

Me conformaré con 'nadie'. pero si conoces una forma simple de obtener la llamada sudo, estoy interesado. – Florian

+3

meh, es fácil, solo necesito 'getenv (" SUDO_UID ")'. – Florian

Respuesta

10

seteuid(some random uid) para soltar privilegios, seteuid(0) para recuperarlos, cuando se ejecuta como root.

+3

Por supuesto, eso deja el problema de obtener el UID original del usuario que llamó 'sudo', si el OP necesita volver a ese usuario. –

+0

Por supuesto, existe la posibilidad de que el UID aleatorio que cambie sea el UID del administrador del sistema. – immibis

+0

sudo crea variables de entorno que contienen el UID y el GID del usuario llamante. Puede cambiar a "nadie" para leer la variable y cambiar a ese usuario. No recomiendo leer variables de entorno como root. "nobody" es una cuenta restringida presente en la mayoría de los sistemas Unix. – wheredidthatnamecomefrom

6

Parece que seteuid (x) debe trabajar a bajar y volver a subir 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 
$ 
+0

¿Cómo se asegura de que uid = 100 no está en el grupo sudoers? – dashesy

+0

Eso solo importa para sudo. El único privilegio especial que otorga el grupo sudoers es la capacidad de usar el comando sudo. No hace que la identificación del usuario tenga acceso de root. – wheredidthatnamecomefrom

1

Tenedor() antes de caer privilegios. Espere en la tarea principal hasta que se complete el elemento secundario con privilegios reducidos, luego reanude en el elemento primario con la función raíz.

seteuid no es portátil para todos los equipos y tiene otros inconvenientes.

Cuestiones relacionadas