diff --git a/ublinux/functions b/ublinux/functions index 8029b39..2e3beac 100755 --- a/ublinux/functions +++ b/ublinux/functions @@ -497,13 +497,17 @@ user_del(){ && VOL_FILEP_SHELL=${BASH_REMATCH[7]} sed "/^${SELECT_USERNAME}:/d" -i "${FILE_PASSWD}" sed "/^${SELECT_USERNAME}:/d" -i "${FILE_SHADOW}" - # Если имеется группа с таким же именем пользователя и она является основной группой указанного пользователя и в ней нет других пользователей, то удаляем группу - local VOL_FILEG_PLAINPASSWORD= VOL_FILEG_GID= VOL_FILEG_MEMBERS= + # Если имеется группа с таким же именем пользователя и она является основной группой указанного пользователя и в ней нет других пользователей + local VOL_FILEG_PLAINPASSWORD= VOL_FILEG_GID= VOL_FILEG_MEMBERS= OTHER_USERNAME= [[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \ && VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[2]} \ && VOL_FILEG_GID=${BASH_REMATCH[3]} \ && VOL_FILEG_MEMBERS=${BASH_REMATCH[4]} - if [[ ${VOL_FILEP_GID} == ${VOL_FILEG_GID} && -z ${VOL_FILEG_MEMBERS} ]]; then + # и она не является основной у других пользователей + [[ -n ${VOL_FILEP_GID} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):([^$'\n']*):"${VOL_FILEP_GID}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \ + && OTHER_USERNAME=${BASH_REMATCH[2]} + # то удаляем группу + if [[ ${VOL_FILEP_GID} == ${VOL_FILEG_GID} && -z ${VOL_FILEG_MEMBERS} && -z ${OTHER_USERNAME} ]]; then sed /^${SELECT_USERNAME}:/d -i "${FILE_GROUP}" sed /^${SELECT_USERNAME}:/d -i "${FILE_GSHADOW}" fi @@ -1603,7 +1607,7 @@ ubconfig_exec_system(){ esac ;; "[${SYSCONF}/network]"|"[network]") - case "${NAME_VAR}" in + case "${NAME_VAR}" in DOMAIN) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd exec_domain "${COMMAND_MODE_VAR}" ;; DOMAIN\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;; REALM_SSSD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;; @@ -1616,7 +1620,7 @@ ubconfig_exec_system(){ esac ;; "[${SYSCONF}/security]"|"[security]") - case "${NAME_VAR}" in + case "${NAME_VAR}" in OPENSSL_ENGINE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/56-openssl-engine ;; ACCESS_DENIED_VTX11) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/57-access-denied-vtx11 ;; ACCESS_ALLOWED_LOGIN) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/58-access-login exec_access_allowed_login ;; diff --git a/ublinux/rc.halt.pre/86-save-rootcopy b/ublinux/rc.halt.pre/86-save-rootcopy index 9043fb8..3cf1d2c 100755 --- a/ublinux/rc.halt.pre/86-save-rootcopy +++ b/ublinux/rc.halt.pre/86-save-rootcopy @@ -37,6 +37,7 @@ exec_save_rootcopy(){ fi cd ${ROOTFS}/${PATH_CHANGES} [[ -n ${SAVE_ROOTCOPY_CHANGES} ]] && while read -r SELECT_CHANGES; do + # Специально добавлено --exclude={'','',''} [[ -e ${SELECT_CHANGES#/*} ]] \ && eval rsync --quiet --update --archive --recursive --acls --xattrs --relative --delete --delete-excluded --exclude={''${ROOTCOPY_EXCLUDE}} ${SELECT_CHANGES#/*} ${PATH_ROOTCOPY} # --dry-run --verbose --quiet diff --git a/ublinux/rc.pamsession.d/02-journald-notify b/ublinux/rc.pamsession.d/02-journald-notify new file mode 100755 index 0000000..f95b5de --- /dev/null +++ b/ublinux/rc.pamsession.d/02-journald-notify @@ -0,0 +1,206 @@ +#!/usr/bin/env bash +# +# Author: Dmitry Razumov +# Copyright (c) 2021-2025 UBLinux +# +# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching +shopt -s extglob + +ENABLED= +[[ ${ENABLED} == yes ]] || exit 0 + +SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null +SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null + +SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null +SOURCE=${SYSCONF}/logging; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null + + +################################################################################ +## JOURNALD_NOTIFY[u:NetworkManager:warning]=@ +## JOURNALD_NOTIFY[u:NetworkManager:warning]=ip@conflict +## JOURNALD_NOTIFY[u:*Network*:warning]=@ +## -u --unit +## echo "$(printf 'journalctl'; printf ' -u %s' $(journalctl -q -F UNIT | grep -E '^Network'))" +## journalctl -u NetworkManager -p warning -b -o export -n1 -f + +################################################################################ +## JOURNALD_NOTIFY[uu:NetworkManager:warning]=@ +## --user-unit + +################################################################################ +## JOURNALD_NOTIFY[t:*Network*:warning]=@ +## -t, --identifier=SYSLOG_IDENTIFIER +## echo "$(printf 'journalctl'; printf ' -t %s' $(journalctl -q -F SYSLOG_IDENTIFIER | grep -E '^gnome'))" +## journalctl -t gnome-system-monitor.desktop -t gnome-shell -t gnome-keyring-daemon -t gnome-session-binary -t gnome-session + +################################################################################ +## JOURNALD_NOTIFY[f:daemon:warning]=@ +## --facility + +declare -A JOURNALD_NOTIFY + +## Вывод уведомления на рабочий стол полученных от лога journald +## JOURNALD_NOTIFY[|||]= +## # Тип фильтра +## u # Фильтр по юнитам системным, применимо на юнимами regexp +## uu # Фильтр (user-unit) по юнитам пользователя, применимо на юнимами regexp +## t # Фильтр (identifier) по идентификатору SYSLOG_IDENTIFIER, применимо regexp +## f # Фильтр (facility) по типу объекта SYSLOG, строгое значение +## # Значения для типа фильтра +## # Если =u то применимо REGEXP выражение +## # Если =uu то применимо REGEXP выражение +## # Если =t то применимо REGEXP выражение +## # Если =f то применимы варианты : +## # 0: kern (Kernel messages) +## # 1: user (User-level messages) +## # 2: mail (Mail system) +## # 3: daemon (System daemons) +## # 4: auth (Security/authorization messages) +## # 5: syslog (Messages generated internally by syslogd) +## # 6: lpr (Line printer subsystem (archaic subsystem)) +## # 7: news (Network news subsystem (archaic subsystem)) +## # 8: uucp (UUCP subsystem (archaic subsystem)) +## # 9: - (Clock daemon systemd-timesyncd) +## # 10: authpriv (Security/authorization messages) +## # 11: ftp (FTP daemon) +## # 12: - (NTP subsystem) +## # 13: - (Log audit) +## # 14: - (Log alert) +## # 15: cron (Scheduling daemon) +## # 16: local0 (Local use 0 (local0)) +## # 17: local1 (Local use 1 (local1)) +## # 18: local2 (Local use 2 (local2)) +## # 19: local3 (Local use 3 (local3)) +## # 20: local4 (Local use 4 (local4)) +## # 21: local5 (Local use 5 (local5)) +## # 22: local6 (Local use 6 (local6)) +## # 23: local7 (Local use 7 (local7)) +## # Фильтр по приоритету 0:emerg 1:alert 2:crit 3:err 4:warning 5:notice 6:info 7:debug +## # 0: emergency (неработоспособность системы) +## # 1: alerts (предупреждения, требующие немедленного вмешательства) +## # 2: critical (критическое состояние) +## # 3: errors (ошибки) +## # 4: warning (предупреждения) +## # 5: notice (уведомления) +## # 6: info (информационные сообщения) +## # 7: debug (отладочные сообщения) +## # Произвольные дополнительные опции фильтра пользователя для journald +## # Шаблон обработки сообщения +## ip@conflict # Вырезать сообщение о конфликте IP адреса +## # Произвольное выражение вырезки для команды sed + +## JOURNALD_NOTIFY[u:NetworkManager:warning]=@ +## JOURNALD_NOTIFY[u:NetworkManager:warning]=ip@conflict +## JOURNALD_NOTIFY[u:*Network*:warning]=@ +## JOURNALD_NOTIFY[uu:NetworkManager:warning]=@ +## JOURNALD_NOTIFY[t:*Network*:warning]=@ +## JOURNALD_NOTIFY[f:daemon:warning]=@ + +#JOURNALD_NOTIFY[u:NetworkManager:warning]=@ + +exec_01_journald_notify(){ + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" + [[ $(declare -p JOURNALD_NOTIFY 2>/dev/null) =~ ^"declare -A" ]] || declare -gA JOURNALD_NOTIFY + local PARAM="$@" + if [[ -n ${PARAM} ]]; then + local APPDESKTOP_PLACEONDESKTOP_INIT= + declare -A APPDESKTOP_PLACEONDESKTOP_INIT=() + [[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}" + fi + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#APPDESKTOP_PLACEONDESKTOP_INIT[@]} -ne 0 ]]; then + local ID_GROUPS= SELECT_USER_HOME= + for SELECT_USERS_GROUPS in "${!APPDESKTOP_PLACEONDESKTOP_INIT[@]}"; do + while IFS= read -r READ_USER_GROUP; do + if [[ -n ${SELECT_USER} ]]; then + # Применить для PAM пользователя + [[ -z ${ID_GROUPS} ]] && ID_GROUPS=$(id --name --groups ${SELECT_USER}) + if [[ ${READ_USER_GROUP} == "0" ]] || [[ ${READ_USER_GROUP} == ${SELECT_USER} ]] || [[ ${READ_USER_GROUP} =~ ^'@' && ${ID_GROUPS} =~ (^| )${READ_USER_GROUP//@/}( |$) ]]; then + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + [[ -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init ]] && continue + copy_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && touch ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + fi + elif [[ ${READ_USER_GROUP} == "0" ]]; then + # Применить для всех пользователей + for SELECT_USER in $(getent passwd | cut -d: -f1 | xargs); do + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + [[ -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init ]] && continue + copy_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && touch ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER_HOME= + done + SELECT_USER= + elif [[ ! ${READ_USER_GROUP} =~ ^'@' ]] && getent passwd "${READ_USER_GROUP}" &>/dev/null; then + # Применить для выбанного пользователь + SELECT_USER=${READ_USER_GROUP} + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + [[ -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init ]] && continue + copy_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && touch ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER=; SELECT_USER_HOME= + elif [[ ${READ_USER_GROUP} =~ ^'@' ]] && getent group "${READ_USER_GROUP//@/}" &>/dev/null; then + # Применить для выбраной группа + for SELECT_USER in $(getent group "${READ_USER_GROUP//@/}" | cut -d: -f4 | tr , ' '); do + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + [[ -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init ]] && continue + copy_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && touch ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER_HOME= + done + SELECT_USER= + fi + done <<< ${SELECT_USERS_GROUPS//@(,|;)/$'\n'} + done + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then + if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' && ${BASH_REMATCH[1]} == @("*"|"**"|"/"|"//") ]]; then + PARAM_VALUE="${PARAM#*=}" + APPDESKTOP_PLACEONDESKTOP_INIT+="${PARAM_VALUE// /,}" + fi + local ID_GROUPS= SELECT_USER_HOME= + for SELECT_USERS_GROUPS in "${!APPDESKTOP_PLACEONDESKTOP_INIT[@]}"; do + while IFS= read -r READ_USER_GROUP; do + if [[ ${READ_USER_GROUP} == "0" ]]; then + # Применить для всех пользователей + for SELECT_USER in $(getent passwd | cut -d: -f1 | xargs); do + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + remove_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && rm -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER_HOME= + done + SELECT_USER= + elif [[ ! ${READ_USER_GROUP} =~ ^'@' ]] && getent passwd "${READ_USER_GROUP}" &>/dev/null; then + # Применить для выбанного пользователь + SELECT_USER=${READ_USER_GROUP} + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + remove_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && rm -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER=; SELECT_USER_HOME= + elif [[ ${READ_USER_GROUP} =~ ^'@' ]] && getent group "${READ_USER_GROUP//@/}" &>/dev/null; then + # Применить для выбраной группа + for SELECT_USER in $(getent group "${READ_USER_GROUP//@/}" | cut -d: -f4 | tr , ' '); do + SELECT_USER_HOME_INIT=$(getent passwd ${SELECT_USER} | cut -d: -f6) + remove_desktop "${SELECT_USER}" "${APPDESKTOP_PLACEONDESKTOP_INIT[${SELECT_USERS_GROUPS}]}" && rm -f ${SELECT_USER_HOME_INIT}/.config/.place_on_desktop_init + SELECT_USER_HOME= + done + SELECT_USER= + fi + done <<< ${SELECT_USERS_GROUPS//@(,|;)/$'\n'} + done + fi +} + +################ +##### MAIN ##### +################ + + # Если файл подключен как ресурс с функциями, то выйти + 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}'"; } + shift + done + eval ${FUNCTION#*; } + fi + true diff --git a/ublinux/rc.preinit/10-accounts b/ublinux/rc.preinit/10-accounts index 1213949..5ea5bad 100755 --- a/ublinux/rc.preinit/10-accounts +++ b/ublinux/rc.preinit/10-accounts @@ -608,6 +608,24 @@ exec_06_useradd(){ #${CMD_CHROOT} /usr/bin/ubconfig --target system --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]" [[ -f ${FILE_ROOT_USERS} ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${FILE_ROOT_USERS}" [[ -f "${SYSCONF}/users" ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${SYSCONF}/users" + # Если в конфигурации имеется другой пользователь с такой-же основной группой как у удоляемого пользователя, то добавить группу в конфигурацию + local GET_GROUPADD=$(get_conf_groupadd_from_system "${SELECT_USERNAME}") + if [[ -n ${GET_GROUPADD} ]]; then + # Получить GID группы + local SELECT_MEMBERS= SELECT_GID= SELECT_OPTIONAL= SELECT_ADMINISTRATORS= SELECT_PASSWORD= + IFS=: read -r SELECT_MEMBERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GET_GROUPADD##*=}" + # Повторно считаем локальную конфигурацию и всех пользователей + SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null + while IFS= read -ru3 SELECT_USERNAME_LOOP; do + local SELECT_GECOS= SELECT_UID= SELECT_GROUP= SELECT_EXTRAGROUPS= SELECT_OPTIONAL= SELECT_PASSWORD= NULL= + IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME_LOOP}]}" + if [[ ${SELECT_USERNAME} != ${SELECT_USERNAME_LOOP} && ${SELECT_GROUP} == @("${SELECT_GID}"|"${SELECT_USERNAME}") ]] ; then + eval ${CMD_CHROOT} /usr/bin/ubconfig --quiet --noexecute remove [users] ${GET_GROUPADD} + eval ${CMD_CHROOT} /usr/bin/ubconfig --quiet --noexecute set [users] ${GET_GROUPADD} + break + fi + done 3< <(printf "%s\n" "${!USERADD[@]}") + fi } if [[ ${SELECT_USERNAME} == @("*"|"**"|"/"|"//") ]]; then [[ -f ${SYSCONF}/users ]] && while IFS= read -ru3 LINE_USERADD; do diff --git a/ublinux/templates/ublinux-data.ini b/ublinux/templates/ublinux-data.ini index f8c0d37..087c2da 100644 --- a/ublinux/templates/ublinux-data.ini +++ b/ublinux/templates/ublinux-data.ini @@ -1669,9 +1669,11 @@ VERSION= #FAILSAFEATI=fbdev ## Перечень программ, которые следует запускать через OPTIRUN для ноутбуков с Nvidia optimus -#OPTIRUN= +## Имена файлов /usr/share/applications/*.desktop +#OPTIRUN=steam ## Перечень программ, которые следует запускать через PRIMUSRUN для ноутбуков с Nvidia optimus +## Имена файлов /usr/share/applications/*.desktop #PRIMUSRUN=steam ## При наличии 2х видеокарт (ноутбуки с картами AMD/ATI) по умолчанию используется