Делаем из мухи слона или кнопка для пингвина

Введение

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

Защитное слово автора

Сразу хотел бы отметить, что не призываю пользоваться данной программой, так как решение для управления выключением и перезагрузкой, предложенное мной, является нестандартным средством и по этой причине не может быть рекомендовано. Код программы также не может служить примером для обучения, поскольку автор программы не является профессиональным программистом. Данная статья и код на языке C публикуются в ознакомительных целях.

История вопроса

После установки системы Gentoo Linux на свой нетбук я неожиданно обнаружил, что в системе нет штатного средства выключения и перезагрузки от обычного пользователя без использования дополнительных средств вроде программы sudo, а исследование файла
/etc/group показало, что в нём нет группы operator. Любые попытки добавить эту группу и пользователя в неё не принесли желаемого результата - компьютер не перезагружался от простого пользователя.

Несколько поразмыслив, я пришёл к идеи (вероятно, я не был первым) научить планировщик cron перезагружать и выключать компьютер . Для этого мной наскоро был написан скрипт на bash и добавлено задание в cron для суперпользователя.

Скрипт запускался раз в минуту от root, проверял файл в директории пользователя на наличие в нём управляющего символа и осуществлял перезагрузку или выключение, записывал в этот файл код 0 для бездействия, чтобы компьютер не начал перезагружаться бесконечно. Я и сам не заметил, что своими руками создал уязвимость в системе (хотя подозрения были). Спасибо участникам форума Linux.org.ru, которые вовремя указали мне на ошибки и дали ряд дельных советов по улучшению моей скромной системы.

Описание технологии

После некоторых переработок система приобрела следующий вид:

  1. На языке C написана программа, которая выполняется 1 раз при старте системы через планировщик cron и создаёт специальный файл /run/shut.txt. Данному файлу присваиваются права на чтение для root и права на запись для пользователя. Хозяином файла назначается пользователь.

  2. Написана еще одна программа на C, назначение которой один раз в минуту проверять появление управляющего символа в файле /run/shut.txt.

  3. Если символ появился, то выполнить перезагрузку или выключение.

  4. Для пользователя добавлены два 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.

Код на Gitflic.ru

