Делаем из мухи слона или кнопка для пингвина
Вврдение
После установки системы 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.