Я изменил свой код на:
function gp() { grep -rnIi --exclude-dir='.svn' $1 $2;}
и это работает
Единственный способ, который я мог придумать, это проверить одну из SUDO_*
сред. переменные, установленные sudo:
#!/usr/bin/env sh
if [ "$(id -u)" -eq 0 ]
then
if [ -n "$SUDO_USER" ]
then
printf "This script has to run as root (not sudo)\n" >&2
exit 1
fi
printf "OK, script run as root (not sudo)\n"
else
printf "This script has to run as root\n" >&2
exit 1
fi
Обратите внимание, что это решение, конечно, не рассчитано на будущее, поскольку вы не можете кто-либо из установки переменной перед запуском скрипта:
$ su
Password:
# SUDO_USER=whatever./root.sh
This script has to run as root (not sudo)
#./root.sh
OK, script run as root (not sudo)
Я предлагаю проверить строки списка процессов и посмотреть, запускает ли пользователь программу, используяsudo
contype=`tty | cut -d '/' -f 3`
tty="$contype/`tty | cut -d '/' -f 4`"
if [ "$(id -u)" -eq 0 ]
then
res=`ps ax | grep "$tty" | grep "$0" | grep "sudo"`
if [ $? == 0 ]
then
echo "You should not run the script using sudo!"
exit 2
else
echo "Done."
fi
else
echo "You are not root. Run this script as root."
exit 2
fi
Эта переменная res
просто для вас, если вы хотите снова отфильтровать результаты.
Код Arkadusz хорош, но, к сожалению, его можно очень легко обойти...
Информация о том, какой пользователь вошел в систему, доступна в /proc/self/loginuid
. РЕДАКТИРОВАТЬиз-за комментариев :Похоже, что этот файл существует не во всех системах. Я тестировал, и он доступен на Centos 6, Fedora 32, Fedora 33 и Ubuntu 20.04, все в стандартных настройках x86 _64. Если мы войдем в систему как наш пользователь, а затем используем sudo
или su
, чтобы стать root, это не изменит /proc/self/loginuid
, и это будет некоторое ненулевое значение -. Если мы напрямую войдем в систему как root, то cat /proc/self/loginuid
вернет 0
. Обратите внимание, что этот файл НЕЛЬЗЯ изменять, даже root не может этого сделать.РЕДАКТИРОВАТЬиз-за комментария Stéphane Chazelas :Root может перезаписать этот файл, используя echo 0 > /proc/self/loginuid
. Однако этого можно избежать, установив auditctl --loginuid-immutable
.
Сценарий для проверки реального корня (, если auditctl --loginuid-immutable
установлен ), может выглядеть так
#!/bin/bash
loginuid=$(cat /proc/self/loginuid)
echo $loginuid
if [[ $loginuid -ne 0 ]]; then
echo "You did not log in as root."
exit
fi
sudo
в скриптеroot
bash? К сожалению, стойкого пути нет... Пожалуйста, дочитайте внимательно до последнего абзаца
Как только вы даете root-доступ кому-то, они могут делать что угодно, включая редактирование вашего скрипта!!
Например, если пользователь нажал sudo su -
, то переменные SUDO_*
больше не существуют...
pstree
Таким образом, более простой способ поиска sudo
присутствия во всем текущем дереве, похоже, используетpstree
:
die() { echo >&2 ${0##*/} Error: "$@"; exit 1;}
pstree -s $$ | grep -q '\bsudo\b' && die "Can't be run under sudo"
ps
вы можете зацикливаться наps ho ppid
:die() { echo >&2 ${0##*/} Error: "$@"; exit 1;}
pid=$$
while read pid name foo < <(ps ho ppid,cmd $pid) && ((pid>1));do
[ "$name" = "sudo" ] && die "Can't be run under sudo"
done
sudo
Если команда sudo переименована или скопирована, то вместо поиска имени команды ищите UID во всем родительском дереве. Итак, сценарий такой же, как и предыдущий,но поиск UID >= 1000
в родительском дереве:
die() { echo >&2 ${0##*/} Error: "$@"; exit 1;}
pid=$$
while read pid uid < <(ps ho ppid,uid $pid) && ((pid>1));do
((uid>999)) && die "Can't be run under sudo"
done
Чтобы быть правильным, избегайте использования фиксированных статических данных, используйте UID_MIN
из /etc/login.defs
:
die() { echo >&2 ${0##*/} Error: "$@"; exit 1;}
while read fld val;do
case $fld in UID_MIN ) UIDMIN=$val ;break ;; esac
done </etc/login.defs
((UIDMIN)) || die Getting UID_MIN.
pid=$$
while read pid uid < <(ps ho ppid,uid $pid) && ((pid>1));do
(( uid >= UIDMIN )) && die "Can't be run under sudo"
done
sudo
в любом случае Но все это как-то хрупко:
$ sudo su -
# screen -D -R # apt install screen if not installed
Теперь нажмите Ctrl + a , затем d , чтобы отсоединиться . Введите exit
или нажмите Ctrl + d , чтобы вернуться в пользовательский режим ...
Тогда просто:
$ sudo screen -x
Теперь вы войдете в сеанс корневого входа . Никаких следов sudo.
# ps $PPID
PID TTY STAT TIME COMMAND
26367 ? Ss 0:00 SCREEN -D -R
# ps ho ppid $PPID
1
# set | grep SUDO
# <-- nothing here!
Как chepner правильно прокомментировал:sudo предназначен для предоставления доступа к конкретным инструментам:
Nothing about sudo requires it to give you root access; that's just the default behavior everyone is familiar with. sudo can be configured to allow you to do only very specific things, including not gain root access at all – chepner
Позаботьтесь о том, чтобы настроить их правильно, прежде чем использовать хрупкий обходной путь!
См.:
apropos sudo
И читайте внимательно
man sudo.conf
man sudoers
logname
Посмотрите на правильный ответ Стефана Шазела ! Это может быть лучшим ответом на домашнее задание !!
Опять же, множество обходных путей , таких как:echo 0 > /proc/self/loginuid
...
/proc/self/loginuid
подLinuxПожалуйста, прочтите интересный ответ laolux по этому поводу!
die() { echo >&2 ${0##*/} Error: "$@"; exit 1;}
read lUid </proc/self/loginuid || die "Can't access procfile"
((lUid)) && die "You must be logged as root."
(Этот синтаксис избегает разветвлений!)
Но тем не менее
cron
запись для инициации специального screen
сеанса какroot
.(cron
и screen
— не единственный способ делать подобные вещи! Просто первое, что пришло мне в голову.)man sudoers
(детали могут различаться от системы к системе)
«Подключаемый модуль политики sudoers определяет привилегии пользователя sudo. Это подключаемый модуль политики sudo по умолчанию. Политика управляется файлом /etc/sudoers...»
«Файл sudoers состоит из двух типов записей :псевдонимов (, в основном переменных )и пользовательских спецификаций (, которые определяют, кто и что может запускать )».
Удалите всех пользователей из /etc/sudoers (детали опущены ), и команда sudo не будет работать ни для кого. После этого только root может запускать команды, требующие привилегий root.
Существуют параметры конфигурации, позволяющие пользователю запускать команды, кроме конкретной команды, и наоборот.
Обратите внимание, что мы делаем за вас домашнее задание, и мы не должны делать это снова.
if [ "$(id -u)" -ne 0 ] || [ "$(logname)" != root ]; then
echo >&2 "You either don't have superuser privilege or didn't login as root"
exit 1
fi
Ненадежный, так как любой процесс с привилегиями суперпользователя, который может выполнять любую команду, может сделать что угодно, чтобы обойти что угодно, но может быть близок к тому, что ожидает учитель, и является стандартным.
Просто чтобы опубликовать что-то совершенно другое:
if ! tty -s 2>&0
then echo "Need to run with standard error on a terminal"
exit 1
fi
if [ x"`stat --printf=%u $(tty)`" != x"0" ]
then echo "Must be logged in as root. Can't use sudo or su here."
exit 1
fi
Это работает путем проверки того, принадлежит ли терминальное устройство вошедшего -пользователя пользователю root. Как и со всеми другими ответами, его можно обмануть, если очень захотеть.