setgid() не работает - операция не разрешена

Я создал программу setuid на C. Исполняемый файл выглядит так:

-r-s-r-s--- 1 root users 13073 Jun 15 21:56 server

Я запускаю программу как userA/users и пытаюсь установить uid/gid на userB/otherUsers. setgid() завершается с ошибкой, операция не разрешена. userA не является частью otherUsers Как я могу изменить действующий GID?


[EDIT] Вот краткое изложение того, что я сделал. Моя программа на C, выполняемая от имени пользователя A, устанавливает для uid и gid значение userB и создает файл. Не так, как ожидалось, файл принадлежит корню группы, потому что setgid() не работает.

[userA@node uid]$ id
uid=11945(userA) gid=544(users) groups=544(users)
[userA@node uid]$ id userB
uid=11946(userB) gid=10792(otherUsers) groups=10792(otherUsers)
[userA@node uid]$ cat uid.c 
#include <stdio.h>
#include <unistd.h>

int main() {
  setuid(11946);
  setgid(10792);

FILE *f = fopen("userB_file", "w");
fclose(f);

return 0;
}
[userA@node uid]$ ls -l uid
-r-sr-sr-x 1 root root 7130 Jun 17 14:16 uid
[userA@node uid]$ ./uid 
[userA@node uid]$ ls -l userB_file 
-rw-r--r-- 1 userB root 0 Jun 17 14:19 userB_file

person multiholle    schedule 16.06.2012    source источник
comment
Вы уверены, что setgid() работает с разрешениями пользователя из группы users? Это приведет к сбою с операцией, не разрешенной, потому что привилегии чтения и exec/setuid не распространяются на мир/другие.   -  person    schedule 16.06.2012
comment
Я не понимаю. Должен ли я запускать свою программу как root? Я думал, что для изменения uid/gid будет достаточно установить владельца как root. Я не смогу запустить программу как root.   -  person multiholle    schedule 16.06.2012
comment
Разрешения Unix: владелец/группа/{мир,другие}. Вы прочитали и выполнили + setuid для владельца (root) и группы (пользователи). У вас нет опубликованного кода, но если то, что вызывает setgid(), не является корневым или входит в группу пользователей, это приведет к ошибке, о которой вы сообщаете.   -  person    schedule 16.06.2012
comment
Я просто вызываю setuid() и setgid() с идентификаторами для userB/otherUsers. Сама программа выполняется пользователем A. Должен ли я добавить пример кода?   -  person multiholle    schedule 16.06.2012


Ответы (1)


Я подозреваю, что вы звоните setuid перед setgid. Как только вы вызовете setuid, чтобы изменить uid на что-то отличное от root, вы лишитесь права изменять gid на произвольное значение. Вы должны сначала позвонить setgid, затем setuid.

person R.. GitHub STOP HELPING ICE    schedule 16.06.2012
comment
Это так же очевидно, как просто! Черт, ты так прав. Я изменил порядок и, конечно же, он работает! Спасибо. Кстати: я добавил в вопрос свою оригинальную программу на C. - person multiholle; 18.06.2012
comment
На самом деле это не так очевидно. Об этом не сообщается ни на справочной странице setgid, ни на справочной странице setuid. - person Bemipefe; 06.10.2017
comment
@Bemipefe: Из-за модели разрешений должно быть очевидно, что вы не можете изменить идентификатор своей группы на что угодно, когда вы являетесь обычным непривилегированным пользователем. - person R.. GitHub STOP HELPING ICE; 06.10.2017
comment
@R.. Я имел в виду тот факт, что функция setgid должна вызываться перед функцией setuid. Это правило также применяется к процессам, запущенным от имени пользователя root. - person Bemipefe; 07.10.2017
comment
@Bemipefe: Это правило является следствием того факта, что только root может изменить gid на произвольные группы. После вызова setuid вы больше не являетесь пользователем root. - person R.. GitHub STOP HELPING ICE; 07.10.2017