You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ublinux-init/ublinux/rc.preinit/10-accounts

846 lines
59 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
#
# Initial script for UBLinux
# This script are launching before starting init from initrd script
# Current dir allways must be set to root (/)
# All system path must be relative, except initrd dirs
ENABLED=
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
CMD_CHROOT= ; [[ -d /usr/lib/ublinux ]] || { [[ -d /sysroot ]] && ROOTFS="/sysroot" || ROOTFS="."; CMD_CHROOT="chroot ${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
SOURCE=${SYSCONF}/system; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
FILE_ROOT_USERS="${SYSCONF}/.users_credential"
SOURCE=${FILE_ROOT_USERS}; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
FILE_PASSWD="${ROOTFS}/etc/passwd"
FILE_SHADOW="${ROOTFS}/etc/shadow"
FILE_GROUP="${ROOTFS}/etc/group"
FILE_GSHADOW="${ROOTFS}/etc/gshadow"
PATH_HOME="/home"
NAME_REGEX="^[a-z_][-a-z0-9_]*\$"
# Задать пароль пользователю
# $1 # Имя пользователя
# $2 # Зашифрованный пароля, если не указан, то пароль '!*' запрет авторизации
set_passwd(){
USER_NAME="${1}"
USER_PASS="${2}"
[[ ${USER_NAME} != "" ]] || return 1
[[ ${USER_PASS} != "" ]] || USER_PASS='!*'
if [[ -x ${ROOTFS}/usr/bin/chpasswd ]]; then
echo "${USER_NAME}:${USER_PASS}" | ${CMD_CHROOT} /usr/bin/chpasswd --encrypted
else
ESC_USER_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${USER_PASS}")
EPOCH_DAY=$(( $(date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day
USER_FROM_SHADOW=$(grep "^${USER_NAME}:" "${FILE_SHADOW}")
if [[ -z ${USER_FROM_SHADOW} ]]; then
echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}"
elif [[ ! ${USER_FROM_SHADOW} =~ ^"${USER_NAME}:${USER_PASS}:" ]]; then
sed -E "s/^${USER_NAME}:[^:]+:[0-9]+:/${USER_NAME}:${ESC_USER_PASS}:${EPOCH_DAY}:/" -i "${FILE_SHADOW}"
sed -E "s/${USER_NAME}:[!]*:/${USER_NAME}:\!\*:/" -i "${FILE_SHADOW}"
#sed /^${USER_NAME}:/d -i "${FILE_SHADOW}"
#echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}"
fi
fi
}
# Задать пароль группе
# $1 # Имя группы
# $2 # Зашифрованный пароля, если не указан, то пароль '!*' запрет авторизации
#set_gpasswd(){
# GROUP_NAME="${1}"
# GROUP_PASS="${2}"
# [[ ${GROUP_NAME} != "" ]] || return 1
# [[ ${GROUP_PASS} != "" ]] || GROUP_PASS="!*"
# if [[ -x ${ROOTFS}/usr/bin/chgpasswd ]]; then
# echo "${GROUP_NAME}:${GROUP_PASS}" | ${CMD_CHROOT} /usr/bin/chgpasswd --encrypted
# else
# ESC_GROUP_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${GROUP_PASS}")
# GROUP_FROM_SHADOW=$(grep "^${GROUP_NAME}:" "${FILE_GSHADOW}")
# if [[ -z ${GROUP_FROM_SHADOW} ]]; then
# echo "${GROUP_NAME}:${GROUP_PASS}::" >> "${FILE_GSHADOW}"
# elif [[ ! ${GROUP_FROM_SHADOW} =~ ^"${GROUP_NAME}:${GROUP_PASS}:" ]]; then
# sed -E "s/^${GROUP_NAME}:[^:]*:/${GROUP_NAME}:${ESC_GROUP_PASS}:/" -i "${FILE_GSHADOW}"
# fi
# fi
#}
# Создать домашний каталог и копировать /etc/skel в домашний каталог пользователя
# $1 # Имя пользователя
# $2 # Основная группа пользователя, если не указана, то соответствует имени пользователя
# $3 # Если указано, то принудительно копировать /etc/skel в домашний каталог пользователя
create_home(){
local SELECT_USERNAME="${1}"
local SELECT_GROUP="${2}"
local SELECT_FORCESKEL="${3}"
local ARG_RECURSIVE=
[[ ${SELECT_GROUP} == "" || ${SELECT_GROUP} == "-" ]] && SELECT_GROUP=${SELECT_USERNAME}
[[ ${SELECT_USERNAME} != "" ]] || return 1
if [[ -d "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" ]]; then
${CMD_CHROOT} /usr/bin/chmod -f u+rw,g-rwx,o-rwx "${PATH_HOME}/${SELECT_USERNAME}"
[[ -z ${SELECT_FORCESKEL} ]] || cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}"
else
install -dm700 "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}"
cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}"
fi
#rsync -rlpt --ignore-existing etc/skel/ "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}"
[[ -n ${ROOTFS} ]] && ARG_RECURSIVE="-R" || ARG_RECURSIVE=
${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} "${SELECT_USERNAME}" ${PATH_HOME}/"${SELECT_USERNAME}"
${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} :"${SELECT_GROUP}" "${PATH_HOME}/${SELECT_USERNAME}"
}
# Задаём пароль root пользователю
exec_00_defaultrootpasswd(){
#echo "exec_00_defaultrootpasswd"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${DEFAULTROOTPASSWD} && ! ${DEFAULTROOTPASSWD,,} == @(no|none|disable) ]]; then
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр DEFAULTROOTPASSWD из '/etc/ublinux/users
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
if [[ -f ${FILE_ROOT_USERS} ]]; then
sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}"
echo "DEFAULTROOTPASSWD='${DEFAULTROOTPASSWD}'" >> ${FILE_ROOT_USERS}
fi
[[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users"
fi
[[ -n ${DEFAULTROOTPASSWD} ]] && DEFAULTROOTPASSWD=$(return_hash_password hash ${HASHPASSWD} ${DEFAULTROOTPASSWD})
set_passwd root "${DEFAULTROOTPASSWD}"
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
[[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}"
[[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users"
fi
fi
}
# Задаём пароль по умолчанию пользователю
exec_00_defaultpasswd(){
#echo "exec_00_defaultpasswd"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${DEFAULTPASSWD} ]]; then
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр DEFAULTROOTPASSWD из '/etc/ublinux/users
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
if [[ -f ${FILE_ROOT_USERS} ]]; then
sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}"
echo "DEFAULTPASSWD='${DEFAULTPASSWD}'" >> ${FILE_ROOT_USERS}
fi
[[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users"
fi
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
[[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}"
[[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users"
fi
fi
}
# Создаём группы из ${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS} c ID из /usr/share/ublinux-sysusers/*.sysusers
exec_01_add_groups(){
#echo "exec_01_add_groups"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
local GROUPADD_GROUPS SELECT_GROUP ARG_FINDGROUP_ID FINDGROUP_ID
DATA_FILE_GROUP=$(cat ${FILE_GROUP})
# Загрузить файлы которые совпадают в каталогах /usr/lib/sysusers.d/ и /usr/share/ublinux-sysusers/. И загрузить которые уникальные в /usr/lib/sysusers.d/
DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers)
if [[ -n ${PARAM} ]]; then
GROUPADD_GROUPS=${PARAM}
else
GROUPADD_GROUPS="${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${GROUPADD_GROUPS} ]]; then
GROUPADD_GROUPS=${GROUPADD_GROUPS//;/,}; GROUPADD_GROUPS="${GROUPADD_GROUPS//,,/,}"
[[ ${GROUPADD_GROUPS:0:1} == ',' ]] && GROUPADD_GROUPS=${GROUPADD_GROUPS:1}
[[ ${GROUPADD_GROUPS} =~ ','$ ]] && GROUPADD_GROUPS=${GROUPADD_GROUPS%*,}
[[ -n ${GROUPADD_GROUPS} ]] && while IFS= read -u3 SELECT_GROUP; do
local ARG_FINDGROUP_ID=
# Найти группу по имени
[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID=
# Найти группу по GID
#[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]}
if [[ ${FINDGROUP_ID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*:${FINDGROUP_ID}:[^$'\n']*($'\n'|$)+ ]]; then
# Группа найдена, имя и id совпадают, пропускаем добавление
continue
elif [[ ${FINDGROUP_ID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*($'\n'|$)+ ]]; then
# Группа найдена, имя и id не совпадают, удаляем группу
echo "WARNING: the group '${SELECT_GROUP}' has an id different from the template /usr/share/ublinux-sysusers/*.sysusers and the id will be changed to '${SELECT_GROUP}:${FINDGROUP_ID}'"
${CMD_CHROOT} /usr/bin/groupdel -f ${SELECT_GROUP}
fi
[[ ${FINDGROUP_ID} == @(""|"-") ]] || ARG_FINDGROUP_ID="--gid ${FINDGROUP_ID}"
if [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]]; then
${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_FINDGROUP_ID} ${SELECT_GROUP}
else
>&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name"
fi
done 3<<< "${GROUPADD_GROUPS//,/$'\n'}"
fi
}
# Создаем пользователей из ${NEEDEDUSERS} и добавляем в группы
# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 Для команды set=|set+=|set++= параметр со значением, пример:
# Для команды set-=|set--=|remove параметр только с именем, пример:
# null Если отсутствует $@, то применяем из системной конфигурации
exec_02_neededusers(){
#echo "exec_02_neededusers"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
local SELECT_USERNAME SELECT_UID SELECT_PASSWORD SELECT_GECOS NULL ADDGROUPS
local ARG_DEFAULTGROUP ARG_SELECT_UID ARG_SELECT_GECOS
if [[ -n ${PARAM} ]]; then
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
# Если по умолчанию нет ни одного пользователя, то создаём администратора
#[[ -z ${NEEDEDUSERS} ]] && NEEDEDUSERS="${DEFAULTUSER}:${ADMUID}:${DEFAULTPASSWD}:Administrator"
[[ -z $(cmdline_value users) ]] || NEEDEDUSERS=$(cmdline_value users)
[[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes
if [[ -n ${NEEDEDUSERS} ]]; then
while IFS= read -ru3 SELECT_USER; do
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр NEEDEDUSERS из '/etc/ublinux/users
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
if [[ -f ${FILE_ROOT_USERS} ]]; then
sed "/NEEDEDUSERS=/d" -i "${FILE_ROOT_USERS}"
echo "NEEDEDUSERS='${SELECT_USER}'" >> ${FILE_ROOT_USERS}
fi
[[ -f "${SYSCONF}/users" ]] && sed "/NEEDEDUSERS=/d" -i "${SYSCONF}/users"
fi
IFS=: read -r SELECT_USERNAME SELECT_UID SELECT_PASSWORD SELECT_GECOS NULL <<< "${SELECT_USER}"
[[ ${SELECT_PASSWORD} == "x" ]] && SELECT_PASSWORD="${DEFAULTPASSWD}"
ADDGROUPS="${USERGROUPS}"
[[ ${SELECT_UID} == ${ADMUID} && ${ADDADM} == "yes" ]] && ADDGROUPS="${USERGROUPS},${ADMGROUPS}"
# Если указана обязательная синхронизация при каждом запуске, то пользователя удалить и создать нового
if [[ ${USERADD_SYNC} =~ 'boot' || ${USERADD_SYNC[${SELECT_USERNAME}]} =~ 'boot' ]]; then
if [[ -x ${ROOTFS}/usr/bin/userdel ]]; then
${CMD_CHROOT} /usr/bin/userdel -f ${SELECT_USERNAME}
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
# busybox deluser
${CMD_CHROOT} /usr/bin/busybox deluser ${SELECT_USERNAME}
fi
fi
# Создаём пользователя
if ! grep -q ^"${SELECT_USERNAME}": ${FILE_PASSWD} 2>/dev/null; then
[[ -n ${SELECT_UID} ]] && ARG_SELECT_UID="-u ${SELECT_UID}" || ARG_SELECT_UID=
if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-c '${SELECT_GECOS}'" || ARG_SELECT_GECOS=
[[ -n ${DEFAULTGROUP} ]] && ARG_DEFAULTGROUP="-G ${DEFAULTGROUP}" || ARG_DEFAULTGROUP=
eval ${CMD_CHROOT} /usr/bin/useradd -M ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME} #>/dev/null 2>&1
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
# busybox adduser
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g '${SELECT_GECOS}'" || ARG_SELECT_GECOS=
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}"
eval ${CMD_CHROOT} /usr/bin/busybox adduser -D -H ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME} #>/dev/null 2>&1
fi
# Добавляем пользователя в группу
USER_GROUPS="${ADDGROUPS//;/,}"
${CMD_CHROOT} /usr/bin/usermod -a -G ${USER_GROUPS%*,} ${SELECT_USERNAME} #>/dev/null 2>&1
# Задаём пароль пользователю
#[[ -n ${SELECT_PASSWORD} ]] && return_hash_password "${SELECT_PASSWORD}" && [[ -n ${HASH_PASSWORD_NEW} ]] && SELECT_PASSWORD="${HASH_PASSWORD_NEW}"
[[ -n ${SELECT_PASSWORD} ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})
set_passwd "${SELECT_USERNAME}" "${SELECT_PASSWORD}"
fi
# Создаём домашний каталог принудительно и копируем /etc/skel
if [[ ! -d ${ROOTFS}${PATH_HOME}/"${SELECT_USERNAME}" \
|| ${UPDATEHOME[${SELECT_USERNAME}],,} == @(yes|y|enable) \
|| ${UPDATEHOME,,} == @(yes|y|enable) ]]; then
create_home "${SELECT_USERNAME}" - force
fi
done 3< <(tr ",;" "\n" <<< "${NEEDEDUSERS}")
fi
}
# Добавить пользователя системы в /etc/passwd. Если пользователь существует, то без изменений
# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 Для команды set=|set+=|set++= параметр со значением, пример: USERADD[user-1]='Пользователь-1:x:x:vboxusers,libvirt:-s /usr/bin/bash:%%plain_password'
# Для команды set-=|set--=|remove параметр только с именем, пример: USERADD[superadmin]
# null Если отсутствует $@, то применяем из системной конфигурации USERADD[*]
##
## USERADD=no|none|disable # Отключить управление прользователями конфигурации
## USERADD[user_name]='gecos:uid:user_group:extra_groups:optional:password|x'
## user_name # Имя пользователя, обязательное поле
## gecos # Поле GECOS, с подробным описанием пользователя, можно локализованное, не обязательное
## uid # UID пользователя, если необходимо автоматически рассчитывать, то оставить пустым или 'x'
## user_group # Основная группа пользователя, номер или имя, если выбрано пусто или 'x', то 'user_group=user_name'
## extra_groups # Дополнительные группы пользователя. Дополнительные к USERGROUPS
## # Если группа отсутствует или 'x', то 'extra_groups=users'. Если группа не существует, то будет создана. Перечисление через запятую.
## optional # Дополнительные параметры, например: '--shell /usr/bin/bash --create-home --no-create-home --no-user-group --non-unique'
## --home-dir <ДОМ_КАТ> # Домашний каталог новой учётной записи
## -s, --shell /usr/bin/bash # Регистрационная оболочка новой учётной записи
## -r, --system # Создавать системную группу
## -M, --no-create-home # Не создавать домашний каталог пользователя
## -N, --no-user-group # Не создавать группу с тем же именем что и у пользователя
## -o, --non-unique # Разрешить создание пользователей с повторяющимися (не уникальными) UID, использовать только совместно с параметром <uid>
## --badnames # Не проверять имя на несоответствие правилам использования символов
## password|x # Хеш пароля пользователя, если пусто или 'x', то 'password=${DEFAULTPASSWD}',
## # Если первые символы (%%), то пароль хранится в нешифрованном виде
## # Если первые символы (!*), то аутентификация запрещена
## # Если первый символ (*) или (!), то аутентификация по паролю заблокирована. Но другие методы входа,
## # такие как аутентификация на основе ключей или переключение на пользователя, по-прежнему разрешены
## USERADD[superadmin]='Администратор:1000:x:x:x:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
## USERADD[user-1]=x
## USERADD[user-1]='Пользователь-1:x:x:vboxusers,libvirt:-s /usr/bin/bash:%%plain_password'
##
## Синхронизация пользователей системы /etc/passwd с глобальной конфигурацией
## USERADD_SYNC[user_name]='boot,shutdown'
## user_name # Имя пользователя, необязательное поле. Если не указано, то применяется для всех пользователей
## boot # При загрузке системы принудительно применить глобальную конфигурацию на пользователя
## shutdown # При завершении работы системы синхронизировать указанных пользователей в системе с глобальной конфигурацией
exec_03_useradd(){
#echo "exec_03_useradd"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
[[ ${USERADD} != @(none|no|disable) ]] || return 0
[[ -n ${USERADD_SYNC} ]] || declare -gA USERADD_SYNC
[[ -n ${UPDATEHOME} ]] || declare -gA UPDATEHOME
[[ -n ${USERADD} ]] || declare -gA USERADD
declare -gA USERSHADOW
local SELECT_USERNAME SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_OPTIONAL SELECT_PASSWORD NULL
local ARG_SELECT_UID ARG_SELECT_GROUP ARG_SELECT_GECOS ARG_SELECT_PASSWORD ARG_SELECT_OPTIONAL
local ARG_GROUPADD_GID ARG_GROUPADD_GROUPNAME
local STATUS=
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local USERADD=
declare -A USERADD
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
# Если в GRUB указан параметр useradd, то создать пользователя
while IFS=':' read -u3 SELECT_USERNAME SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_PASSWORD NULL; do
[[ ${SELECT_USERNAME} != "" ]] && USERADD[${SELECT_USERNAME}]=":${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUP}:x:${SELECT_PASSWORD}"
done 3< <(tr ';' '\n' <<< $(cmdline_value useradd))
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
[[ ${#USERADD[@]} == 0 ]] && USERADD[${DEFAULTUSER}]="Administrator:${ADMUID}:x:x:x:${DEFAULTPASSWD}"
[[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes
useradd_local(){
DATA_FILE_PASSWD=$(cat ${FILE_PASSWD})
DATA_FILE_GROUP=$(cat ${FILE_GROUP})
local SELECT_USERNAME=$1
# Вызов как исполнителя после ubconfig
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить хеш пароля параметра USERADD[.*] в /etc/ublinux/users
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
if [[ -f ${FILE_ROOT_USERS} ]]; then
sed "/USERADD\[${SELECT_USERNAME}\]=/d" -i "${FILE_ROOT_USERS}"
echo "USERADD[${SELECT_USERNAME}]='${USERADD[${SELECT_USERNAME}]}'" >> ${FILE_ROOT_USERS}
fi
[[ -f "${SYSCONF}/users" ]] && sed -E "s/(USERADD\[${SELECT_USERNAME}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users"
fi
# Проверяем существует ли пользователь в системе
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}": ]] && IS_USERNAME_PASSWD=yes || IS_USERNAME_PASSWD=
# Проверяем отсутствие пользователя в системе или параметр принудительного обновления
if [[ ${IS_USERNAME_PASSWD} == "" || ${USERADD_SYNC} =~ 'boot' || ${USERADD_SYNC[${SELECT_USERNAME}]} =~ 'boot' ]]; then
IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}"
#echo -e "\n===> exec_03_useradd: ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}"
[[ ${SELECT_GECOS,,} == "x" ]] && SELECT_GECOS=
[[ ${SELECT_OPTIONAL,,} == "x" ]] && SELECT_OPTIONAL=
[[ ${SELECT_OPTIONAL} =~ ("--home-dir "|"-d ")([^' ']*)(' '|$) ]] && HOME_DIR_SELECT_USERNAME="${BASH_REMATCH[2]}" || HOME_DIR_SELECT_USERNAME="${PATH_HOME}/${SELECT_USERNAME}"
[[ ${SELECT_UID,,} == "x" || ${SELECT_UID} =~ ^[^0-9]+$ ]] && SELECT_UID=
# Если существует домашний каталог пользователя, то UID берём от каталога
if [[ -z ${SELECT_UID} && -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]]; then
SELECT_UID=$(stat -c %u "${ROOTFS}${HOME_DIR_SELECT_USERNAME}")
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+[^:]*:[^:]*:"${SELECT_UID}": ]] && SELECT_UID=
fi
[[ ${SELECT_GROUP,,} == "x" ]] && SELECT_GROUP=
# Если существует домашний каталог пользователя, то GID берём от каталога
if [[ -z ${SELECT_GROUP} && -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]]; then
SELECT_GROUP=$(stat -c %g "${ROOTFS}${HOME_DIR_SELECT_USERNAME}")
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+[^:]*:[^:]*:[^:]*:"${SELECT_GROUP}": ]] && SELECT_GROUP=
fi
[[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD="${DEFAULTPASSWD}"
[[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD="$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})"
[[ ${SELECT_EXTRAGROUPS,,} == "x" ]] && SELECT_EXTRAGROUPS=
# Если в дополнительных группа присутствует группа по имени пользователя, то удалить её из списка
SELECT_EXTRAGROUPS=${SELECT_EXTRAGROUPS//${SELECT_USERNAME}/}
# Создадать группы из параметра SELECT_EXTRAGROUPS
local SELECT_EXTRAGROUPS_TO_EXEC_01=
local SELECT_EXTRAGROUPS_TO_EXEC_05=
[[ -n ${SELECT_EXTRAGROUPS} ]] && while IFS= read -u4 ITEM_SELECT_EXTRAGROUP; do
[[ ${ITEM_SELECT_EXTRAGROUP} != "" ]] || continue
if [[ -n ${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]} ]]; then
#exec_05_groupadd "GROUPADD[${ITEM_SELECT_EXTRAGROUP}]=${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]}"
SELECT_EXTRAGROUPS_TO_EXEC_05+="exec_05_groupadd GROUPADD[${ITEM_SELECT_EXTRAGROUP}]=${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]}; "
else
SELECT_EXTRAGROUPS_TO_EXEC_01+="${ITEM_SELECT_EXTRAGROUP},"
fi
done 4<<< "${SELECT_EXTRAGROUPS//,/$'\n'}"
#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && echo "exec_01_add_groups ${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}"
# [[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && exec_01_add_groups "${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}"
#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && echo "eval ${SELECT_EXTRAGROUPS_TO_EXEC_05}"
# [[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && eval "${SELECT_EXTRAGROUPS_TO_EXEC_05}"
SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS},${USERGROUPS}"
[[ ${SELECT_UID} == ${ADMUID} && ${ADDADM} == "yes" ]] && SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS},${ADMGROUPS}"
SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//;/,}"; SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//,,/,}"
[[ ${SELECT_EXTRAGROUPS:0:1} == "," ]] && SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS:1}"
#echo "===> ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}"
#echo "===> ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}"
ARG_SELECT_UID=; ARG_SELECT_GROUP=; ARG_SELECT_GECOS=; ARG_SELECT_PASSWORD=; ARG_SELECT_OPTIONAL=; STATUS=; IS_USERNAME_PASSWD=
[[ -n ${SELECT_UID} && ${SELECT_UID} != 0 ]] && ARG_SELECT_UID="--uid ${SELECT_UID}" || ARG_SELECT_UID=
# Если указана основная группа, но она не создана, то создать
local ARG_GROUPADD_GID= ARG_GROUPADD_GROUPNAME=
if [[ -n ${SELECT_GROUP} && -n ${GROUPADD[${SELECT_GROUP}]} ]]; then
# Если группа указана и присутствует в списке групп GROUPADD[.]
#echo 0:${SELECT_GROUP}
#echo "exec_05_groupadd GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}"
exec_05_groupadd "GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}"
elif [[ -n ${SELECT_GROUP} && ! ${DATA_FILE_GROUP} =~ ($'\n'|^)+(${SELECT_GROUP}:|[^$'\n']*:${SELECT_GROUP}:) ]]; then
# Если группа указана и не найдена в файле shadow
# Группа имет цифровой GID и номер GID=UID
if [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} == ${SELECT_UID} ]]; then
#echo 1:${SELECT_GROUP}
ARG_GROUPADD_GID="${SELECT_GROUP}"
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
elif [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} != ${SELECT_UID} ]]; then
#echo 2:${SELECT_GROUP}
# Группа имет цифровой GID и номер GID!=UID
ARG_GROUPADD_GID="${SELECT_GROUP}"
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
elif [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]]; then
#echo 3:${SELECT_GROUP}
# Группа имет буквенный GID
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
else
#echo 4:${SELECT_GROUP}
# Если группа не имеет цифры и буквы
SELECT_GROUP=
fi
if [[ -n ${ARG_GROUPADD_GROUPNAME} ]]; then
[[ ${ARG_GROUPADD_GROUPNAME} =~ ${NAME_REGEX} ]] || ARG_GROUPADD_GROUPNAME="_${ARG_GROUPADD_GROUPNAME}"
#echo "exec_05_groupadd GROUPADD[${ARG_GROUPADD_GROUPNAME}]=x:${ARG_GROUPADD_GID}"
exec_05_groupadd "GROUPADD[${ARG_GROUPADD_GROUPNAME}]=x:${ARG_GROUPADD_GID}"
fi
fi
if [[ ${IS_USERNAME_PASSWD} == "" ]]; then
# Создаём пользователя
if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="--comment '${SELECT_GECOS}'" || ARG_SELECT_GECOS=
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="--gid ${SELECT_GROUP}" || ARG_SELECT_GROUP=
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD=
ARG_SELECT_OPTIONAL="${SELECT_OPTIONAL}"
[[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_UID} ]] || { ARG_SELECT_OPTIONAL=${ARG_SELECT_OPTIONAL//-o/}; ARG_SELECT_OPTIONAL=${ARG_SELECT_OPTIONAL//--non-unique/}; }
[[ ${SELECT_OPTIONAL} =~ ("-M"|"--no-create-home") ]] || { [[ -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]] || ARG_SELECT_OPTIONAL+=" --create-home"; }
[[ ${SELECT_OPTIONAL} =~ ("-N"|"--no-user-group") ]] || { [[ -z ${SELECT_GROUP} ]] && ARG_SELECT_OPTIONAL+=" --user-group"; }
eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME}' failed, try attempt 2"; \
eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 2 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${SELECT_USERNAME}' failed, try attempt 3"; \
eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 3 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${SELECT_USERNAME}' failed, try attempt 4"; \
eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 4 to use 'useradd ${ARG_SELECT_UID} ${SELECT_USERNAME}' failed, try attempt 5"; \
eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 5 to use 'useradd ${SELECT_USERNAME}' failed, try attempt 6"; \
eval ${CMD_CHROOT} /usr/bin/useradd ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { >&2 echo "ERROR: Attempt 6 to use 'useradd ${SELECT_USERNAME}' failed, exit"; return 1; }
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
# busybox adduser
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g '${SELECT_GECOS}'" || ARG_SELECT_GECOS=
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}"
[[ ${SELECT_OPTIONAL} =~ ("-M"|"--no-create-home") ]] && ARG_SELECT_OPTIONAL+=" -H"
eval ${CMD_CHROOT} /usr/bin/busybox adduser -D ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME} #>/dev/null 2>&1
# Задаём пароль пользователю
set_passwd "${SELECT_USERNAME}" "${SELECT_PASSWORD}"
fi
else
# Изменяем пользователя
if [[ -x ${ROOTFS}/usr/bin/usermod ]]; then
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="--comment '${SELECT_GECOS}'" || ARG_SELECT_GECOS=
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="--gid ${SELECT_GROUP}" || ARG_SELECT_GROUP=
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD=
ARG_SELECT_OPTIONAL=
[[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_UID} ]] && ARG_SELECT_OPTIONAL+=" --non-unique"
[[ ${SELECT_OPTIONAL} =~ ("--shell "|"-s ")([^' ']*)(' '|$) ]] && ARG_SELECT_OPTIONAL+=" --shell ${BASH_REMATCH[2]}"
[[ ${SELECT_OPTIONAL} =~ ("--home-dir "|"-d ")([^' ']*)(' '|$) ]] && ARG_SELECT_OPTIONAL+=" --home ${BASH_REMATCH[2]} --move-home"
eval ${CMD_CHROOT} /usr/bin/usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?
[[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME}' failed, try attempt 2"; \
eval ${CMD_CHROOT} /usr/bin/usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; }
[[ ${STATUS} -eq 0 ]] || { >&2 echo "ERROR: Attempt 2 to use 'usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}' failed, exit"; return 1; }
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
true
fi
fi
# Создаём дополнитеьные группы
#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && echo "exec_01_add_groups ${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}"
[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && exec_01_add_groups "${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}"
#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && echo "eval ${SELECT_EXTRAGROUPS_TO_EXEC_05}"
[[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && eval "${SELECT_EXTRAGROUPS_TO_EXEC_05}"
# Добавляем пользователя в основную группу
if [[ -x ${ROOTFS}/usr/bin/usermod ]]; then
# Добавляем пользователя в дополнительные группы
${CMD_CHROOT} /usr/bin/usermod -a -G ${SELECT_EXTRAGROUPS%*,} ${SELECT_USERNAME} #>/dev/null 2>&1
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
true
fi
# Задаём параметры пароля пользователю /etc/shadow из USERSHADOW[user]. Только если запущено отдельно с параметром
[[ -n ${PARAM} && -n ${USERSHADOW[${SELECT_USERNAME}]} ]] && exec_04_usershadow "USERSHADOW[${SELECT_USERNAME}]=${USERSHADOW[${SELECT_USERNAME}]}"
# Проверим права на домашний каталог пользователя совпадают с указанным польователем, если нет, то переназначим
if [[ -d ${ROOTFS}${HOME_DIR_SELECT_USERNAME} ]]; then
GET_UID_GID_HOME=$(${CMD_CHROOT} /usr/bin/stat -c "%U:%G" ${HOME_DIR_SELECT_USERNAME})
GET_UID_GID_SELECT="$(${CMD_CHROOT} /usr/bin/id -u ${SELECT_USERNAME} 2>/dev/null):$(${CMD_CHROOT} /usr/bin/id -g ${SELECT_GROUP:-${SELECT_USERNAME}} 2>/dev/null)"
if [[ ${GET_UID_GID_HOME} != ${GET_UID_GID_SELECT} ]]; then
eval ${CMD_CHROOT} /usr/bin/chown -f -h "${SELECT_USERNAME}:" \
$(${CMD_CHROOT} find ${HOME_DIR_SELECT_USERNAME} -maxdepth 1 -printf '"%p"\n') \
$(cat ${ROOTFS}/etc/xdg/user-dirs.defaults 2>/dev/null | grep -v "^\s*#" | sed -E "s|.*=(.*)|${HOME_DIR_SELECT_USERNAME}/\1|") \
$(cat ${ROOTFS}${HOME_DIR_SELECT_USERNAME}/.config/user-dirs.dirs 2>/dev/null | grep -v "^\s*#"| sed -E "s|.*HOME/(.*)|${HOME_DIR_SELECT_USERNAME}/\"\1|")
ARG_RECURSIVE="-hRP"
eval ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} "${SELECT_USERNAME}:" \
$(${CMD_CHROOT} find ${HOME_DIR_SELECT_USERNAME} -maxdepth 1 -name ".*" -printf '"%p"\n')
fi
fi
else
echo "INFO: The user '${SELECT_USERNAME}' exists in the system, the settings are not applied. To force the settings, enable the '[users] USERADD_SYNC[${SELECT_USERNAME}]=boot' option"
fi
# Создаём домашний каталог принудительно и копируем /etc/skel
if [[ ${UPDATEHOME,,} == @(yes|y|enable) \
|| ${UPDATEHOME[${SELECT_USERNAME}],,} == @(yes|y|enable) ]]; then
create_home "${SELECT_USERNAME}" "${SELECT_GROUP}" force
fi
}
# Обработать всех пользователей у которых указан UID
local LIST_USERADD_UID= LIST_USERADD_NOUID=
while IFS= read -ru3 SELECT_USERNAME; do
IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}"
if [[ ${SELECT_UID} =~ ^[0-9]+$ ]] ; then
LIST_USERADD_UID+="useradd_local ${SELECT_USERNAME}; "
else
LIST_USERADD_NOUID+="useradd_local ${SELECT_USERNAME}; "
fi
done 3< <(printf "%s\n" "${!USERADD[@]}")
eval "${LIST_USERADD_UID}"
eval "${LIST_USERADD_NOUID}"
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
# Удалим пользователей только тех кто содержиться в файле учетных данных ${FILE_ROOT_USERS}
SELECT_USERNAME=${BASH_REMATCH[1]}
delete_select_username(){
local SELECT_USERNAME=$1
if [[ -n ${SELECT_USERNAME} ]] && ${CMD_CHROOT} /usr/bin/getent passwd ${SELECT_USERNAME} &>/dev/null; then
${CMD_CHROOT} /usr/bin/userdel --force ${SELECT_USERNAME}
fi
[[ -f ${FILE_ROOT_USERS} ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null
${CMD_CHROOT} /usr/bin/ubconfig --target system --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]"
}
if [[ ${SELECT_USERNAME} == @("*"|"**"|"/"|"//") ]]; then
[[ -f ${FILE_ROOT_USERS} ]] && while IFS= read -ru3 LINE_USERADD; do
[[ ${LINE_USERADD} =~ ^.*'['(.*)']' ]] && delete_select_username ${BASH_REMATCH[1]}
done 3< <(grep -E "USERADD\[.*\]" ${FILE_ROOT_USERS} 2>/dev/null)
else
delete_select_username ${SELECT_USERNAME}
fi
fi
fi
# echo -e "\nEND\n"
}
# Параметры пользователя системы /etc/shadow. Если пользователь существует, то без изменений
# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 Для команды set=|set+=|set++= параметр со значением, пример: USERSHADOW[superadmin]=2023-01-01:0:99999:7::2025-01-01
# Для команды set-=|set--=|remove параметр только с именем, пример: USERSHADOW[superadmin]
# null Если отсутствует $@, то применяем из системной конфигурации USERSHADOW[*]
## USERSHADOW[user_name]='lastchanged:minday:maxday:warn:inactive:expire'
## user_name # Имя пользователя, обязательное поле
## lastchanged # Дата последнего изменения пароля. Указывается количество дней, исчисляется с 1 января 1970 года (дата эпохи). Возможно указать дату формата: YYYY-MM-DD
## minday # Минимальное количество дней действия пароля, прежде чем пароль пользователя может быть изменен. По умолчанию 0 означает отсутствие минимального срока действия парол
## maxday # Максимальное количество дней действия пароля после смены пароля пользователя. По умолчанию этот номер установлен на 99999
## warn # Количество дней предупреждения, в течение которого пользователь получает предупреждение о необходимости изменения пароля. По умолчанию 7
## inactive # Количество дней не активности пароля до отключения учетной записи пользователя. По умолчанию пустое
## expire # Дата, когда учетная запись была отключена. Указывается количество дней, исчисляется с 1 января 1970 года (дата эпохи). Возможно указать дату формата: YYYY-MM-DD
## <null> # Если один из параметров не задан, содержит пустое значение, то исходное значение не изменяется
## # Конвертировать кол-во дней от эпохи в понятную дату: date --date=@$(( DDDDD*(60*60*24) )); date --date=@EPOCH
## USERSHADOW[superadmin]=2023-01-01:0:99999:7::2025-01-01
## USERSHADOW[superadmin]=18009:0:120:7:14:
exec_04_usershadow(){
#echo "exec_04_usershadow"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local SELECT_USERNAME SELECT_LASTCHANGED SELECT_MINDAY SELECT_MAXDAY SELECT_WARN SELECT_INACTIVE SELECT_EXPIRE NULL
local ARG_SELECT_LASTCHANGED ARG_SELECT_MINDAY ARG_SELECT_MAXDAY ARG_SELECT_WARN ARG_SELECT_INACTIVE ARG_SELECT_EXPIRE
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local USERSHADOW
declare -A USERSHADOW
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERSHADOW[@]} != 0 ]]; then
while IFS= read -ru3 SELECT_USERNAME; do
# Если пользователь не существует, то пропустить
if [[ -n ${SELECT_USERNAME} ]]; then
if ! ${CMD_CHROOT} /usr/bin/getent shadow ${SELECT_USERNAME} &>/dev/null; then
${CMD_CHROOT} /usr/bin/ubconfig --quiet --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]"
continue
fi
else
continue
fi
IFS=: read -r SELECT_LASTCHANGED SELECT_MINDAY SELECT_MAXDAY SELECT_WARN SELECT_INACTIVE SELECT_EXPIRE NULL <<< "${USERSHADOW[${SELECT_USERNAME}]}"
# Получить из секунд от эпохи текущую дату: date -d @1705841503
# Получить от эпохи количество дней: $(( $(date +%s)/(60*60*24) )). В дне 86400 секунд (60*60*24)
#[[ ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(date --date=${SELECT_LASTCHANGED} +"%s")
#[[ -z ${SELECT_LASTCHANGED_EPOH} && -x /bin/busybox && ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(busybox date --date="${SELECT_LASTCHANGED//./}0000" +"%s")
#[[ -z ${SELECT_LASTCHANGED_EPOH} && -x ${ROOTFS}/usr/bin//date && ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(${ROOTFS}/usr/bin/date --date="${SELECT_LASTCHANGED//./} 0000" +"%s")
#[[ -n ${SELECT_LASTCHANGED_EPOH} ]] && SELECT_LASTCHANGED=$(( ${SELECT_LASTCHANGED_EPOH}/(60*60*24) ))
#[[ ${SELECT_LASTCHANGED,,} == @(""|"x") || ${SELECT_LASTCHANGED} =~ ^[^0-9]*$ || ! ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED=
[[ ${SELECT_LASTCHANGED} =~ (^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || SELECT_LASTCHANGED=
[[ ${SELECT_MINDAY} =~ ^[0-9]*$ ]] || SELECT_MINDAY=
[[ ${SELECT_MAXDAY} =~ ^[0-9]*$ ]] || SELECT_MAXDAY=
[[ ${SELECT_WARN} =~ ^[0-9]*$ ]] || SELECT_WARN=
[[ ${SELECT_INACTIVE} =~ (-1|^[0-9]*$) ]] || SELECT_INACTIVE=
#[[ ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(date --date=${SELECT_EXPIRE} +"%s")
#[[ -z ${SELECT_EXPIRE_EPOH} && -x /bin/busybox && ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(busybox date --date="${SELECT_EXPIRE//./}0000" +"%s")
#[[ -z ${SELECT_EXPIRE_EPOH} && -x ${ROOTFS}/usr/bin/date && ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(${ROOTFS}/usr/bin/date --date="${SELECT_EXPIRE//./} 0000" +"%s")
#[[ -n ${SELECT_EXPIRE_EPOH} ]] && SELECT_EXPIRE=$(( ${SELECT_EXPIRE_EPOH}/(60*60*24) ))
[[ ${SELECT_EXPIRE} =~ (-1|^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || SELECT_EXPIRE=
if [[ -z ${SELECT_LASTCHANGED} && -z ${SELECT_MINDAY} && -z ${SELECT_MAXDAY} && -z ${SELECT_WARN} && -z ${SELECT_INACTIVE} && -z ${SELECT_EXPIRE} ]]; then
SELECT_LASTCHANGED=
SELECT_MINDAY="0"
SELECT_MAXDAY="99999"
SELECT_WARN="7"
SELECT_INACTIVE="-1"
SELECT_EXPIRE="-1"
fi
[[ -n ${SELECT_LASTCHANGED} ]] && ARG_SELECT_LASTCHANGED="--lastday ${SELECT_LASTCHANGED}" || ARG_SELECT_LASTCHANGED=
[[ -n ${SELECT_MINDAY} ]] && ARG_SELECT_MINDAY="--mindays ${SELECT_MINDAY}" || ARG_SELECT_MINDAY=
[[ -n ${SELECT_MAXDAY} ]] && ARG_SELECT_MAXDAY="--maxdays ${SELECT_MAXDAY}" || ARG_SELECT_MAXDAY=
[[ -n ${SELECT_WARN} ]] && ARG_SELECT_WARN="--warndays ${SELECT_WARN}" || ARG_SELECT_WARN=
[[ -n ${SELECT_INACTIVE} ]] && ARG_SELECT_INACTIVE="--inactive ${SELECT_INACTIVE}" || ARG_SELECT_INACTIVE=
[[ -n ${SELECT_EXPIRE} ]] && ARG_SELECT_EXPIRE="--expiredate ${SELECT_EXPIRE}" || ARG_SELECT_EXPIRE=
# Задаём параметры пароля пользователя
if [[ -x ${ROOTFS}/usr/bin/chage ]]; then
${CMD_CHROOT} /usr/bin/chage ${ARG_SELECT_LASTCHANGED} ${ARG_SELECT_MINDAY} ${ARG_SELECT_MAXDAY} ${ARG_SELECT_WARN} ${ARG_SELECT_INACTIVE} ${ARG_SELECT_EXPIRE} "${SELECT_USERNAME}" #>/dev/null 2>&1
fi
done 3< <(printf "%s\n" "${!USERSHADOW[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
SELECT_USERNAME=${BASH_REMATCH[1]}
if [[ -n ${SELECT_USERNAME} ]] && ${CMD_CHROOT} /usr/bin/getent shadow ${SELECT_USERNAME} &>/dev/null; then
if [[ -x ${ROOTFS}/usr/bin/chage ]]; then
${CMD_CHROOT} /usr/bin/chage --mindays 0 --maxdays 99999 --warndays 7 --inactive -1 --expiredate -1 ${SELECT_USERNAME}
fi
fi
fi
fi
}
# Функция добавление/удаление групп в систему. Если группа существует, то изменить под параметры
# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 Для команды set=|set+=|set++= параметр со значением, пример: GROUPADD[g_department_1]=ob.ivanov,rv.smirnov
# Для команды set-=|set--=|remove параметр только с именем, пример: GROUPADD[g_department_1]
# null Если отсутствует $@, то применяем из системной конфигурации GROUPADD[*]
## GROUPADD[group_name]='group_users:gid:optional:password|x'
## group_name # Имя группы
## group_users # Пользователи группы, перечисление через запятую. Может быть пусто.
## gid # GID группы, если необходимо автоматически рассчитывать, то оставить пустым или 'x'
## optional # Дополнительные параметры, например: '--system --non-unique'
## -o, --non-unique # Разрешить создание групп с повторяющимися (не уникальными) GID
## -r, --system # Cоздавать системную группу
## administrators # Администраторы группы которые могут менять пароль группы и добавлять членов
## password|x # Хеш пароля группа, если выбрано 'x' или пусто, то группа без пароля
## GROUPADD[g_department_1]=ob.ivanov,rv.smirnov
## GROUPADD[g_department_2]='ob.ivanov,rv.smirnov:1001:x:superadmin:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
exec_05_groupadd(){
#echo "exec_05_groupadd"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
local SELECT_GROUP SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL
local ARG_SELECT_USERS ARG_SELECT_GID SELECT_OPTIONAL ARG_SELECT_PASSWORD ARG_NON_UNIQUE
local DATA_FILE_PASSWD REAL_SELECT_USERS REAL_SELECT_ADMINISTRATORS
DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers)
if [[ -n ${PARAM} ]]; then
local GROUPADD=
declare -A GROUPADD
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#GROUPADD[@]} != 0 ]]; then
groupadd_local(){
local SELECT_GROUP=$1
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр GROUPADD[.*] из '/etc/ublinux/users
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
if [[ -f ${FILE_ROOT_USERS} ]]; then
sed "/GROUPADD\[${SELECT_GROUP}\]=/d" -i "${FILE_ROOT_USERS}"
echo "GROUPADD[${SELECT_GROUP}]='${GROUPADD[${SELECT_GROUP}]}'" >> ${FILE_ROOT_USERS}
fi
[[ -f "${SYSCONF}/users" ]] && sed -E "s/(GROUPADD\[${SELECT_GROUP}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users"
fi
IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}"
[[ ${SELECT_USERS} == "x" ]] && SELECT_USERS=
[[ ${SELECT_GID,,} == "x" || ${SELECT_GID} =~ ^[^0-9]*$ ]] && SELECT_GID=
#echo "==> exec_05_groupadd: ${SELECT_GROUP}:${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}"
[[ ${SELECT_OPTIONAL} == "x" ]] && SELECT_OPTIONAL=
[[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD=
[[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})
# Поиск по имени в шаблонах пользователей/групп systemd
[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID=
# Поиск по GID в шаблонах пользователей/групп systemd
[[ -z ${FINDGROUP_ID} ]] \
&& [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]} || FINDGROUP_NAME=
[[ -n ${FINDGROUP_ID} ]] && SELECT_GID="${FINDGROUP_ID}"
[[ -n ${FINDGROUP_NAME} ]] && SELECT_GID="${FINDGROUP_NAME}"
DATA_FILE_GROUP=$(cat ${FILE_GROUP})
# Добавляем аргументы к опциям, при условии что такого GID не существует
[[ -n ${SELECT_GID} ]] && [[ ! ${DATA_FILE_GROUP} =~ :${SELECT_GID}: ]] && ARG_SELECT_GID="--gid ${SELECT_GID}" || ARG_SELECT_GID=
#[[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="--users ${SELECT_USERS}" || ARG_SELECT_USERS=
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD=
[[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_GID} ]] || { SELECT_OPTIONAL=${SELECT_OPTIONAL//-o/}; SELECT_OPTIONAL=${SELECT_OPTIONAL//--non-unique/}; }
# Создаём группу, если создана то изменяем под установленные параметры
if [[ ! ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}: ]]; then
if [[ -x ${ROOTFS}/usr/bin/groupadd ]]; then
#${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_USERS} ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
#echo "eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}"
eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
[[ $? -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'groupadd ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${SELECT_GROUP}' failed, try attempt 2"; \
eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; }
[[ $? -eq 0 ]] || { echo "WARNING: Attempt 2 to use 'groupadd ${ARG_SELECT_GID} ${SELECT_GROUP}' failed, try attempt 3"; \
eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; }
[[ $? -eq 0 ]] || { echo "WARNING: Attempt 3 to use 'groupadd ${SELECT_GROUP}' failed, try attempt 4"; \
${CMD_CHROOT} /usr/bin/groupadd --force ${SELECT_GROUP} ; }
[[ $? -eq 0 ]] || { >&2 echo "ERROR: Attempt 4 to use 'groupadd ${SELECT_GROUP}' failed, exit"; return 1; }
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
true
# Задаём пароль группе
# set_gpasswd "${SELECT_GROUP}" "${SELECT_PASSWORD}"
fi
elif [[ -n ${ARG_SELECT_GID} ]]; then
if [[ -x ${ROOTFS}/usr/bin/groupmod ]]; then
# т.к. groupmod принимет не все возможные аргументы совместимы с groupadd, то фильтруем
[[ ${SELECT_OPTIONAL} =~ ("--non-unique"|"-o") ]] && [[ -n ${ARG_SELECT_GID} ]] && ARG_NON_UNIQUE="--non-unique" || ARG_NON_UNIQUE=
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD=
#eval ${CMD_CHROOT} /usr/bin/groupmod --append ${ARG_SELECT_USERS} ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
#echo "eval ${CMD_CHROOT} /usr/bin/groupmod ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}"
eval ${CMD_CHROOT} /usr/bin/groupmod ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
true
# Задаём пароль группе
# set_gpasswd "${SELECT_GROUP}" "${SELECT_PASSWORD}"
fi
fi
DATA_FILE_PASSWD=$(cat ${FILE_PASSWD})
local REAL_SELECT_USERS= REAL_SELECT_ADMINISTRATORS=
# Если пользователь не существуют то убрать из списка SELECT_USERS
while IFS= read -r ITEM_SELECT_USERS; do
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${ITEM_SELECT_USERS}: ]] && REAL_SELECT_USERS+=",${ITEM_SELECT_USERS}"
done <<< ${SELECT_USERS//,/$'\n'}
[[ ${REAL_SELECT_USERS:0:1} == "," ]] && REAL_SELECT_USERS=${REAL_SELECT_USERS:1}
[[ ${REAL_SELECT_USERS} != "" ]] && SELECT_USERS=${REAL_SELECT_USERS} || SELECT_USERS=
# Если пользователь не существуют то убрать из списка REAL_SELECT_ADMINISTRATORS
while IFS= read -r ITEM_SELECT_ADMINISTRATORS; do
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${ITEM_SELECT_ADMINISTRATORS}: ]] && REAL_SELECT_ADMINISTRATORS+=",${ITEM_SELECT_ADMINISTRATORS}"
done <<< ${SELECT_ADMINISTRATORS//,/$'\n'}
[[ ${REAL_SELECT_ADMINISTRATORS:0:1} == "," ]] && REAL_SELECT_ADMINISTRATORS=${REAL_SELECT_ADMINISTRATORS:1}
[[ ${REAL_SELECT_ADMINISTRATORS} != "" ]] && SELECT_ADMINISTRATORS=${REAL_SELECT_ADMINISTRATORS} || SELECT_ADMINISTRATORS=
# Добавляем пользователей в группу, т.к. groupadd не добавил пользователей в /etc/gshadow
if [[ -n ${SELECT_USERS} || -n ${SELECT_ADMINISTRATORS} ]]; then
if [[ -x ${ROOTFS}/usr/bin/gpasswd ]]; then
[[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="-M ${SELECT_USERS}" || ARG_SELECT_USERS=
[[ -n ${SELECT_ADMINISTRATORS} ]] && ARG_SELECT_ADMINISTRATORS="-A ${SELECT_ADMINISTRATORS}" || ARG_SELECT_ADMINISTRATORS=
#echo "${CMD_CHROOT} /usr/bin/gpasswd ${ARG_SELECT_ADMINISTRATORS} ${ARG_SELECT_USERS} ${SELECT_GROUP}"
${CMD_CHROOT} /usr/bin/gpasswd ${ARG_SELECT_ADMINISTRATORS} ${ARG_SELECT_USERS} ${SELECT_GROUP} #>/dev/null 2>&1
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
true
fi
fi
}
local LIST_GROUPADD_GID= LIST_GROUPADD_NOGID=
while IFS= read -ru3 SELECT_GROUP; do
[[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]] || { >&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name"; continue; }
IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}"
if [[ ${SELECT_GID} =~ ^[0-9]+$ ]] ; then
LIST_GROUPADD_GID+="groupadd_local ${SELECT_GROUP}; "
else
LIST_GROUPADD_NOGID+="groupadd_local ${SELECT_GROUP}; "
fi
done 3< <(printf "%s\n" "${!GROUPADD[@]}")
[[ -n ${LIST_GROUPADD_GID} ]] && eval "${LIST_GROUPADD_GID}"
[[ -n ${LIST_GROUPADD_NOGID} ]] && eval "${LIST_GROUPADD_NOGID}"
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
SELECT_GROUP=${BASH_REMATCH[1]}
delete_select_group(){
local SELECT_GROUP=$1
if [[ -n ${SELECT_GROUP} ]] && ${CMD_CHROOT} /usr/bin/getent group ${SELECT_GROUP} &>/dev/null; then
${CMD_CHROOT} /usr/bin/groupdel --force ${SELECT_GROUP}
fi
[[ -f ${FILE_ROOT_USERS} ]] && sed "/GROUPADD\[${SELECT_GROUP}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null
}
if [[ ${SELECT_GROUP} == @("*"|"**"|"/"|"//") ]]; then
[[ -f ${FILE_ROOT_USERS} ]] && while IFS= read -ru3 LINE_GROUPADD; do
[[ ${LINE_GROUPADD} =~ ^.*'['(.*)']' ]] && delete_select_group ${BASH_REMATCH[1]}
done 3< <(grep -E "GROUPADD\[.*\]" ${FILE_ROOT_USERS} 2>/dev/null)
else
delete_select_group ${SELECT_GROUP}
fi
fi
fi
}
# Autodetect firststart
# Если пароли по умолчанию, то firststart
exec_99_firststart(){
#echo "exec_99_firststart"
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local FIRSTSTART=
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
if [[ -n ${ROOTFS} ]]; then
if grep -q "^root:${DEFAULTROOTPASSWD}:" ${ROOTFS}/etc/shadow \
&& grep -q "^$(grep ".*:x:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):${DEFAULTPASSWD}:" ${ROOTFS}/etc/shadow; then
grep -q "^FIRSTSTART$" ${SYSCONF}/config 2>/dev/null || echo "FIRSTSTART=yes" >> ${SYSCONF}/config
fi
elif [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${FIRSTSTART} ]]; then
[[ $(cat ${SYSCONF}/config 2>/dev/null) =~ ($'\n'|^)+'FIRSTSTART=' ]] || echo "FIRSTSTART=yes" >> ${SYSCONF}/config
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
sed "/FIRSTSTART=/d" -i ${SYSCONF}/config
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
#rm -f "${FILE_ROOT_USERS}"
if [[ -z $@ ]]; then
while read -ru3 FUNCTION; do
$"${FUNCTION##* }"
done 3< <(declare -F | grep "declare -f exec_")
else
while [[ $# -gt 0 ]]; do
declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" '${1}'" && shift; }
done
eval ${FUNCTION#*; }
fi