seteuid/geteuid: программа всегда имеет корневой идентификатор

В настоящее время я пытаюсь выяснить, как работают бит SUID и соответствующие функции seteuid и geteuid. Итак, я написал эту небольшую программу:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {

    printf("oldid %d\n", geteuid());
    if(seteuid(0) == -1)
        perror("seteuid faied");
    printf("newid %d\n", geteuid());

    return 0;

}

Скомпилировал, сменил владельца на root и s-бит на владельца файла:

[chris@myhost Test]$ ls -l test
-rwsr-xr-x 1 root root 4830 Apr  5 07:56 test

Но тогда произведенный вывод выглядит следующим образом:

[chris@myhost Test]$ ./test
oldid 0
newid 0

А вот этого я не понимаю. Согласно тому, что я обнаружил, первый вызов geteuid должен фактически возвращать идентификатор пользователя вызывающей стороны этой программы (т. Е. Крис - мой идентификатор будет 1000), но программа показывает root как эффективный идентификатор пользователя. Может ли кто-нибудь объяснить мне, почему это так?


person Chris    schedule 05.04.2011    source источник


Ответы (1)


Со страницы руководства geteuid() на моем Mac (OS X 10.6.7):

Настоящий идентификатор пользователя — это идентификатор пользователя, вызвавшего программу. Поскольку эффективный идентификатор пользователя дает процессу дополнительные разрешения во время выполнения процессов режима «set-user-ID», функция getuid() используется для определения реального идентификатора пользователя вызывающего процесса.

Поскольку вы установили бит suid, действующий идентификатор пользователя программы — это владелец файла (root) с начала выполнения.

person JeremyP    schedule 05.04.2011
comment
Хорошо, спасибо (этой информации не было на моей странице руководства). Но тогда вся концепция кажется бесполезной? Предположим, у меня есть небольшой фрагмент кода в моей программе, который я хочу выполнить с правами суперпользователя. Мой план состоял в том, чтобы сделать root владельцем всей программы, установить SUID-бит, а затем изменить эффективный идентификатор пользователя только для небольшой части ... Как я могу добиться этого тогда? - person Chris; 05.04.2011
comment
@Chris: Это большая тема, и она может варьироваться в зависимости от вашей операционной системы. В Mac OS X общая стратегия всегда раньше состояла в том, чтобы иметь отдельную программу, которая выполняет часть, требующую привилегий, и делать ее программой setuid. Основная программа будет разветвляться и выполняться для запуска отдельной программы. Это делает часть setuid очень маленькой и с меньшей вероятностью имеет дыры в безопасности. - person JeremyP; 05.04.2011
comment
@Chris: В настоящее время передовой практикой для OS X является создание демона запуска, работающего от имени пользователя root, и использование его для обслуживания запросов через сокет домена Unix. Как по-старому, так и по-новому вам необходимо аутентифицировать пользователя в привилегированном коде, чтобы убедиться, что он авторизован для выполнения операции (для этого OS X предоставляет API). - person JeremyP; 05.04.2011
comment
@Chris: Я прокомментирую ради записи и, возможно, чтобы помочь бедняге в будущем. Это не бесполезно. Это просто работает наоборот, чем вы думаете. Вам нужно сразу же установить идентификатор своего пользователя при запуске, а затем ненадолго переключиться на другого пользователя. Недостаток дизайна Unix, возможно, заключается в том, что он начинается как другой пользователь, а не как вы (см. Advanced Programming in the UNIX Environment 8.10). - person Waslap; 30.05.2016
comment
Чтобы сделать что-то от имени пользователя root, а затем вернуться к обычному идентификатору пользователя, вам нужно использовать что-то вроде getresuid() (при условии, что у вас Linux). Однако это не определено POSIX, поэтому вам может понадобиться выяснить аналогичные функции для других UNIX-подобных систем. См. также: stackoverflow.com/q/34452939/334451 - person Mikko Rantalainen; 14.03.2018