
Я пытаюсь создать службу, которая запускает процесс.
Я хочу, чтобы при запуске процесса можно было выполнить несколько команд как пользователь root, а затем запустить остальную часть процесса как менее привилегированный пользователь, не являющийся человеком.
Например: я знаю, что apache
пользователю требуются некоторые привилегии root для настройки веб-сервера с портами и запуска различных серверных процессов, но он не работает как root все время. Я не могу найти код, который делает что-то похожее на это, и мне было интересно, есть ли другие примеры, которые я могу использовать.
По сути мой вопрос таков:как предоставить пользователю, не являющемуся root, временные права root для запуска определенных процессов, доступных только root?
Или я неправильно об этом думаю:Должен ли я не предоставлять пользователю привилегии root, а вместо этого разрешить пользователю root запускать процессы, необходимые для этого?
решение1
Существует довольно много вариантов в зависимости от того, что именно вы делаете как пользователь root. Однако для автоматизированных служб («типа apache») вы обычно начинаете как пользователь root и переходите к ограниченному пользователю.
Конфигурация в стиле Debian (включая Ubuntu и Mint) тогда будет иметь файл в /etc/default/мое-имя-службынастройка, на которую переключается пользователь. В других дистрибутивах Linux настройки хранятся в другом месте, но техника в конечном итоге та же.
Если вы пишете сервисную программу самостоятельно, вам следует использоватьsetuid(). После вызова setuid процесс не может вернуться к привилегиям root. Вам нужно будетпоиск пользователя по имениа такжеустановить группы для пользователя.
упрощаю код, который я написал давным-давно:
int lockToUser(const char * user) {
# Look up the username in /etc/passwd
struct passwd * pwd = getpwnam(user);
if (!pwd) {
# Failed... Could not find user, see errno
return 0;
}
# setuid sets the user
# setgid sets the main group similar to the group in /etc/passwd
# Sets the other groups which will grant additional permissions.
# similar to the groups in /etc/groups
if (initgroups(user, pwd->pw_gid) || setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) {
# Failed... Could not lock down to user, see errno
return 0;
}
return 1;
}