Как повысить привилегии root в bash и вернуть обратно?

Как повысить привилегии пользователя root в bash? А как тогда вернуться обратно в точно предыдущее состояние? У меня вопрос о повышении / уменьшении привилегий и возможных проблемах с некоторыми приложениями, особенно приложениями с графическим интерфейсом (и «средой»).

Скажем, некоторые приложения поддерживают отдельный профиль для каждого пользователя и пользователя root. GUI & amp; профили могут быть не единственной проблемой «среды», если я запускаю приложение от имени пользователя root, независимо от того, является ли это ошибкой их или ОС, или функцией.

Скажем, мне нужно запустить скрипт от имени пользователя root или уже запустить скрипт от имени пользователя root (как в rc.local), поэтому вам может потребоваться уменьшить привилегии или «полностью» переключиться обратно на обычного пользователя ([ 115] не всегда работает). Запустить сначала скрипт с sudo -H, а затем переключиться на другого пользователя? Это не всегда работает должным образом, особенно с приложениями с графическим интерфейсом. Я полагаю, что проблема в «окружающей среде», и DISPLAY=:0 ... или DISPLAY=:0 gtk-launch ... (gtk-launch, вероятно, прослушивается) могут быть все же бесполезными.

Скажем, у меня есть gedit с открытым документом. Если я работаю как обычный пользователь gedit /doc2, он открывается с видимым меню и в уже существующем окне в еще одна вкладка . Если я запускаю его как root, он открывается в отдельном окне и без видимого меню. Если я запускаю скрипт через sudo -H или su и пытаюсь запустить там gedit /doc2 от имени этого обычного пользователя (снова с sudo (-H) или su), то он работает так, как будто я сделал это как root, а не как обычный пользователь. Я попробовал также sudo варианты -l, -s, -i. С другими приложениями GUI, которые вызвали гораздо более серьезные проблемы. Некоторые приложения с графическим интерфейсом имеют другой графический интерфейс или вообще не запускаются. Иногда runuser помогал мне, но не всегда. И формат heredoc (sudo -H /bin/bash <<EOF <lines with commands> EOF) не работает должным образом.

1131 Это много неприятностей. Больше года я не мог найти хорошего универсального решения. Так есть ли что-нибудь для повышения привилегий и возвращения обратно? Или другие хорошие обходные пути?

И полный пример на всякий случай (запустите как sudo ./script.sh или с -H):

