Qt, Linux, проверьте, есть ли у данного пользователя привилегии sudo

Я использую Fedora 17 KDE x64 и Qt 4.8.1.

В отличие от Ubuntu, Fedora не дает первому созданному пользователю привилегии sudo и не добавляет первого созданного пользователя в файл /etc/sudoers. Поэтому при установке программ на Fedora 17 KDE (не тестировал Gnome и т.п. спины) требуются root (не sudo) привилегии. Итак, у нас есть три уровня привилегий (перечислены в порядке убывания по уровню привилегий):

1) root 2) sudo 3) пользователь

В Fedora 17 KDE, если у вас есть доступ к учетной записи пользователя root, вы можете предоставить привилегии sudo любому другому пользователю, просто отредактировав файл /etc/sudoers и добавив строку:

user ALL = (ALL) ALL

… ниже линии:

root ALL = (ALL) ALL

Замените user именем учетной записи, к которой вы хотите предоставить доступ sudo.

Но не каждый пользователь имеет доступ к учетной записи root пользователя. Вот почему пользователь root может предоставлять привилегии суперпользователя (sudo) некоторым учетным записям пользователей.

Я хочу проверить, зарегистрирован ли текущий пользователь, запускающий приложение, как суперпользователь. Если это так, я заставлю инструмент /usr/bin/kdesu использовать инструмент /usr/bin/sudo, который запрашивает пароль sudo.

Если пользователь не является суперпользователем, я оставляю /usr/bin/kdesu вести себя так, как он ведет себя по умолчанию — он использует инструмент /usr/bin/su, для которого требуется пароль root.

В настоящее время я использую getenv('USER') («ИМЯ ПОЛЬЗОВАТЕЛЯ» в Windows, но мне нужна эта функция только в Linux), чтобы получить текущего пользователя. Имя текущего пользователя можно получить, перейдя QProcess::systemEnvironment(), где перечислены переменные HOSTNAME и USER.

Анализ файла /etc/sudoers невозможен, так как для открытия файла требуются привилегии sudo или root.


person Ivan Caravanio    schedule 01.07.2012    source источник
comment
человек getuid () ? Не специфично для Qt. root всегда имеет нулевой UID.   -  person Torp    schedule 01.07.2012
comment
Но я не хочу знать, является ли текущий пользователь пользователем root, я хочу проверить, есть ли у текущего пользователя привилегии суперпользователя.   -  person Ivan Caravanio    schedule 01.07.2012
comment
sudo -l перечисляет права sudo текущего пользователя. Если вы запустите его, пользователь должен ввести свой пароль. Вы можете использовать что-то вроде expect, чтобы проверить, вводил ли пользователь пароль ранее и находится ли он в настоящее время во временном окне sudo.   -  person snies    schedule 01.07.2012
comment
@snies: я думаю, что пользователь не должен вводить свой пароль для sudo -l. Я только что проверил это на учетной записи без привилегий, и команда не запрашивала пароль, а просто перечисляла все разрешенные команды.   -  person n. 1.8e9-where's-my-share m.    schedule 01.07.2012
comment
вы еще не все сложности перечислили. Просто добавлю несколько: в зависимости от конфигурации вам нужно быть в группе wheel, чтобы иметь возможность использовать su, чтобы стать root. Тем не менее, getgid() может быть вашим другом: если в нем указан root, все в порядке, если в нем указано колесо, возможно, все в порядке и т. д.   -  person Klaas van Gend    schedule 01.07.2012
comment
Однако здесь есть еще кое-что - вы просите нас решить небольшую часть головоломки, которая, вероятно, уже решалась много раз. Пожалуйста, уточните, чего вы хотите достичь - путь к вашей цели может значительно отличаться от подрешения, над которым вы, кажется, работаете.   -  person Klaas van Gend    schedule 01.07.2012


Ответы (2)


   man sudo
   [...]
   -l[l] [command]
               If no command is specified, the -l (list)
               option will list the allowed (and forbidden)
               commands for the invoking user (or the user
               specified by the -U option) on the current
               host.  If a command is specified and is
               permitted by sudoers, the fully-qualified
               path to the command is displayed along with
               any command line arguments.  If command is
               specified but not allowed, sudo will exit
               with a status value of 1.  If the -l option
               is specified with an l argument (i.e. -ll),
               or if -l is specified multiple times, a
               longer list format is used.

Обновить Вам нужен (псевдо)терминал для запуска sudo. Вот один из способов сделать это:

#include <pty.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>

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

    int status, master;
    pid_t respid, pid = forkpty (&master, 0, 0, 0);
    if (pid == 0) {
        /* we are child */
        argv[0] = "/usr/bin/sudo"; /* I know it's a sin... just for a demo */
        execve("/usr/bin/sudo", argv, 0);
    }
    else if (pid > 0) {
        /* we are parent */
        respid = waitpid(pid, &status, 0);
        fprintf (stderr, "sudo exited with status %d\n", 
                   WEXITSTATUS(status));
        }
    }
    else {
        fprintf (stderr, "could not forkpty\n");
    }
}

Запустите это: runsudo -l и runsudo -l /foo/bar/baz например.

person n. 1.8e9-where's-my-share m.    schedule 01.07.2012
comment
QProcess process; QString superUserCommands; process.start( "/usr/bin/sudo -l" ); while ( process.waitForReadyRead() ) { superUserCommands = QString::fromAscii( process.readAllStandardOutput().data() ).trimmed(); } Таким образом я смогу получить доступ к командам sudo для текущего пользователя. Но в окне вывода приложения в Qt Creator указано: sudo: извините, у вас должен быть tty для запуска sudo Вероятно, это связано с тем, что для моей учетной записи пользователя требуется requiretty, и я выполняю команду терминала через графическое приложение. QProcess возвращает код 1. system() возвращает 256. - person Ivan Caravanio; 01.07.2012
comment
О, да. Извините, забыл про tty. Если у вас нет tty, вы можете создать его таким же образом, как xterm или sshd создают их (через posix_openpt(3) и друзей), или вызвать небольшую служебную функцию под названием forkpty(3) из -lutil. Я добавил пример кода в ответ. - person n. 1.8e9-where's-my-share m.; 01.07.2012

Пожалуйста, запустите приведенный ниже однострочный скрипт.
В нем будут перечислены все пользователи, у которых есть разрешения sudo, а не:

for i in $(awk -F ':' '{print $1}' /etc/passwd ); do sudo -l -U $i ; done
person linux.cnf    schedule 21.10.2020