seteuid/geteuid: Програмата винаги има root id

В момента се опитвам да разбера как работят SUID-bit и съответните функции 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 всъщност трябва да върне потребителския идентификатор на повикващия на тази програма (т.е. Крис - моят ID ще бъде 1000), но програмата показва root като действителен потребителски идентификатор. Може ли някой да ми обясни защо е така?


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


Отговори (1)


От man страницата на geteuid() на моя Mac (OS X 10.6.7):

Истинският потребителски идентификатор е този на потребителя, който е извикал програмата. Тъй като ефективният потребителски идентификатор дава на процеса допълнителни разрешения по време на изпълнение на процеси в режим ``set-user-ID'', getuid() се използва за определяне на реалния потребителски идентификатор на извикващия процес.

Тъй като сте задали suid бита, ефективният потребителски идентификатор на програмата е собственикът на файла (root) от началото на изпълнението.

person JeremyP    schedule 05.04.2011
comment
Добре, благодаря (тази информация не беше в моята страница с ръководство). Но тогава цялата концепция изглежда безполезна? Да приемем, че имам малка част от кода в моята програма, която искам да изпълня с root права. Моят план беше да направя root собственик на цялата програма, да задам SUID-бита и след това да променя ефективния потребителски идентификатор само за малката част... Как мога да постигна това тогава? - person Chris; 05.04.2011
comment
@Chris: Това е голяма тема и може да варира в зависимост от вашата операционна система. В Mac OS X общата стратегия винаги използвана е била да има отделна програма, която върши частта, изискваща привилегии, и да я превърне в програма setuid. Основната програма ще се разклони и изпълни, за да изпълни отделната програма. Това прави частта на setuid много малка и е по-малко вероятно да има дупки в сигурността. - person JeremyP; 05.04.2011
comment

Това не би трябвало да изисква много тестове. Един правилен тест ще покаже, че кодът, делегиран на FirstOrDefault, работи, тогава всички следващи тестове наистина тестват дали логиката в ограничението Func е правилна, което може да се направи, без да се предава в Repository.

- person JeremyP; 05.04.2011
comment
@Chris: Ще коментирам за протокола и може би за да помогна на някоя бедна душа в бъдеще. Не е безполезно. Просто работи обратното от това, което мислите. Трябва незабавно да настроите uid към собствения си потребител при стартиране и след това да превключите за кратко към другия потребител. Недостатъкът в дизайна на Unix може би е, че той започва като другия потребител, вместо като вас (вижте Разширено програмиране в UNIX среда 8.10) - person Waslap; 30.05.2016
comment
За да направите нещо като root и след това да се върнете към нормален потребителски идентификатор, трябва да използвате нещо като getresuid() (ако приемем, че имате Linux). Това обаче не е дефинирано от POSIX, така че може да се наложи да разберете подобни функции за други UNIX-подобни системи. Вижте също: stackoverflow.com/q/34452939/334451 - person Mikko Rantalainen; 14.03.2018