cd /somedir
some_commands # using the current directory, root privileges and setting some variables, and writing to somefile (better as normal user)
sudo -u normaluser /bin/bash -c 'gedit --encoding someencoding /somefile'`

Если я запускаю следующий скрипт bash как просто [ 1121]

gedit --encoding someencoding /somefile

, затем gedit работает как надо.

На всякий случай: речь идет об Ubunu 16.04 xenial, версия bash 4.3.48.

Обновление :

Я знаю, что могу запускать такие команды, как

sudo sh -c ‘command1 $somevariable; command2’

или (я обнаружил, что это может быть несколько строк)

[ 113]

или, может быть, что-то похожее с bash. Это может быть не вариант для большого набора команд и не решает всех проблем. И мне абсолютно не нужно вводить команды в интерактивном режиме. Смотрите также мой ответ.

P.S. Я думаю, что Linux должен быть удобным и простым в использовании.

-2
задан 13 May 2019 в 04:54

3 ответа

Мой ответ. Все же решение того, как просто поднять и уменьшить полномочия (на самом деле, концептуально без ровного обертывания, существующего отдельно) или полностью переключаться на корень, и назад требуется.

Базируясь на предложениях меня, LeonidMew и WinEunuuchs2Unix, вот обходное решение. -H опция обычно является хорошим выбором, таким образом, я включаю ее.

Существует два обходных решения (bash может быть заменен sh):

1) sudo -H /bin/bash -c ‘commands’ и

2) sudo -H /bin/bash -c “commands” (а также heredoc формат, sudo -H /bin/bash <<EOF <lines with commands> EOF).

1) Переменные снаружи не видимы внутри автоматически. Они должны были бы быть перемещены внутри, дважды определены или быть переданными как аргументы. Я не мог сделать или передать короткое (ре) объявление внешней функции как $(declare -f functionname) внутри (возможно, это все же возможно), но это работало, если я просто переместил его внутри.

2) Только копии переменных снаружи передаются внутри. Необходимо будет выйти с \ конструкции $(...), $PWD или другие локально определенные переменные, И комментирующий с # может не работать (как с #$(declare -f ...)). Аргументы как $1 те целого сценария и не могут быть переданы внутри как локальные переменные. Внешне определенные функции не видимы внутри, но могут быть повторно объявлены внутри как $(declare -f functionname).

В обоих случаях Вы можете быть произведены через файлы или быстрое, произведенное строкой от stdout (или несколько разделенных пробелом переменных) посредством обертывания res=$(...). Вы видите пример здесь: https://stackoverflow.com/a/23567255. Хотя после обертывания всего EOLs преобразовываются в пробелы. Возможно, export, разработанный для передачи переменных подпроцессам, поможет избежать, что обертывание или использование файлов, но так или иначе оно не работало на меня.

Случай 1), кажется, лучший выбор по умолчанию и скорее всего потребует меньшего количества модификаций существующего кода вопреки случаю 2), когда тщательная модификация существующего кода будет обычно требоваться. Возможно, Вы найдете оба случая полезными одновременно.

Это - мой простой пример:

tmpdir=/tmp/ tmpfile=/tmp/tmpfile res=$(sudo -H bash -c 'tmpdir=$1; tmpfile=$2 echo "$tmpdir;" cd $ tmpdir echo $(pwd) echo "A string from file" > $tmpfile ' - $tmpdir $tmpfile) echo $res arr=($res) echo ${arr[0]} # Hellooo echo ${arr[1]} # world; echo ${arr[*]} # whole array echo ${#arr[*]} # number of items n=0 echo ${#arr[$n]} # length of the n-th element cat $tmpfile sudo sh -c 'rm -f $2' - - $tmpfile

-1
ответ дан 13 May 2019 в 04:54

Чтобы повысить привилегии для нескольких команд в скрипте, используйте sudo с синтаксисом heredoc:

possiblevariable=something    
sudo /bin/bash <<EOF
    cd /somedir
    pwd
    commandasroot1 "$possiblevariable"
    commandasroot2
EOF
nonrootcommand (and not in /somedir)

Тестирование cd: (рабочий каталог изменен внутри heredoc, но восстанавливается, как это было раньше в конце heredoc)

leonid@DevSSD:~$ sudo bash <<EOF
> cd /tmp
> pwd
> EOF
[sudo] password for leonid: 
/tmp
leonid@DevSSD:~$ 

Еще один пример, показывающий, как подстановка переменных работает в heredoc:

leonid@DevSSD:~$ sudo bash <<EOF
    cd /tmp
    echo $PWD; echo \$PWD
EOF
[sudo] password for leonid: 
/home/leonid
/tmp
leonid@DevSSD:~$ 

Обновление: пример того, как вы можете получить вывод в переменную

leonid@DevSSD:~$ variable=$(sudo bash <<EOF
    cd /tmp
    echo $PWD; echo \$PWD
EOF
)
[sudo] password for leonid: 
leonid@DevSSD:~$ echo $variable
/home/leonid /tmp
0
ответ дан 13 May 2019 в 04:54

У меня не так много сценариев, которые повышают привилегии пользователя до полномочий sudo (суперпользователя). По иронии судьбы, из-за того, что ваш вопрос касается gedit одного из моих сценариев, он называется sgedit. Он был создан из-за того, что gksu gedit больше не поддерживается и из-за того, что пользователь root не может устанавливать настройки вкладок, настройки шрифтов и т. Д.

#!/bin/bash

# NAME: sgedit
# PATH: /mnt/e/bin
# DESC: Run gedit as sudo using $USER preferences
# DATE: June 17, 2018.

# Must not prefix with sudo when calling script
if [[ $(id -u) == 0 ]]; then
    zenity --error --text "You cannot call this script using sudo. Aborting."
    exit 99
fi

# Get user preferences before elevating to sudo
gsettings list-recursively | grep -i gedit | grep -v history | \
    grep -v docinfo | \
    grep -v virtual-root | grep -v state.window > /tmp/gedit.gsettings

sudoFunc () {

    # Must be running as sudo
    if [[ $(id -u) != 0 ]]; then
        zenity --error --text "Sudo password authentication failed. Aborting."
        exit 99
    fi

    # Get sudo's gedit preferences
    gsettings list-recursively | grep -i gedit | grep -v history | \
        grep -v docinfo | \
        grep -v virtual-root | grep -v state.window > /tmp/gedit.gsettings.root
    diff /tmp/gedit.gsettings.root /tmp/gedit.gsettings | grep '>' > /tmp/gedit.gsettings.diff
    sed -i 's/>/gsettings set/g; s/uint32 //g' /tmp/gedit.gsettings.diff
    chmod +x /tmp/gedit.gsettings.diff
    bash -x /tmp/gedit.gsettings.diff  # Display override setting to terminal
#    nohup gedit $@ &>/dev/null &
    nohup gedit -g 1300x840+1+1220 $@ &>/dev/null &
#              Set the X geometry window size (WIDTHxHEIGHT+X+Y).

}

FUNC=$(declare -f sudoFunc)
sudo -H bash -c "$FUNC; sudoFunc $*;"

exit 0

Сценарий должен вызываться в обычном пользовательском режиме. Копирует gsettings для gedit из профиля пользователя в /tmp. Важные настройки, такие как размер шрифта, перенос строки, настройки вкладок, преобразование вкладок в пробелы и плагины, копируются.

Затем запрашивается sudo пароль и статус повышается до root.

sudo -H используется для эквивалентной gksu защиты, чтобы не дать root полномочиям забивать файлы конфигурации пользователя.

Следующие корневые параметры конфигурации для gedit наследуются от профиля вызывающего пользователя, который был скопирован в /tmp.

gedit загружается как фоновая задача, и пользователю предоставляется sudo версия открытого файла. Например, /etc/default/grub.

Полномочия sudo немедленно сбрасываются, и приглашение командной строки возвращается. Однако gedit все еще работает в отдельном окне с файлом, открытым для редактирования.

0
ответ дан 13 May 2019 в 04:54

Другие вопросы по тегам:

Похожие вопросы: