Делаем из мухи слона или кнопка для пингвина
Введение
После установки системы Gentoo Linux на свой нетбук я неожиданно обнаружил, что в системе нет штатного средства выключения и перезагрузки от обычного пользователя без использования sudo.
Защитное слово автора
Сразу хотел бы отметить, что не призываю пользоваться данной программой, так как решение для управления выключением и перезагрузкой, предложенное мной, является нестандартным средством и по этой причине не может быть рекомендовано. Код программы также не может служить примером для обучения, поскольку автор программы не является профессиональным программистом. Данная статья и код на языке C публикуются в ознакомительных целях.
История вопроса
После установки системы Gentoo Linux на свой нетбук я неожиданно обнаружил, что в системе нет штатного средства выключения и перезагрузки от обычного пользователя без использования дополнительных средств вроде программы sudo, а исследование файла
/etc/group показало, что в нём нет группы operator. Любые попытки добавить эту группу и пользователя в неё не принесли желаемого результата - компьютер не перезагружался от простого пользователя.
Несколько поразмыслив, я пришёл к идеи (вероятно, я не был первым) научить планировщик cron перезагружать и выключать компьютер . Для этого мной наскоро был написан скрипт на bash и добавлено задание в cron для суперпользователя.
Скрипт запускался раз в минуту от root, проверял файл в директории пользователя на наличие в нём управляющего символа и осуществлял перезагрузку или выключение, записывал в этот файл код 0 для бездействия, чтобы компьютер не начал перезагружаться бесконечно. Я и сам не заметил, что своими руками создал уязвимость в системе (хотя подозрения были). Спасибо участникам форума Linux.org.ru, которые вовремя указали мне на ошибки и дали ряд дельных советов по улучшению моей скромной системы.
Описание технологии
После некоторых переработок система приобрела следующий вид:
На языке C написана программа, которая выполняется 1 раз при старте системы через планировщик cron и создаёт специальный файл /run/shut.txt. Данному файлу присваиваются права на чтение для root и права на запись для пользователя. Хозяином файла назначается пользователь.
Написана еще одна программа на C, назначение которой один раз в минуту проверять появление управляющего символа в файле /run/shut.txt.
Если символ появился, то выполнить перезагрузку или выключение.
Для пользователя добавлены два sh скрипта, назначение которых отправить в файл /run/shut.txt управляющий символ для выключения и перезагрузки. Это вся система. По настроению в пользовательские скрипты можно добавить звуковой эффект.
Данная система интересна тем, что её код получился крайне минималистичным, фактически - это тот случай, когда программу можно собрать, используя примеры из классического учебника по языку C. Таким образом данная система служит примером того, что "учебный код" может иметь полезное применение.
1) Программа создания файла /run/shut.txt с управляющим символом:
check_shutdown_reboot_file.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>А
int main ()
{
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char *filename = "/run/shut.txt";
/*Cоздадим файл, установим права и владельца*/
creat(filename, mode);
chown(filename, 1000, 0);
}
2) Программа проверки управляющего символа:
shut_and_reb.c
#include <stdio.h>
#include <stdlib.h>
int main ()
{
char c;
FILE *file;
/*Откроем файл, прочитаем управляющий символ, перезагрузим или выключим.*/
file = fopen("/run/shut.txt", "r");
c = getc (file);
if (c == '9')
system("/sbin/reboot");
if (c == '8')
system("/sbin/poweroff");
fclose(file);
}
3) Скрипт sh (кнопка) для перезагрузки (можно поместить в /usr/local/bin или /home/USER/bin или создать alias):
reboot_com.sh
echo 9 > /run/shut.txt
amixer set Master off & amixer set Master toggle & beep -f 2200 -l 3000
4) 3) Скрипт sh (кнопка) для выключения (можно поместить в /usr/local/bin или /home/USER/bin или создать alias, etc):
shutdown_comp.sh
echo 8 > /run/shut.txt
amixer set Master off & amixer set Master toggle & beep -f 2200 -l 3000
#mplayer /home/iv/Музыка/zavershenie-raboty-cistemnyy-zvuk-windows-xp.mp3
5) Содержимое crontab -e суперпользователя root:
@reboot /usr/local/bin/check_shutdown_reboot_file
*/1 * * * * /usr/local/bin/shut_or_reb
P.S.
Комментарии (38)
nochkin
06.12.2022 21:09+1Возможно в Gentoo это отключено, но обычно для перезагрузки пользователем есть Ctrl+Alt+Del.
k-semenenkov
06.12.2022 21:18+13Наверно баян но вспомнилась байка про подзависающий системник А, и чтобы держать его аптайм - напротив поставили системник Б который пинговал А, и когда пропадал пинг - у Б выезжал лоток дисковода и нажимал резет А
phaggi
07.12.2022 20:42Видел удаленное выключение путем печати матричного принтера, к головке которого привязан кабель питания. А ресет сиди-приводом… красота!
lorc
06.12.2022 21:25+6Современные линуксы используют systemd и polkit для этого: https://wiki.archlinux.org/title/allow_users_to_shutdown
Gentoo тоже вроде бы поддерживает systemd
inetstar
06.12.2022 21:39+9У меня в Gentoo и Calculate Linux есть возможность из под KDE как выключить, так и перегрузить комп.
А у sudo есть специальный файл sudoerrs и специальная директория, где можно разрешить юзеру выполнять только одну/две программы из под рута.
isBlaze
06.12.2022 21:59+7ух…
alias shutdown=«sudo shutdown»
и всё. обычный пользователь может делать выключение и перезагрузку без судоdcc0 Автор
07.12.2022 11:02В системе нет sudo, от слова совсем.
isBlaze
07.12.2022 11:04+1а поставить нельзя?
dcc0 Автор
07.12.2022 13:26-2Можно, но тогда нет повода для статьи :)
Я чуть позже нашёл похожий способ автоматизации с incron и inotify, здесь на habr:
https://habr.com/ru/post/66569/ но было уже поздно.
F0iL
06.12.2022 22:02+1Мне прям очень интересно, зачем городить две программы на Си, когда все то же самое элементарно делается шелл-скриптом из пары строчек?
Rosti
06.12.2022 22:03+1А зачем вообще заморачиваться с С? Любой шелл скрипт сделает тоже-самое и будет намного удобнее.
А если ещё сделать с "inotifywait -e close_write file", то не надо каждый раз проверять содержимое вайла, а просто ждать пока система сообщит что файл был записан.
nice_nick_matter
06.12.2022 22:21Если у вас обычная инсталляция Генту, то
loginctl poweroff
(из sys-auth/eligond) спасут отца русской демократии.dcc0 Автор
07.12.2022 13:42Спасибо. Всегда появится мудрый человек, который знает простой путь. Спасут, конечно же. Однако мне моя идея с cron нравится в том смысле, что она показывает на очень простом примере способы взаимодействия между пользователями.
KorP
06.12.2022 22:22+3Ноутбук с гентой
Собственная выключалка на С
человек просто любит сложности и велосипеды
Arioch
06.12.2022 22:54+5Сделать chmod +suid нельзя, нужно брать "большой" ЯП и учиться демонов писать?
Не понимаю...
DreamingKitten
07.12.2022 05:27+4что в системе нет штатного средства выключения и перезагрузки от обычного пользователя без использования sudo.
systemctl poweroff
systemctl reboot
вполне себе от обычного пользователя работают.
dcc0 Автор
07.12.2022 13:16Нет systemctl в системе.
DreamingKitten
07.12.2022 13:53+1Есть systemctl в системе. Это часть пакета systemd, который, в свою очередь, является частью stage3.
Если же вы возразите, что использовали stage3 с OpenRC, то это называется «героическое преодоление собственноручно созданных самому себе препятствий». Если так, то вы не поняли, что такое Gentoo way.
dcc0 Автор
07.12.2022 14:00-2Не помню уже. Вроде бы был какой-то выбор, и я выбрал OpenRc. Использую Gentoo, но Gentoo way я никогда не следовал. Я и не знаю, что это такое. Я довольно специфично пользуюсь системой, многим такой способ не подойдет.
DreamingKitten
07.12.2022 14:32+4Так вот, Gentoo way это о том, что любой выбор на любом шаге установки\использования является осознанным и информированным, а не «какой-то не помню».
BFSold1er
07.12.2022 05:49-1это программа для вечного перезапуска ПК? 1 раз запустил скрипт и вечный ребут, или выключение
mapnik
Потому что линукс — это всё-таки немного юникс.
Вот представьте, что вы университет. И у вас есть юниксовая машина, а на ней сидят пользователи со всей страны через модемы. Человек так сто-пятьсот одновременно. Решают какие-то научные и учебные задачи, машинное время используют, в очередь за ним стоят, по записи.
И у каждого при этом есть возможность эту машину перезагрузить. Или выключить.
georgevp
Тогда для чего продвигать Linux за пределы серверных станций? И да, владельцы маков, наверное плачут от умиления, читая Ваш снобистский комментарий.
mapnik
Я владелец мака, но не плачу от умиления даже от своего собственного снобистского комментария :)
georgevp
Вас не смущает, что macOS является UNIX-cистемой? И в ней есть штатные механизмы выключения.
mapnik
Не смущает. Apple изначально делала однопользовательские компьютеры, и их недавнее решение заменить ядро системы никак не меняет их изначальной концепции.
georgevp
Я с Вами согласен, что для университетского компьютера такая возможность выключения явно была бы лишней. Однако, Вы сами пишите, что Линукс - это немного Юникс. При этом, по-моему, другое "немного" ушло со временем за пределы университетов и появилось у нас на личных компьютерах, выключение которых не обвалит рынки и не остановит производство. Автор статьи, по-видимому, считает, что его опыт по привнесению удобства в пользовании его личного нетбука может быть полезен/интересен/загадочен (нужный вариант выберете сами). Только и всего. К тому же, авторы Gentoo Linux сами стремятся к тому, чтобы у пользователей был инструмент (ОС), идеально соответствующий Их потребностям..
P.S. А авторов, критикуя, как мне представляется, надо поощрять.