|
|
#!/usr/bin/bash
|
|
|
#
|
|
|
# Author: Dmitry Razumov <asmeron@ublinux.com>
|
|
|
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
|
|
|
#
|
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
#
|
|
|
# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
|
|
|
shopt -s extglob
|
|
|
|
|
|
ENABLED=yes
|
|
|
[[ ${ENABLED} == "yes" ]] || { return 0 2>/dev/null && return 0 || exit 0; }
|
|
|
DEBUGMODE=no
|
|
|
|
|
|
unset ROOTFS; [[ -d /usr/lib/ublinux ]] || ROOTFS=.
|
|
|
SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
|
|
|
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
|
|
|
debug_mode "$0" "$@"
|
|
|
|
|
|
SYSCONF="${ROOTFS}${SYSCONF}"
|
|
|
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
|
|
|
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
|
|
|
|
|
|
## Синхронизация пользователей системы /etc/passwd и их параметры /etc/shadow с глобальной конфигурацией
|
|
|
## USERADD_SYNC='boot,shutdown,shutdown@all,shutdown@users,shutdown@systems,shutdown@<min>-<max>,shutdown@<uid>'
|
|
|
## boot # При загрузке системы принудительно применить глобальную конфигурацию на пользователя
|
|
|
## shutdown # Аналогичен shutdown@users + shutdown@systems
|
|
|
## shutdown@all # При завершении работы системы синхронизировать всех пользователей в системе с глобальной конфигурацией
|
|
|
## shutdown@users # При завершении работы системы синхронизировать пользователей 1000<=UID<=6000 в системе с глобальной конфигурацией
|
|
|
## shutdown@systems # При завершении работы системы синхронизировать системных пользователей 500<=UID<=999 в системе с глобальной конфигурацией
|
|
|
## shutdown@<min>-<max> # При завершении работы системы синхронизировать диапазон UID пользователей в системе с глобальной конфигурацией
|
|
|
## shutdown@<uid> # При завершении работы системы синхронизировать UID пользователя в системе с глобальной конфигурацией
|
|
|
## USERADD_SYNC=boot,shutdown
|
|
|
##
|
|
|
## USERADD_SYNC[<user_name>]='boot,shutdown'
|
|
|
## <user_name> # Имя пользователя, необязательное поле. Если не указано, то применяется для всех пользователей
|
|
|
## boot # При загрузке системы принудительно применить глобальную конфигурацию на пользователя
|
|
|
## shutdown # При завершении работы системы синхронизировать указанного пользователя в системе с глобальной конфигурацией
|
|
|
## USERADD_SYNC[superadmin]=boot,shutdown
|
|
|
exec_01_useradd_sync(){
|
|
|
remove_ubconfig(){
|
|
|
# Удалить пользователей из глобальной конфигурации
|
|
|
local PARAM="$1"
|
|
|
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
|
|
|
if [[ ${PARAM} == '@all' ]]; then
|
|
|
# Удалить всех пользователей из глобальной конфигурации
|
|
|
${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] USERADD[*] USERSHADOW[*]
|
|
|
elif [[ ${PARAM} == '@users' ]]; then
|
|
|
# Удалить пользователей 1000<=UID<=6000 из глобальной конфигурации
|
|
|
# Все пользователи кроме системных
|
|
|
local UID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
|
|
|
local UID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
|
|
|
local STR_REMOVE_USERS=()
|
|
|
[[ -n ${!USERADD[@]} ]] && while IFS= read -u3 SELECT_USER; do
|
|
|
IFS=':' read -u4 SELECT_GECOS SELECT_UID NULL 4<<< ${USERADD[${SELECT_USER}]}
|
|
|
if [[ ${SELECT_UID} == @(""|"x"|"X") ]] || [[ ${SELECT_UID} -ge ${UID_MIN} && ${SELECT_UID} -le ${UID_MAX} ]]; then
|
|
|
STR_REMOVE_USERS+=("USERADD[${SELECT_USER}]")
|
|
|
STR_REMOVE_USERS+=("USERSHADOW[${SELECT_USER}]")
|
|
|
fi
|
|
|
done 3< <(printf "%s\n" "${!USERADD[@]}")
|
|
|
[[ ${#STR_REMOVE_USERS[@]} -ge 0 ]] && ${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] "${STR_REMOVE_USERS[@]}"
|
|
|
elif [[ ${PARAM} == '@systems' ]]; then
|
|
|
# Удалить пользователей 500<=UID<=999 из глобальной конфигурации
|
|
|
# Пользователи системные
|
|
|
local UID_MIN_SYS=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
|
|
|
local UID_MAX_SYS=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
|
|
|
local STR_REMOVE_USERS=()
|
|
|
[[ -n ${!USERADD[@]} ]] && while IFS= read -u3 SELECT_USER; do
|
|
|
IFS=':' read -u4 SELECT_GECOS SELECT_UID NULL 4<<< ${USERADD[${SELECT_USER}]}
|
|
|
if [[ ${SELECT_UID} != @(""|"x"|"X") && ${SELECT_UID} -ge ${UID_MIN_SYS} && ${SELECT_UID} -le ${UID_MAX_SYS} ]]; then
|
|
|
STR_REMOVE_USERS+=("USERADD[${SELECT_USER}]")
|
|
|
STR_REMOVE_USERS+=("USERSHADOW[${SELECT_USER}]")
|
|
|
fi
|
|
|
done 3< <(printf "%s\n" "${!USERADD[@]}")
|
|
|
[[ ${#STR_REMOVE_USERS[@]} -ge 0 ]] && ${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] "${STR_REMOVE_USERS[@]}"
|
|
|
elif [[ ${PARAM} =~ ^([[:digit:]]+)'-'*([[:digit:]]*)$ ]]; then
|
|
|
# Удалить пользователей X<=UID<=Y из глобальной конфигурации
|
|
|
local UID_MIN=${BASH_REMATCH[1]}
|
|
|
local UID_MAX=${BASH_REMATCH[2]}
|
|
|
local STR_REMOVE_USERS=()
|
|
|
[[ -n ${UID_MAX} ]] || UID_MAX=${UID_MIN}
|
|
|
[[ -n ${!USERADD[@]} ]] && while IFS= read -u3 SELECT_USER; do
|
|
|
IFS=':' read -u4 SELECT_GECOS SELECT_UID NULL 4<<< ${USERADD[${SELECT_USER}]}
|
|
|
if [[ ${SELECT_UID} != @(""|"x"|"X") && ${SELECT_UID} -ge ${UID_MIN} && ${SELECT_UID} -le ${UID_MAX} ]]; then
|
|
|
STR_REMOVE_USERS+=("USERADD[${SELECT_USER}]")
|
|
|
STR_REMOVE_USERS+=("USERSHADOW[${SELECT_USER}]")
|
|
|
fi
|
|
|
done 3< <(printf "%s\n" "${!USERADD[@]}")
|
|
|
[[ ${#STR_REMOVE_USERS[@]} -ge 0 ]] && ${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] "${STR_REMOVE_USERS[@]}"
|
|
|
else
|
|
|
# Входящий параметр - имя пользователя
|
|
|
${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] USERADD[${PARAM}] USERSHADOW[${PARAM}]
|
|
|
fi
|
|
|
}
|
|
|
set_ubconfig(){
|
|
|
local PARAM="$1"
|
|
|
local GET_USERADD=$(get_conf_useradd_from_system "${PARAM}")
|
|
|
if [[ ${GET_USERADD} != "" ]]; then
|
|
|
eval ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] ${GET_USERADD}
|
|
|
local GET_USERSHADOW=$(get_conf_usershadow_from_system ${PARAM})
|
|
|
# TODO: Если задан диапазон пользователей, пример 0-999, то GET_USERSHADOW будет содержать всех пользователей в этом диапазоте
|
|
|
# А нужно выбрать только пользователей которые содержатся в GET_USERADD
|
|
|
if [[ ${GET_USERSHADOW} != "" ]]; then
|
|
|
eval ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] ${GET_USERSHADOW}
|
|
|
fi
|
|
|
fi
|
|
|
}
|
|
|
set_ubconfig_global_allsync(){
|
|
|
# Если в системной конфигурации заданы USERADD_SYNC= то установить в глобальной конфигурации
|
|
|
[[ -n ${USERADD_SYNC} ]] && ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] USERADD_SYNC="${USERADD_SYNC}"
|
|
|
}
|
|
|
set_ubconfig_global_selectsync(){
|
|
|
local PARAM="$1"
|
|
|
# Если в системной конфигурации заданы USERADD_SYNC[${PARAM}]= то установить в глобальной конфигурации
|
|
|
[[ -n ${PARAM} && "$(declare -p USERADD_SYNC 2>/dev/null)" == "declare -A"* && -n ${USERADD_SYNC[${PARAM}]} ]] \
|
|
|
&& ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] USERADD_SYNC["${PARAM}"]="${USERADD_SYNC[${PARAM}]}"
|
|
|
}
|
|
|
|
|
|
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
|
|
|
[[ -n ${COMMAND} ]] || COMMAND="set="
|
|
|
local PARAM="$@"
|
|
|
if [[ -n ${PARAM} ]]; then
|
|
|
# Параметр вида USERADD_SYNC=
|
|
|
if [[ ${PARAM} =~ ^[^'[']+'=' ]]; then
|
|
|
USERADD_SYNC=
|
|
|
else
|
|
|
# Параметр вида USERADD_SYNC[*]=
|
|
|
local USERADD_SYNC=
|
|
|
declare -A USERADD_SYNC=()
|
|
|
fi
|
|
|
[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
|
|
|
fi
|
|
|
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
|
|
|
# Обработка всех пользователей параметр USERADD_SYNC=...
|
|
|
while IFS= read -u3 SELECT_USERADD_SYNC; do
|
|
|
if [[ ${SELECT_USERADD_SYNC} == 'shutdown@all' ]]; then
|
|
|
remove_ubconfig "@all"
|
|
|
set_ubconfig "@all"
|
|
|
elif [[ ${SELECT_USERADD_SYNC} == 'shutdown@users' ]]; then
|
|
|
remove_ubconfig "@users"
|
|
|
set_ubconfig "@users"
|
|
|
elif [[ ${SELECT_USERADD_SYNC} == 'shutdown@systems' ]]; then
|
|
|
remove_ubconfig "@systems"
|
|
|
set_ubconfig "@systems"
|
|
|
elif [[ ${SELECT_USERADD_SYNC} == 'shutdown' ]]; then
|
|
|
remove_ubconfig "@users"
|
|
|
remove_ubconfig "@systems"
|
|
|
set_ubconfig
|
|
|
elif [[ ${SELECT_USERADD_SYNC} =~ ^'shutdown@'(([[:digit:]]+)'-'*([[:digit:]]*))$ ]]; then
|
|
|
local LIST_USERS="${BASH_REMATCH[1]}"
|
|
|
remove_ubconfig "${LIST_USERS}"
|
|
|
set_ubconfig "${LIST_USERS}"
|
|
|
fi
|
|
|
set_ubconfig_global_allsync
|
|
|
done 3<<< "${USERADD_SYNC//@(,|;)/$'\n'}"
|
|
|
# Обработка выбранних пользователей параметр USERADD_SYNC[...]=...
|
|
|
if [[ "$(declare -p USERADD_SYNC 2>/dev/null)" == "declare -A"* ]]; then
|
|
|
[[ -n ${!USERADD_SYNC[@]} ]] && while IFS= read -u3 SELECT_USER; do
|
|
|
# В массиве 0 запись игнорируем, т.к. это параметр не ассоциативного массива
|
|
|
if [[ ${SELECT_USER} != 0 && ${USERADD_SYNC[${SELECT_USER}]} =~ 'shutdown' ]]; then
|
|
|
# Если все пользователи уже были синхронизироаны, то пропустить
|
|
|
if [[ ! ${USERADD_SYNC} =~ (^|,)('shutdown@all'|'shutdown')(,|$) ]]; then
|
|
|
remove_ubconfig "${SELECT_USER}"
|
|
|
set_ubconfig "${SELECT_USER}"
|
|
|
fi
|
|
|
set_ubconfig_global_selectsync "${SELECT_USER}"
|
|
|
fi
|
|
|
done 3< <(printf "%s\n" "${!USERADD_SYNC[@]}")
|
|
|
fi
|
|
|
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
|
|
|
true
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
## Синхронизация группы системы /etc/groups и их параметры /etc/gshadow с глобальной конфигурацией
|
|
|
## GROUPADD_SYNC='shutdown,shutdown@all,shutdown@users,shutdown@systems,shutdown@<min>-<max>,shutdown@<gid>'
|
|
|
## shutdown # Аналогичен shutdown@users + shutdown@systems
|
|
|
## shutdown@all # При завершении работы системы синхронизировать все группы в системе с глобальной конфигурацией
|
|
|
## shutdown@groups # При завершении работы системы синхронизировать группы 1000<=GID<=6000 в системе с глобальной конфигурацией
|
|
|
## shutdown@systems # При завершении работы системы синхронизировать системные группы 500<=GID<=999 в системе с глобальной конфигурацией
|
|
|
## shutdown@<min>-<max> # При завершении работы системы синхронизировать диапазон GID групп в системе с глобальной конфигурацией
|
|
|
## shutdown@<gid> # При завершении работы системы синхронизировать GID группы в системе с глобальной конфигурацией
|
|
|
## GROUPADD_SYNC=shutdown
|
|
|
##
|
|
|
## GROUPADD_SYNC[group_name]='shutdown'
|
|
|
## group_name # Имя группы, необязательное поле. Если не указано, то применяется для всех групп
|
|
|
## shutdown # При завершении работы системы синхронизировать указанную группу в системе с глобальной конфигурацией
|
|
|
## GROUPADD_SYNC[users]='shutdown'
|
|
|
exec_02_groupadd_sync(){
|
|
|
set_ubconfig(){
|
|
|
local PARAM="$1"
|
|
|
local GET_GROUPADD=$(get_conf_groupadd_from_system "${PARAM}")
|
|
|
if [[ ${GET_GROUPADD} != "" ]]; then
|
|
|
eval ${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] ${GET_GROUPADD}
|
|
|
eval ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] ${GET_GROUPADD}
|
|
|
fi
|
|
|
}
|
|
|
set_ubconfig_global_allsync(){
|
|
|
# Если в системной конфигурации заданы GROUPADD_SYNC= то установить в глобальной конфигурации
|
|
|
[[ -n ${GROUPADD_SYNC} ]] && ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] GROUPADD_SYNC="${GROUPADD_SYNC}"
|
|
|
}
|
|
|
set_ubconfig_global_selectsync(){
|
|
|
local PARAM="$1"
|
|
|
# Если в системной конфигурации заданы GROUPADD_SYNC[${PARAM}]= то установить в глобальной конфигурации
|
|
|
[[ -n ${PARAM} && "$(declare -p GROUPADD_SYNC 2>/dev/null)" == "declare -A"* && -n ${GROUPADD_SYNC[${PARAM}]} ]] \
|
|
|
&& ${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] GROUPADD_SYNC["${PARAM}"]="${GROUPADD_SYNC[${PARAM}]}"
|
|
|
}
|
|
|
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
|
|
|
[[ -n ${COMMAND} ]] || COMMAND="set="
|
|
|
local PARAM="$@"
|
|
|
if [[ -n ${PARAM} ]]; then
|
|
|
# Параметр вида GROUPADD_SYNC=
|
|
|
if [[ ${PARAM} =~ ^[^'[']+'=' ]]; then
|
|
|
GROUPADD_SYNC=
|
|
|
else
|
|
|
# Параметр вида GROUPADD_SYNC[*]=
|
|
|
local GROUPADD_SYNC=
|
|
|
declare -A GROUPADD_SYNC=()
|
|
|
fi
|
|
|
[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
|
|
|
fi
|
|
|
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
|
|
|
# Обработка всех групп, параметр GROUPADD_SYNC=...
|
|
|
# Если синхронизируем группы по шаблону, то удалим все группы из глобальной конфигурации
|
|
|
if [[ ${USERADD_SYNC} =~ 'shutdown' ]]; then
|
|
|
${ROOTFS}/usr/bin/ubconfig --quiet --target global remove [users] GROUPADD[*]
|
|
|
fi
|
|
|
while IFS= read -u3 SELECT_GROUPADD_SYNC; do
|
|
|
if [[ ${SELECT_GROUPADD_SYNC} == 'shutdown@all' ]]; then
|
|
|
set_ubconfig "@all"
|
|
|
elif [[ ${SELECT_GROUPADD_SYNC} == 'shutdown@groups' ]]; then
|
|
|
set_ubconfig "@groups"
|
|
|
elif [[ ${SELECT_GROUPADD_SYNC} == 'shutdown@systems' ]]; then
|
|
|
set_ubconfig "@systems"
|
|
|
elif [[ ${SELECT_GROUPADD_SYNC} =~ ^'shutdown@'(([[:digit:]]+)'-'*([[:digit:]]*))$ ]]; then
|
|
|
set_ubconfig "${BASH_REMATCH[1]}"
|
|
|
elif [[ ${SELECT_GROUPADD_SYNC} == 'shutdown' ]]; then
|
|
|
set_ubconfig
|
|
|
fi
|
|
|
set_ubconfig_global_allsync
|
|
|
done 3<<< "${GROUPADD_SYNC//@(,|;)/$'\n'}"
|
|
|
# Обработка выбранних групп параметр GROUPADD_SYNC[...]=...
|
|
|
if [[ "$(declare -p GROUPADD_SYNC 2>/dev/null)" == "declare -A"* ]]; then
|
|
|
while IFS= read -u3 SELECT_GROUP; do
|
|
|
# В массиве 0 запись игнорируем, т.к. это параметр не ассоциативного массива
|
|
|
if [[ ${SELECT_GROUP} != 0 && ${GROUPADD_SYNC[${SELECT_GROUP}]} =~ 'shutdown' ]]; then
|
|
|
# Если все пользователи уже были синхронизироаны, то пропустить
|
|
|
if [[ ! ${GROUPADD_SYNC} =~ (^|,)('shutdown@all'|'shutdown')(,|$) ]]; then
|
|
|
set_ubconfig "${SELECT_GROUP}"
|
|
|
fi
|
|
|
set_ubconfig_global_selectsync "${SELECT_GROUP}"
|
|
|
fi
|
|
|
done 3< <(printf "%s\n" "${!GROUPADD_SYNC[@]}")
|
|
|
fi
|
|
|
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
|
|
|
true
|
|
|
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
|