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

750 lines
52 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=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
unset ROOTFS 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"
# Задать пароль пользователю
# $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" || unset 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_02_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_02_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 ${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
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
unset ARG_FINDGROUP_ID
# Найти группу по имени
[[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID=
# Найти группу по GUID
#[[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]}
if [[ ${FINDGROUP_ID} != "" && $(cat ${FILE_GROUP} 2>/dev/null) =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*:${FINDGROUP_ID}:[^$'\n']*($'\n'|$)+ ]]; then
# Группа найдена, имя и id совпадают, пропускаем добавление
continue
elif [[ ${FINDGROUP_ID} != "" && $(cat ${FILE_GROUP} 2>/dev/null) =~ ($'\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}"
${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_FINDGROUP_ID} ${SELECT_GROUP}
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_03_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}" || unset ARG_SELECT_UID
if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-c ${SELECT_GECOS}" || unset ARG_SELECT_GECOS
[[ -n ${DEFAULTGROUP} ]] && ARG_DEFAULTGROUP="-G ${DEFAULTGROUP}" || unset ARG_DEFAULTGROUP
${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}" || unset ARG_SELECT_GECOS
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}"
${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 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(){
local SELECT_USERNAME=$1
if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then
# Вызов как исполнителя после ubconfig
# Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить хеш параметра USERADD[.*] в /etc/ublinux/users
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
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}" 2>/dev/null
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
# busybox deluser
${CMD_CHROOT} /usr/bin/busybox deluser ${SELECT_USERNAME} 2>/dev/null
fi
fi
IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}"
[[ ${SELECT_GECOS,,} == "x" ]] && unset SELECT_GECOS
[[ ${SELECT_UID,,} == "x" || ${SELECT_UID} =~ ^[^0-9]+$ ]] && unset SELECT_UID
[[ ${SELECT_GROUP,,} == "x" ]] && unset SELECT_GROUP
[[ ${SELECT_EXTRAGROUPS,,} == "x" ]] && unset SELECT_EXTRAGROUPS
[[ ${SELECT_OPTIONAL,,} == "x" ]] && unset SELECT_OPTIONAL
[[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD="${DEFAULTPASSWD}"
[[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})
# Если в дополнительных группа присутствует группа по имени пользователя, то удалить её из списка
SELECT_EXTRAGROUPS=${SELECT_EXTRAGROUPS//${SELECT_USERNAME}/}
# Создадать группы из параметра SELECT_EXTRAGROUPS
local SELECT_EXTRAGROUPS_TO_EXEC_01=
[[ -n ${SELECT_EXTRAGROUPS} ]] && while IFS= read -u4 ITEM_SELECT_EXTRAGROUP; do
if [[ -n ${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]} ]]; then
exec_05_groupadd "GROUPADD[${ITEM_SELECT_EXTRAGROUP}]=${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]}"
elif [[ ${ITEM_SELECT_EXTRAGROUP} != "" ]]; then
SELECT_EXTRAGROUPS_TO_EXEC_01+="${ITEM_SELECT_EXTRAGROUP},"
fi
done 4<<< "${SELECT_EXTRAGROUPS//,/$'\n'}"
[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && exec_01_add_groups "${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}"
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=;
if [[ ! $(cat ${FILE_PASSWD} 2>/dev/null) =~ ($'\n'|^)+"${SELECT_USERNAME}": ]]; then
# Проверяем наличие пользователя в системе
[[ -n ${SELECT_UID} && ${SELECT_UID} != 0 ]] && ARG_SELECT_UID="--uid ${SELECT_UID}" || unset ARG_SELECT_UID
# Если указана основная группа, но она не создана, то создать
unset ARG_GROUPADD_GID ARG_GROUPADD_GROUPNAME
if [[ -n ${SELECT_GROUP} && -n ${GROUPADD[${SELECT_GROUP}]} ]]; then
# Если группа указана и присутствует в списке групп GROUPADD[.]
exec_05_groupadd "GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}"
elif [[ -n ${SELECT_GROUP} && ! $(cat ${FILE_GROUP}) =~ ($'\n'|^)+(${SELECT_GROUP}:|[^$'\n']*:${SELECT_GROUP}:) ]]; then
# Если группа указана и не найдена в файле shadow
# Группа имет цифровой GID и номер GID=UID
if [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} == ${SELECT_UID} ]]; then
#ARG_GROUPADD_GID=" --gid ${SELECT_GROUP}"
ARG_GROUPADD_GID="${SELECT_GROUP}"
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
elif [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} != ${SELECT_UID} ]]; then
# Группа имет цифровой GID и номер GID!=UID
#ARG_GROUPADD_GID=" --gid ${SELECT_GROUP}"
ARG_GROUPADD_GID="${SELECT_GROUP}"
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
elif [[ ${SELECT_GROUP} =~ [[:alpha:]]+ ]]; then
# Группа имет буквенный GID
ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME}
else
# Если группа не имеет цифры и буквы
unset SELECT_GROUP
fi
[[ -n ${ARG_GROUPADD_GROUPNAME} ]] && exec_05_groupadd "GROUPADD[${ARG_GROUPADD_GROUPNAME}]=x:${ARG_GROUPADD_GID}"
fi
# Создаём пользователя
if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="--comment ${SELECT_GECOS}" || unset ARG_SELECT_GECOS
[[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="--gid ${SELECT_GROUP}" || unset ARG_SELECT_GROUP
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password ${SELECT_PASSWORD}" || unset 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}${PATH_HOME}/${SELECT_USERNAME}" ]] || ARG_SELECT_OPTIONAL+=" --create-home"; }
[[ ${SELECT_OPTIONAL} =~ ("-N"|"--no-user-group") ]] || { [[ -z ${SELECT_GROUP} ]] && ARG_SELECT_OPTIONAL+=" --user-group"; }
${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME} #>/dev/null 2>&1
[[ $? -eq 0 ]] || { echo "Try 2:useradd"; ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; }
[[ $? -eq 0 ]] || { echo "Try 3:useradd"; ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; }
[[ $? -eq 0 ]] || { echo "Try 4:useradd"; ${CMD_CHROOT} /usr/bin/useradd ${SELECT_USERNAME}; }
elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
# busybox adduser
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g ${SELECT_GECOS}" || unset 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"
${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
if [[ -x ${ROOTFS}/usr/bin/usermod ]]; then
# Добавляем пользователя в основную группу
#${CMD_CHROOT} /usr/bin/usermod -a -G ${SELECT_EXTRAGROUPS%*,} ${SELECT_USERNAME} #>/dev/null 2>&1
# Добавляем пользователя в дополнительные группы
${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}${PATH_HOME}/${SELECT_USERNAME} && $(${CMD_CHROOT} /usr/bin/stat -c "%U:%G" ${PATH_HOME}/${SELECT_USERNAME}) != "${SELECT_USERNAME}:${SELECT_GROUP:-${SELECT_USERNAME}}" ]]; then
[[ -n ${ROOTFS} ]] && ARG_RECURSIVE="-R" || unset 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:-${SELECT_USERNAME}}" ${PATH_HOME}/"${SELECT_USERNAME}"
fi
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 --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
}
# Параметры пользователя системы /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
[[ -n ${SELECT_USERNAME} ]] && ${CMD_CHROOT} /usr/bin/getent shadow ${SELECT_USERNAME} &>/dev/null || continue
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}$ ]] && unset SELECT_LASTCHANGED
[[ ${SELECT_LASTCHANGED} =~ (^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || unset SELECT_LASTCHANGED
[[ ${SELECT_MINDAY} =~ ^[0-9]*$ ]] || unset SELECT_MINDAY
[[ ${SELECT_MAXDAY} =~ ^[0-9]*$ ]] || unset SELECT_MAXDAY
[[ ${SELECT_WARN} =~ ^[0-9]*$ ]] || unset SELECT_WARN
[[ ${SELECT_INACTIVE} =~ ^[0-9]*$ ]] || unset 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} =~ (^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || unset SELECT_EXPIRE
[[ -n ${SELECT_LASTCHANGED} ]] && ARG_SELECT_LASTCHANGED="--lastday ${SELECT_LASTCHANGED}" || unset ARG_SELECT_LASTCHANGED
[[ -n ${SELECT_MINDAY} ]] && ARG_SELECT_MINDAY="--mindays ${SELECT_MINDAY}" || unset ARG_SELECT_MINDAY
[[ -n ${SELECT_MAXDAY} ]] && ARG_SELECT_MAXDAY="--maxdays ${SELECT_MAXDAY}" || unset ARG_SELECT_MAXDAY
[[ -n ${SELECT_WARN} ]] && ARG_SELECT_WARN="--warndays ${SELECT_WARN}" || unset ARG_SELECT_WARN
[[ -n ${SELECT_INACTIVE} ]] && ARG_SELECT_INACTIVE="--inactive ${SELECT_INACTIVE}" || unset ARG_SELECT_INACTIVE
[[ -n ${SELECT_EXPIRE} ]] && ARG_SELECT_EXPIRE="--expiredate ${SELECT_EXPIRE}" || unset 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
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 -i "${SYSCONF}/users"
fi
IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}"
[[ ${SELECT_USERS} == "x" ]] && unset SELECT_USERS
[[ ${SELECT_GID,,} == "x" || ${SELECT_GID} =~ ^[^0-9]*$ ]] && unset SELECT_GID
#echo "==> ${SELECT_GROUP}:${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}"
[[ ${SELECT_OPTIONAL} == "x" ]] && unset SELECT_OPTIONAL
[[ ${SELECT_PASSWORD} == @(""|"x") ]] && unset SELECT_PASSWORD
[[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})
# Поиск по имени в шаблонах пользователей/групп systemd
[[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || unset FINDGROUP_ID
# Поиск по GID в шаблонах пользователей/групп systemd
[[ -z ${FINDGROUP_ID} ]] \
&& [[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]} || unset FINDGROUP_NAME
[[ -n ${FINDGROUP_ID} ]] && SELECT_GID="${FINDGROUP_ID}"
[[ -n ${FINDGROUP_NAME} ]] && SELECT_GID="${FINDGROUP_NAME}"
DATA_FILE_GROUP=$(cat ${FILE_GROUP} 2>/dev/null)
# Добавляем аргументы к опциям, при условии что такого GID не существует
[[ -n ${SELECT_GID} ]] && [[ ! ${DATA_FILE_GROUP} =~ :${SELECT_GID}: ]] && ARG_SELECT_GID="--gid ${SELECT_GID}" || unset ARG_SELECT_GID
#[[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="--users ${SELECT_USERS}" || unset ARG_SELECT_USERS
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password ${SELECT_PASSWORD}" || unset 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}
${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
[[ $? -eq 0 ]] || { echo "Try 2: groupadd"; ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; }
[[ $? -eq 0 ]] || { echo "Try 3: groupadd"; ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; }
[[ $? -eq 0 ]] || { echo "Try 4: groupadd"; ${CMD_CHROOT} /usr/bin/groupadd --force ${SELECT_GROUP} ; }
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" || unset ARG_NON_UNIQUE
[[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password ${SELECT_PASSWORD}" || unset ARG_SELECT_PASSWORD
#${CMD_CHROOT} /usr/bin/groupmod --append ${ARG_SELECT_USERS} ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}
${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} 2>/dev/null)
unset REAL_SELECT_USERS REAL_SELECT_ADMINISTRATORS
# Если пользователь не существуют то убрать из списка SELECT_USERS
while IFS= read -r READ_SELECT_USERS; do
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${READ_SELECT_USERS}: ]] && REAL_SELECT_USERS+=",${READ_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} || unset SELECT_USERS
# Если пользователь не существуют то убрать из списка REAL_SELECT_ADMINISTRATORS
while IFS= read -r READ_SELECT_ADMINISTRATORS; do
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${READ_SELECT_ADMINISTRATORS}: ]] && REAL_SELECT_ADMINISTRATORS+=",${READ_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} || unset SELECT_ADMINISTRATORS
# Добавляем пользователей в группу, т.к. groupadd не добавил пользователей в /etc/shadow
if [[ -n ${SELECT_USERS} || -n ${SELECT_ADMINISTRATORS} ]]; then
if [[ -x ${ROOTFS}/usr/bin/gpasswd ]]; then
[[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="-M ${SELECT_USERS}" || unset ARG_SELECT_USERS
[[ -n ${SELECT_ADMINISTRATORS} ]] && ARG_SELECT_ADMINISTRATORS="-A ${SELECT_ADMINISTRATORS}" || unset ARG_SELECT_ADMINISTRATORS
${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
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[@]}")
eval "${LIST_GROUPADD_GID}"
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
else
sed "/FIRSTSTART=/d" -i ${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