Я не могу получить доступ к файлу, принадлежащему группе, после вызова setgid и setuid в Linux

Давайте добавим новую группу и пользователя и добавим его в системную группу 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: Отказано в доступе)

В чем проблема?


person Honza    schedule 18.09.2012    source источник
comment
Не могли бы вы указать узел устройства в демоне и проверить, есть ли у вас права на чтение/запись, обратившись к полю st_mode в struct stat? (подробности см. в статистике человека 2)   -  person spitfire88    schedule 26.09.2012
comment
Я ожидал, что теперь у меня должен быть доступ... - Вероятно, это ошибочное предположение. Код возврата из setuid() должен быть проверен на успешность или неудачу.   -  person sawdust    schedule 26.09.2012
comment
Я немного отредактировал вопрос, может быть, теперь есть больше информации.   -  person Honza    schedule 27.09.2012


Ответы (1)


Вы должны использовать вызов initgroups() для инициализации групп в соответствии с базой данных групп.

person Pavel    schedule 03.10.2012