@ -23,44 +23,162 @@ SYSCONF="${ROOTFS}${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/security; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null
# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
shopt -s extglob
declare -A POLKIT
exec_polkit_ubinstall(){
[[ $(cmdline_value ub.sgnfiles) =~ .*"-iso.sgn" ]] && POLKIT[com.ublinux.ubinstall-gtk.]=yes:wheel
[[ $(cmdline_value ub.sgnfiles) =~ .*"-iso.sgn" ]] && POLKIT[com.ublinux.ubinstall-gtk.]=yes
}
## Управление разрешениями действий polkit, можно разрешать для группы пользователей
## POLKIT[<id_object>]=<result>[:<user_1>,<user_n>,<@group_1>,<@group_n>:<active>:<local>]"
## Посмотреть все доступные объекты polkit: pkaction | grep udisks
## <id_object> # Имя схемы, применимо использование не полного имени до .(точки)
## org.freedesktop.udisks2. # Mounting a filesystems all subgroup | Монтировать файловую систему все подгруппы
## org.freedesktop.udisks2.filesystem-mount # Mounting a filesystems | Монтировать файловую систему
## org.freedesktop.udisks2.filesystem-mount-system # Mount a filesystem on a system device | Монтировать файловую систему на системном устройстве
## org.freedesktop.udisks2.filesystem-mount-other-seat # Mount a device attached to another seat | Монтировать файловую систему с устройства, подключенного в другое место
## org.freedesktop.udisks2.filesystem-unmount-others # Unmount a device mounted by another user | Демонтировать устройство, смонтированное другим пользователем
## org.freedesktop.udisks2.eject-media-other-seat # Разрешение на извлечение лотка оптического привода пользователям, подключенным не к основному рабочему месту
## org.freedesktop.udisks2.power-off-drive-other-seat # Разрешение на извлечение usb-диска пользователям, подключенным не к основному рабочему месту
## org.freedesktop.machine1.host-login
## org.freedesktop.DisplayManager.AccountsService.ModifyAny
## org.freedesktop.login1.suspend
## org.freedesktop.login1.suspend-multiple-sessions
## org.freedesktop.login1.suspend-ignore-inhibit
## org.freedesktop.login1.hibernate
## org.freedesktop.login1.hibernate-multiple-sessions
## org.freedesktop.login1.hibernate-ignore-inhibit
## org.freedesktop.login1.reboot
## org.freedesktop.login1.reboot-multiple-sessions
## org.freedesktop.login1.reboot-ignore-inhibit
## org.freedesktop.login1.set-reboot-parameter
## org.freedesktop.login1.set-reboot-to-boot-loader-entry
## org.freedesktop.login1.set-reboot-to-boot-loader-menu
## org.freedesktop.login1.set-reboot-to-firmware-setup
## org.freedesktop.login1.manage
## org.freedesktop.login1.lock-sessions
## org.freedesktop.login1.chvt
## org.freedesktop.upower.hibernate
## org.freedesktop.upower.suspend
## org.xfce.power.xfce4-pm-helper
## org.xfce.session.xfsm-shutdown-helper
## org.manjaro.pamac. # GUI Pamac install package | ГУЙ pamac установка и обновление пакетов
## org.opensuse.cupspkhelper.mechanism.all-edit # Printer settings | Настройки принтера
## org.freedesktop.NetworkManager. # NetworkManager settings | Настройки NetworkManager
## org.freedesktop.NetworkManager.settings.modify.system # Разрешение на создание и модификацию системных сетевых соединений
## <result> # Действие на правило
## yes # Предоставить разрешения
## no # Заблокировать разрешения
## auth_self # Пользователь должен ввести свой пароль для аутентификации
## auth_self_keep # Пользователь должен ввести свой пароль для аутентификации, авторизация сохраняется на несколько минут
## auth_admin # Пользователь должен ввести пароль администратора при каждом запросе
## auth_admin_keep # Пользователь должен ввести пароль администратора, авторизация сохраняется на несколько минут
## null # Пробовать следующую пользовательскую функцию
## log # Сделать запись сообщения о событии в системном журнале
## # Сервис polkit перезапускается без параметра --no-debug
## # В параметре action передается объект с информацией о совершенном процессе и связанные с этим действием параметры
## # В параметре subject передается объект с информацией о пользователе, запустившем процесс. Этот объект имеет следующие атрибуты:
## # id — идентификатор процесса;
## # user — имя пользователя;
## # groups — список групп, в которые входит пользователь;
## # seat — местонахождение субъекта (пустое значение, если местонахождение не локальное);
## # session — сессия субъекта;
## # local — true, только если местонахождение имеет локальный характер;
## # active — true, только если сеанс активен.
## <user> # Имена пользователей перечисленные через запятую
## <@group> # Имена групп перечисленные через запятую, перед именем группы ставится знак @
## <active> # Применять правило только для активных сейнсов
## <local> # Применять правило только если местонахождение локальное
##
## POLKIT[org.freedesktop.udisks2.]=yes:@storage
## POLKIT[org.manjaro.pamac.]=yes:@wheel,user-1
## POLKIT[com.ublinux.ubl-settings-datetime.run]=yes:@users:true:true
## POLKIT[org.manjaro.pamac.]=log
## POLKIT[com.ublinux.ubl-settings-kernel.run]=yes,log:@whell,user-1
## POLKIT[org.debian.pcsc-lite.access_pcsc]="yes:@users"
## POLKIT[org.debian.pcsc-lite.access_card]="yes:@users"
exec_polkit(){
## Настрока polkit правил
SYSTEMD_POLKIT_CONF_FILE="${ROOTFS}"/etc/systemd/system/polkit.service.d/ubconfig-59-polkit.conf
rm -f ${SYSTEMD_POLKIT_CONF_FILE}
rm -f "${ROOTFS}"/etc/polkit-1/rules.d/ublinux-*
rm -f "${ROOTFS}"/etc/polkit-1/rules.d/100-ubconfig-*
local SYSTEMD_POLKIT_CONF_MAKE=
if [[ -n ${POLKIT[@]} ]]; then
for RULES in "${!POLKIT[@]}"; do
RULES_GROUP=
RULES_FILE="${ROOTFS}/etc/polkit-1/rules.d/ublinux-$(sed 's/\([[:alnum:]]*.[[:alnum:]]*.[[:alnum:]]*\)\..*/\1/' <<< ${RULES}).rules"
RULES_RESULT=$(cut -d: -f1 <<< ${POLKIT[${RULES}]})
for GROUP in $(grep ":" <<< ${POLKIT[${RULES}]} | cut -d: -f2 | tr ',' '\n'); do
RULES_GROUP+="&& subject.isInGroup(\"${GROUP}\") "
done
cat >> ${RULES_FILE} <<EOF
local IN_RULES_RESULT= IN_RULES_USERGROUP= IN_RULES_ACTIVE= IN_RULES_LOCAL=
local OUT_RULES_IF= OUT_RULES_LOG= OUT_RULES_RESULT=
local ALLOW_RULES_RESULT=
OUT_RULES_FILE="${ROOTFS}/etc/polkit-1/rules.d/100-ubconfig-$(sed -E -e 's/([^\.]*)\.([^\.]*)\.([^\.]+)\..*/\1-\2-\3/' -e 's/\./-/g' <<< ${RULES}).rules"
: ${OUT_RULES_FILE:+${OUT_RULES_FILE//-./.}}
IFS=: read -r IN_RULES_RESULT IN_RULES_USERGROUP IN_RULES_ACTIVE IN_RULES_LOCAL <<< "${POLKIT[${RULES}]}"
# Проверка на верность заданных значений
[[ -n ${IN_RULES_RESULT} ]] && while IFS= read -ru3 SELECT_RULES_RESULT; do
[[ ${SELECT_RULES_RESULT,,} == @(yes|no|auth_self|auth_self_keep|auth_admin|auth_admin_keep|null|log) ]] && ALLOW_RULES_RESULT=yes
done 3<<< ${IN_RULES_RESULT//@(,|;)/$'\n'}
# Если нет разрешённого RULES_RESULT, то следующий параметр
[[ -n ${ALLOW_RULES_RESULT} ]] || continue
[[ -n ${IN_RULES_ACTIVE} && ${IN_RULES_ACTIVE,,} != @(yes|true|enable) ]] && continue
[[ -n ${IN_RULES_LOCAL} && ${IN_RULES_LOCAL,,} != @(yes|true|enable) ]] && continue
#
[[ ${IN_RULES_ACTIVE,,} == @(yes|true|enable) ]] && OUT_RULES_IF+=$'\n'$'\t'"&& subject.active == true"
[[ ${IN_RULES_LOCAL,,} == @(yes|true|enable) ]] && OUT_RULES_IF+=$'\n'$'\t'"&& subject.local == true"
[[ -n ${IN_RULES_USERGROUP} ]] && while IFS= read -ru3 SELECT_USERGROUP; do
if [[ ${SELECT_USERGROUP:0:1} == "@" ]]; then
OUT_RULES_IF+=$'\n'$'\t'"&& subject.isInGroup(\"${SELECT_USERGROUP:1}\")"
else
OUT_RULES_IF+=$'\n'$'\t'"&& subject.user == \"${SELECT_USERGROUP}\""
fi
done 3<<< ${IN_RULES_USERGROUP//@(,|;)/$'\n'}
[[ -n ${IN_RULES_RESULT} ]] && while IFS= read -ru3 SELECT_RULES_RESULT; do
[[ ${SELECT_RULES_RESULT,,} == "log" ]] && OUT_RULES_LOG+=$'\n'$'\t''polkit.log("action=" + action);'$'\n'$'\t''polkit.log("subject=" + subject);' && SYSTEMD_POLKIT_CONF_MAKE=yes
[[ ${SELECT_RULES_RESULT,,} == @(yes|no|auth_self|auth_self_keep|auth_admin|auth_admin_keep|null) ]] && OUT_RULES_RESULT+=$'\n'$'\t'"return polkit.Result.${SELECT_RULES_RESULT^^};"
done 3<<< ${IN_RULES_RESULT//@(,|;)/$'\n'}
cat >> ${OUT_RULES_FILE} <<EOF
polkit.addRule(function(action, subject) {
if (action.id.indexOf("${RULES}") == 0
&& subject.active == true
&& subject.local == true
${RULES_GROUP}
if (action.id.indexOf("${RULES}") == 0${OUT_RULES_IF}
)
{
return polkit.Result.${RULES_RESULT^^};
{ ${OUT_RULES_LOG}${OUT_RULES_RESULT}
}
});
EOF
done
#touch ${ROOTFS}/etc/polkit-1/rules.d
ISSYSTEMD=$(readlink -fq ${ROOTFS}/usr/bin/init | grep "lib/systemd/systemd$")
if [[ -n ${ISSYSTEMD} && -n ${SYSTEMD_POLKIT_CONF_MAKE} ]]; then
install -Dm644 /dev/stdin ${SYSTEMD_POLKIT_CONF_FILE} <<-EOF
[Service]
ExecStart=
ExecStart=-/usr/lib/polkit-1/polkitd
EOF
# Перезапуск сервиса polkit.service
# Если выполнение в initrd, то не выполнять
[[ -z ${ROOTFS} ]] && systemctl daemon-reload && systemctl restart polkit.service
fi
fi
}
################
##### MAIN #####
################
exec_polkit_ubinstall $@
exec_polkit $@
# Если файл подключен как р е с у р с с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
FUNCTION=
while [[ $# -gt 0 ]]; do
#[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1//\'/}'"; }
# Что-бы передавать пустые параметры как аргументы, нужно для соблюдения очередности и кол-ва, отключил [[ -z ${1} ]] ||
declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1//\'/}'"
shift
done
eval ${FUNCTION#*; }
fi