Давайте добавим новую группу и пользователя и добавим его в системную группу video
$ sudo addgroup --system mydaemon
$ sudo adduser --system --no-create-home --ingroup mydaemon mydaemon
$ sudo adduser mydaemon video
Создайте файл и измените его владельца на root и группу на video
$ touch video0
$ sudo chown root:video video0
$ sudo chmod 0660 video0
Теперь рассмотрим простое приложение, написанное на C с использованием setgid()
и setuid()
.
/* perms.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
int main(int argc, char const *argv[])
{
int ret;
int gid;
int uid;
struct passwd *pw;
struct group *gr;
pw = getpwnam("mydaemon");
if (pw) {
ret = setgid(pw->pw_gid);
if (ret < 0) {
printf("error with setgid\n");
exit(1);
}
ret = setuid(pw->pw_uid);
if (ret < 0) {
printf("error with setuid\n");
exit(1);
}
}
pw = getpwuid(getuid());
gr = getgrgid(getgid());
printf("gid: %d gr_name: %s\n", gr->gr_gid, gr->gr_name);
printf("uid: %d user_name: %s\n", pw->pw_uid, pw->pw_name);
ret = open("video0", O_RDWR);
printf("open status: %d (errno %d)\n", ret, errno);
return 0;
}
После компиляции мы можем запустить его как обычный пользователь:
$ ./perms
error with setgid
Это не удается, потому что у нас нет прав доступа к setgid. Поэтому запустите его напрямую от имени mydaemon:
$ sudo -u mydaemon ./perms
gid: 126 gr_name: mydaemon
uid: 116 user_name: mydaemon
open status: 3 (errno 0)
Хорошо, я могу сделать setgid
и setuid
(я тот же пользователь), и я могу открыть файл, как и ожидалось.
Теперь запустите его как root:
$ sudo ./perms
gid: 126 gr_name: mydaemon
uid: 116 user_name: mydaemon
open status: -1 (errno 13)
Я могу сделать setgid
и setuid
, getgid
и getuid
говорит, что я работаю как mydaemon но не могу открыть файл. (ошибка 13 — EACCES: Отказано в доступе)
В чем проблема?