Подтвердить что ты не робот

Как использовать setuid() от root, чтобы стать пользователем, с возможностью снова стать root?

Я пытаюсь сделать что-то безопасное, и у меня есть программа, которая должна запускаться от имени root, чтобы отказаться от ее привилегий, когда она им не нужна. Это хорошо работает, если я chmod мой двоичный код с битом SUID и сделать его принадлежащим root, так как теперь у меня есть UID = некоторый пользователь и EUID = root, поэтому я могу использовать seteuid(0) и seteuid(getuid()) соответственно, чтобы повысить и отказаться от прав администратора.

Но если я использую sudo вместо установки SUID, тогда UID == EUID == 0, и поэтому вызов seteuid(getuid()) не будет иметь никакого эффекта. И я не могу просто изменить UID на какое-то значение от какого-то случайного пользователя, так как в man-странице setuid() четко указано, что если она вызывается из программы, запущенной с правами root, то теряет привилегии навсегда, без надежды возвращая их.

Итак, как мне заставить мою программу временно потерять свои привилегии при запуске с помощью sudo?

4b9b3361

Ответ 1

seteuid(some random uid), чтобы сбросить привилегии, seteuid(0), чтобы вернуть их, когда они выполняются как root.

Ответ 2

Кажется, что seteuid (x) должен работать, чтобы сбросить и снова поднять привилегии...

$ 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
$ 

Ответ 4

Fork() перед тем, как сбросить привилегии. Подождите в родительской задаче до тех пор, пока не будет выполнен дочерний элемент с ограниченными правами, затем возобновите работу в родительском корневом каталоге.

seteuid не переносится для всех узлов и имеет другие недостатки.