Комментарии (38)


  1. mapnik
    06.12.2022 20:48
    +18

    я неожиданно обнаружил, что в системе нет штатного средства выключения и перезагрузки от обычного пользователя

    Потому что линукс — это всё-таки немного юникс.
    Вот представьте, что вы университет. И у вас есть юниксовая машина, а на ней сидят пользователи со всей страны через модемы. Человек так сто-пятьсот одновременно. Решают какие-то научные и учебные задачи, машинное время используют, в очередь за ним стоят, по записи.

    И у каждого при этом есть возможность эту машину перезагрузить. Или выключить.


    1. georgevp
      06.12.2022 21:51
      -17

      Тогда для чего продвигать Linux за пределы серверных станций? И да, владельцы маков, наверное плачут от умиления, читая Ваш снобистский комментарий.


      1. mapnik
        06.12.2022 21:54
        +6

        Я владелец мака, но не плачу от умиления даже от своего собственного снобистского комментария :)


        1. georgevp
          06.12.2022 22:36
          -2

          Вас не смущает, что macOS является UNIX-cистемой? И в ней есть штатные механизмы выключения.


          1. mapnik
            06.12.2022 22:50
            +2

            Не смущает. Apple изначально делала однопользовательские компьютеры, и их недавнее решение заменить ядро системы никак не меняет их изначальной концепции.


            1. georgevp
              06.12.2022 23:31
              -1

              Я с Вами согласен, что для университетского компьютера такая возможность выключения явно была бы лишней. Однако, Вы сами пишите, что Линукс - это немного Юникс. При этом, по-моему, другое "немного" ушло со временем за пределы университетов и появилось у нас на личных компьютерах, выключение которых не обвалит рынки и не остановит производство. Автор статьи, по-видимому, считает, что его опыт по привнесению удобства в пользовании его личного нетбука может быть полезен/интересен/загадочен (нужный вариант выберете сами). Только и всего. К тому же, авторы Gentoo Linux сами стремятся к тому, чтобы у пользователей был инструмент (ОС), идеально соответствующий Их потребностям..
              P.S. А авторов, критикуя, как мне представляется, надо поощрять.


  1. nochkin
    06.12.2022 21:09
    +1

    Возможно в Gentoo это отключено, но обычно для перезагрузки пользователем есть Ctrl+Alt+Del.


  1. funca
    06.12.2022 21:11
    +6

    Отлично. Ждём ebuild'ов.


    1. dcc0 Автор
      07.12.2022 10:55
      +1

      Классная шутка :)


      1. LevOrdabesov
        07.12.2022 11:20
        +1

        нестареющая...


  1. k-semenenkov
    06.12.2022 21:18
    +13

    Наверно баян но вспомнилась байка про подзависающий системник А, и чтобы держать его аптайм - напротив поставили системник Б который пинговал А, и когда пропадал пинг - у Б выезжал лоток дисковода и нажимал резет А


    1. phaggi
      07.12.2022 20:42

      Видел удаленное выключение путем печати матричного принтера, к головке которого привязан кабель питания. А ресет сиди-приводом… красота!


  1. lorc
    06.12.2022 21:25
    +6

    Современные линуксы используют systemd и polkit для этого: https://wiki.archlinux.org/title/allow_users_to_shutdown

    Gentoo тоже вроде бы поддерживает systemd


  1. inetstar
    06.12.2022 21:39
    +9

    У меня в Gentoo и Calculate Linux есть возможность из под KDE как выключить, так и перегрузить комп.

    А у sudo есть специальный файл sudoerrs и специальная директория, где можно разрешить юзеру выполнять только одну/две программы из под рута.


  1. Mirzapch
    06.12.2022 21:40
    +5

    Если вы собрали систему по Gentoo Handbook, для выключения ноутбука достаточно нажать кнопку включения. Даже команд вводить не придётся.


    1. dcc0 Автор
      07.12.2022 14:09

      Да, это работает. И перезагрузка через клавиатуру тоже работат.


  1. isBlaze
    06.12.2022 21:59
    +7

    ух…
    alias shutdown=«sudo shutdown»
    и всё. обычный пользователь может делать выключение и перезагрузку без судо


    1. dcc0 Автор
      07.12.2022 11:02

      В системе нет sudo, от слова совсем.


      1. isBlaze
        07.12.2022 11:04
        +1

        а поставить нельзя?


        1. dcc0 Автор
          07.12.2022 13:26
          -2

          Можно, но тогда нет повода для статьи :)
          Я чуть позже нашёл похожий способ автоматизации с incron и inotify, здесь на habr:
          https://habr.com/ru/post/66569/ но было уже поздно.


  1. F0iL
    06.12.2022 22:02
    +1

    Мне прям очень интересно, зачем городить две программы на Си, когда все то же самое элементарно делается шелл-скриптом из пары строчек?


  1. Rosti
    06.12.2022 22:03
    +1

    А зачем вообще заморачиваться с С? Любой шелл скрипт сделает тоже-самое и будет намного удобнее.

    А если ещё сделать с "inotifywait -e close_write file", то не надо каждый раз проверять содержимое вайла, а просто ждать пока система сообщит что файл был записан.


  1. Mirzapch
    06.12.2022 22:09

    Товарищ, а что такое

    неутбук?

    @dcc0зачем-то запретил отправлять ему уведомления по Ctrl+Enter...


  1. nice_nick_matter
    06.12.2022 22:21

    Если у вас обычная инсталляция Генту, то loginctl poweroff (из sys-auth/eligond) спасут отца русской демократии.


    1. dcc0 Автор
      07.12.2022 13:42

      Спасибо. Всегда появится мудрый человек, который знает простой путь. Спасут, конечно же. Однако мне моя идея с cron нравится в том смысле, что она показывает на очень простом примере способы взаимодействия между пользователями.


  1. KorP
    06.12.2022 22:22
    +3

    Ноутбук с гентой

    Собственная выключалка на С
    человек просто любит сложности и велосипеды


  1. Arioch
    06.12.2022 22:54
    +5

    Сделать chmod +suid нельзя, нужно брать "большой" ЯП и учиться демонов писать?
    Не понимаю...

    https://ru.wikipedia.org/wiki/Suid

    https://habr.com/ru/company/jetinfosystems/blog/506750/


  1. Starl1ght
    06.12.2022 23:34
    +1

    Я со статьи в голос смеялся. Только гентушник может тратить так бессмысленно тратить свое время.


    1. kolu4iy
      07.12.2022 21:06

      Нет. Гентушник знает более простой и правильный способ. И гамак для секса выбирает совершенно сознательно, с учетом тонкостей и предыдущих ошибок.


  1. DreamingKitten
    07.12.2022 05:27
    +4

    что в системе нет штатного средства выключения и перезагрузки от обычного пользователя без использования sudo.

    systemctl poweroff

    systemctl reboot

    вполне себе от обычного пользователя работают.


    1. dcc0 Автор
      07.12.2022 13:16

      Нет systemctl в системе.


      1. DreamingKitten
        07.12.2022 13:53
        +1

        Есть systemctl в системе. Это часть пакета systemd, который, в свою очередь, является частью stage3.

        Если же вы возразите, что использовали stage3 с OpenRC, то это называется «героическое преодоление собственноручно созданных самому себе препятствий». Если так, то вы не поняли, что такое Gentoo way.


        1. dcc0 Автор
          07.12.2022 14:00
          -2

          Не помню уже. Вроде бы был какой-то выбор, и я выбрал OpenRc. Использую Gentoo, но Gentoo way я никогда не следовал. Я и не знаю, что это такое. Я довольно специфично пользуюсь системой, многим такой способ не подойдет.


          1. DreamingKitten
            07.12.2022 14:32
            +4

            Так вот, Gentoo way это о том, что любой выбор на любом шаге установки\использования является осознанным и информированным, а не «какой-то не помню».


            1. dcc0 Автор
              08.12.2022 02:58

              Пингвин с ним! Gentoo way неинтересен в данном случае.


  1. BFSold1er
    07.12.2022 05:49
    -1

    это программа для вечного перезапуска ПК? 1 раз запустил скрипт и вечный ребут, или выключение


  1. includedlibrary
    07.12.2022 10:02
    +1

    А в чём проблема использовать loginctl?


  1. ajijiadduh
    07.12.2022 10:32

    заяление