Add new options

master v2.46
Dmitry Razumov 2 years ago
parent bf16565e69
commit 1af4743af6
Signed by: asmeron
GPG Key ID: 50BC1DB583B79706

@ -7,6 +7,7 @@ declare -A AUTHPAM
declare -A JOURNALD declare -A JOURNALD
declare -A SYSTEMD_COREDUMP declare -A SYSTEMD_COREDUMP
declare -A DOMAIN declare -A DOMAIN
declare -A REPOSITORY
##rc.desktop/all/* is launching when desktop is ready ##rc.desktop/all/* is launching when desktop is ready
@ -227,3 +228,10 @@ SYSTEMD_COREDUMP[Storage]=none
SYSTEMD_COREDUMP[ProcessSizeMax]=0 SYSTEMD_COREDUMP[ProcessSizeMax]=0
DOMAIN[client]=realmd_sssd DOMAIN[client]=realmd_sssd
REPOSITORY[core]=::/etc/pacman.d/mirrorlist
REPOSITORY[extra]=::/etc/pacman.d/mirrorlist
REPOSITORY[community]=::/etc/pacman.d/mirrorlist
REPOSITORY[multilib]=::/etc/pacman.d/mirrorlist
REPOSITORY[ublinux]=::/etc/pacman.d/mirrorlist
REPOSITORY[modules]=::/etc/pacman.d/mirrorlist

@ -1,87 +1,171 @@
#!/usr/bin/env bash #!/usr/bin/env bash
[[ -d /usr/lib/ublinux ]] && { unset ROOTFS; unset CMD_CHROOT; } || { ROOTFS="/sysroot"; CMD_CHROOT="chroot ${ROOTFS}"; }
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SYSCONF="${ROOTFS}/${SYSCONF}"
export TEXTDOMAINDIR=/usr/share/locale export TEXTDOMAINDIR=/usr/share/locale
export TEXTDOMAIN=ublinux_functions export TEXTDOMAIN=ublinux_functions
# Make from ini file text file with strings like [SECTION]Name=Value # https://en.wikipedia.org/wiki/Crypt_(C)
# $1 - input filename # https://man.archlinux.org/man/core/libxcrypt/crypt.5.en # /etc/shadow file format
# stdout - result file # user:$6$.n.:17736:0:99999:7:::
function ini2simple(){ # [--] [----] [---] - [---] ----
SECTION='[]' # | | | | | |||+-----------> 9. Неиспользованный
cat $1 | while read a ;do # | | | | | ||+------------> 8. Срок годности
[ "$a" = "" ] && continue # | | | | | |+-------------> 7. Период бездействия
if [ "${a#\[*\]}" = "" -a "$a" != "" ] ;then # | | | | | +--------------> 6. Период предупреждения
SECTION=$a # | | | | +------------------> 5. Максимальный возраст пароля
else # | | | +----------------------> 4. Минимальный возраст пароля
echo "$SECTION$a" # | | +--------------------------> 3. Последнее изменение пароля
fi # | +---------------------------------> 2. Зашифрованный пароль
done # +----------------------------------------> 1. Имя пользователя
} # Если поле пароля содержит первый символ звездочку (*), то пользователь не сможет войти по паролю, но сможет другим способом (например по ключу через ssh)
# Если поле пароля содержит первый символ восклицательный знак (!), то пользователь вообще не сможет войти, даже по ключу
# Restore ini file from text file with strings like [SECTION]Name=Value # Алгоритмы хеширования пароля:
# $1 - input filename # (empty) # DES
# stdout - result file # $_$ # BSDi
function simple2ini(){ # $1$ # MD5
LASTSECTION='[]' # $2$ # bcrypt based on Blowfish
cat $1 | while read a ;do # $2a$ # Blowfish
SECTION=${a%%\]*}']' # $2b$ # OpenBSD blowfish
if [ "$SECTION" != "$LASTSECTION" ] ;then # $2x$ # blowfish
[ "LASTSECTION" != "[]" ] && echo # $2y$ # Eksblowfish
echo "$SECTION" # $3$ # NTHASH
LASTSECTION=$SECTION # $5$ # SHA-256
fi # $6$ # SHA-512
echo ${a#\[*\]} # $7$ # scrypt
done # $md5$ # Solaris MD5
# $sha1$ # PBKDF1 with SHA1
# $gy$ # gost-yescrypt
# $y$ # yescrypt
# $argon2d$ # Argon2d
# $argon2i$ # Argon2i
# $argon2ds$ # Argon2ds
# $argon2id$ # Argon2id
# Получить хеш пароля, тип хеша
# $1 # Режим получения хеша, значения: hash, phash
# hash # Вернуть хеш, если первые символы %%, то удалить их и вернуть хеш
# phash # Если первые символы %%, то убрать %% и вернуть не шифрованный пароль, в остальных случаях вернуть хеш
# $2 # Тип хеша, поддерживаются yescrypt|gost-yescrypt|scrypt|bcrypt|bcrypt-a|sha512crypt|sha256crypt|sunmd5|md5crypt|bsdicrypt|descrypt|nt
# # В разработке argon2d|argon2i|argon2ds|argon2id
# $3 # Пароль пользователя шифрованный или не шифрованный. Если шифрованный, то вернётся как есть
return_hash_password(){
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
[[ $1 == @(hash|phash) ]] && local ARG_MODE=$1 && shift
[[ -n ${ARG_MODE} ]] || ARG_MODE='hash'
[[ $1 == @(yescrypt|gost-yescrypt|scrypt|bcrypt|bcrypt-a|sha512crypt|sha256crypt|sunmd5|md5crypt|bsdicrypt|descrypt|nt|argon2d|argon2i|argon2ds|argon2id) ]] && local ARG_HASH=$1 && shift
[[ -n ${ARG_HASH} ]] || ARG_HASH=${HASHPASSWD}
[[ -n ${ARG_HASH} ]] || ARG_HASH=$(${ROOTFS}/usr/bin/ubconfig --raw --default get users HASHPASSWD)
[[ -n ${ARG_HASH} && ${ARG_HASH} != "(null)" ]] || ARG_HASH='yescrypt'
local ARG_PASSWORD="$1"
local HASH_PASSWORD=${ARG_PASSWORD}
[[ -n ${ARG_PASSWORD} ]] || return 0
if [[ ! ${ARG_PASSWORD} =~ ^('!*'|'!'|'*')*'$'(_|1|2|2a|2b|2x|2y|3|4|5|6|7|md5|sha1|gy|y|argon2d|argon2i|argon2ds|argon2id)'$' ]]; then
[[ ${ARG_PASSWORD} =~ ^'%%' ]] && ARG_PASSWORD=${ARG_PASSWORD:2} && HASH_PASSWORD=${ARG_PASSWORD} || ARG_MODE='hash'
if [[ ${ARG_MODE} == 'hash' && ${ARG_HASH} =~ (yescrypt|gost-yescrypt|scrypt|bcrypt|bcrypt-a|sha512crypt|sha256crypt|sunmd5|md5crypt|bsdicrypt|descrypt|nt) ]]; then
HASH_PASSWORD=$(echo "${ARG_PASSWORD}" | ${ROOTFS}/usr/bin/mkpasswd2 -sm ${ARG_HASH})
elif [[ ${ARG_HASH} =~ (argon2d|argon2i|argon2ds|argon2id) ]]; then
true
fi
fi
echo "${HASH_PASSWORD}"
} }
# It include string from $2 file and apply to $1 file # Remove user home directories. Used ubl-settings-usergroup
# $1 - base file # $1 # Users name a comma separated list
# $2 - included file remove_userhome(){
function apply2simple(){ local LIST_USERNAME="$@"
cat "$2" | while read a ;do [[ ${LIST_USERNAME} != "" ]] || return 1
SECTION=${a%%\]*} while IFS= read -r SELECT_USERNAME; do
SECTION=${SECTION#\[} rm -rdf ${ROOTFS}/home/"${SELECT_USERNAME}"
STR=${a#\[*\]} done < <(tr ',;' '\n' <<< ${LIST_USERNAME})
PNAME=${STR%%=*}
PVAL=${a#*=}
# echo $SECTION $PNAME $PVAL
echo -ne >"$1.tmp"
echo -ne >"$1.lck"
FOUNDS=
cat "$1" | while read b ;do
BSECTION=${b%%\]*}
BSECTION=${BSECTION#\[}
BSTR=${b#\[*\]}
BPNAME=${BSTR%%=*}
BPVAL=${b#*=}
[ "$BSECTION" = "$SECTION" ] && FOUNDS=1
if [ "$BSECTION" = "$SECTION" -a "$BPNAME" = "$PNAME" ] ;then
b="$a"
rm -f "$1.lck"
fi
if [ "$BSECTION" != "$SECTION" -a "$FOUNDS" != "" -a -f "$1.lck" ] ;then
echo "$a" >> "$1.tmp"
rm -f "$1.lck"
fi
echo "$b" >> "$1.tmp"
done
[ -f "$1.lck" ] && echo "$a" >> "$1.tmp"
mv -f "$1.tmp" "$1"
rm -f "$1.lck"
done
} }
# It include string from $2 ini file and apply to $1 ini file # Convert plain passwords to a hash in the global configuration
# $1 - base file # Конвертировать не шифрованные пароли в шифрованные для глобальных переменных USERADD GROUPADD DEFAULTPASSWD DEFAULTROOTPASSWD
# $2 - included file # $1 # Параметр конфигурации, где содержится пароль который нужно конвертировать, если первые символы %%, то пароль останется не шифрованным
function concatenate_ini(){ # Если запущенно без параметра, то все пароли зашифровать в переменных USERADD GROUPADD DEFAULTPASSWD DEFAULTROOTPASSWD
[ -f "$1" -a -f "$2" ] || return 1 globalconf_convert_pass_plain_to_hash(){
ini2simple "$1" >"$1.tmp" [[ -z ${ROOTFS} ]] || return 0
ini2simple "$2" >"$2.tmp" SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
apply2simple "$1.tmp" "$2.tmp" SOURCE=${ROOTFS}/root/.ublinux/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
simple2ini "$1.tmp" >"$1" local PARAM="$@"
rm -f "$1.tmp" "$2.tmp" local -A USERADD
local -A GROUPADD
local DEFAULTPASSWD
local DEFAULTROOTPASSWD
[[ -n ${HASHPASSWD} ]] || HASHPASSWD=$(/usr/bin/ubconfig --raw --default get users HASHPASSWD)
[[ -n ${HASHPASSWD} && ${HASHPASSWD} != "(null)" ]] || HASHPASSWD='yescrypt'
if [[ -n ${PARAM} ]]; then
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
# Проверим DEFAULTPASSWD, если не указан в $1, то подгрузить из глобальной конфигурации
[[ -n ${PARAM} ]] || DEFAULTPASSWD=$(ubconfig --raw --source global get [users] DEFAULTPASSWD)
if [[ -n ${DEFAULTPASSWD} && ${DEFAULTPASSWD} != "(null)" ]]; then
if [[ -n ${PARAM} && ${DEFAULTPASSWD} =~ ^'%%'(.*)$ ]]; then
ubconfig --noexecute --target global set [users] DEFAULTPASSWD="${BASH_REMATCH[1]}"
else
#return_hash_password "${DEFAULTPASSWD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] DEFAULTPASSWD="${HASH_PASSWORD_NEW}"
ubconfig --noexecute --target global set [users] DEFAULTPASSWD="$(return_hash_password hash ${HASHPASSWD} ${DEFAULTPASSWD})"
fi
fi
# Проверим DEFAULTROOTPASSWD, если не указан в $1, то подгрузить из глобальной конфигурации
[[ -n ${PARAM} ]] || DEFAULTROOTPASSWD=$(ubconfig --raw --source global get [users] DEFAULTROOTPASSWD)
if [[ -n ${DEFAULTROOTPASSWD} && ${DEFAULTROOTPASSWD} != "(null)" ]]; then
if [[ -n ${PARAM} && ${DEFAULTROOTPASSWD} =~ ^'%%'(.*)$ ]]; then
ubconfig --noexecute --target global set [users] DEFAULTROOTPASSWD="${BASH_REMATCH[1]}"
else
#return_hash_password "${DEFAULTROOTPASSWD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] DEFAULTROOTPASSWD="${HASH_PASSWORD_NEW}"
ubconfig --noexecute --target global set [users] DEFAULTROOTPASSWD="$(return_hash_password hash ${HASHPASSWD} ${DEFAULTROOTPASSWD})"
fi
fi
# Проверим USERADD, если не указан в $1, то подгрузить из глобальной конфигурации
[[ -n ${PARAM} ]] || while IFS= read -r SELECT_USERADD; do
if [[ ! ${SELECT_USERADD%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]]; then
VAR_NAME=${SELECT_USERADD%%=*}
VAR_VALUE=${SELECT_USERADD#*=}; VAR_VALUE=${VAR_VALUE//\'/}
eval "${VAR_NAME}=\${VAR_VALUE}"
fi
done < <(ubconfig --source global get [users] USERADD[*])
if [[ ${#USERADD[@]} != 0 ]]; then
while IFS= read -u3 SELECT_USERNAME; do
IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}"
if [[ ${SELECT_PASSWORD} != "" ]]; then
if [[ -n ${PARAM} && ${SELECT_PASSWORD} =~ ^'%%'(.*)$ ]]; then
ubconfig --noexecute --target global set [users] USERADD[${SELECT_USERNAME}]="${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${BASH_REMATCH[1]}"
else
#return_hash_password "${SELECT_PASSWORD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] USERADD[${SELECT_USERNAME}]="${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${HASH_PASSWORD_NEW}"
ubconfig --noexecute --target global set [users] USERADD[${SELECT_USERNAME}]="${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})"
fi
fi
done 3< <(printf "%s\n" "${!USERADD[@]}")
fi
# Проверим GROUPADD, если не указан в $1, то подгрузить из глобальной конфигурации
[[ -n ${PARAM} ]] || while IFS= read -r SELECT_GROUPADD; do
if [[ ! ${SELECT_GROUPADD%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]]; then
VAR_NAME=${SELECT_GROUPADD%%=*}
VAR_VALUE=${SELECT_GROUPADD#*=}; VAR_VALUE=${VAR_VALUE//\'/}
eval "${VAR_NAME}=\${VAR_VALUE}"
fi
done < <(ubconfig --source global get [users] GROUPADD[*])
if [[ ${#GROUPADD[@]} != 0 ]]; then
while IFS= read -u3 SELECT_GROUP; do
IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}"
if [[ ${SELECT_PASSWORD} != "" ]]; then
if [[ -n ${PARAM} && ${SELECT_PASSWORD} =~ ^'%%'(.*)$ ]]; then
ubconfig --noexecute --target global set [users] GROUPADD[${SELECT_GROUP}]="${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${BASH_REMATCH[1]}"
else
#return_hash_password "${SELECT_PASSWORD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] GROUPADD[${SELECT_GROUP}]="${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${HASH_PASSWORD_NEW}"
ubconfig --noexecute --target global set [users] GROUPADD[${SELECT_GROUP}]="${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})"
fi
fi
done 3< <(printf "%s\n" "${!GROUPADD[@]}")
fi
} }
detectDE(){ detectDE(){
@ -126,7 +210,7 @@ debug_log(){
} }
log(){ log(){
echo "$@" 2>/dev/null >>/var/log/ublinuxlog echo "$@" 2>/dev/null >>/var/log/ublinux.log
} }
debug_mode(){ debug_mode(){
@ -227,7 +311,7 @@ allow_only_root(){
# Hotkeys functions # # Hotkeys functions #
##################### #####################
notify-send(){ notify_send(){
local FIND_DISPLAY=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)" local FIND_DISPLAY=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
local FIND_USER=$(who | grep '('${FIND_DISPLAY}')' | awk '{print $1}' | head -n 1) #' local FIND_USER=$(who | grep '('${FIND_DISPLAY}')' | awk '{print $1}' | head -n 1) #'
local FIND_UID=$(id -u ${FIND_USER}) local FIND_UID=$(id -u ${FIND_USER})
@ -416,4 +500,19 @@ screen_scale(){
fi fi
} }
[[ $(basename $0) == functions ]] && $@ || true ################
##### MAIN #####
################
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
while [[ $# -gt 0 ]]; do
declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" '${1}'" && shift; }
done
eval ${FUNCTION#*; }
fi

@ -13,8 +13,6 @@ SYSCONF="${ROOTFS}/${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/boot; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/boot; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null
SELF_NAME="20-grub"
get_path_grub2(){ get_path_grub2(){
NAME_GRUB_CFG="grub.cfg" NAME_GRUB_CFG="grub.cfg"
PATH_GRUB=$(find ${ROOTFS}/memory/data/from/*/boot/grub/ -maxdepth 1 -type f -name "${NAME_GRUB_CFG}" | head -1) PATH_GRUB=$(find ${ROOTFS}/memory/data/from/*/boot/grub/ -maxdepth 1 -type f -name "${NAME_GRUB_CFG}" | head -1)
@ -162,21 +160,22 @@ exec_grub_cmdline_linux(){
################ ################
##### MAIN ##### ##### MAIN #####
################ ################
# Возможность подключить как source из любого скрипта и вызов встроенных функций # Возможность подключить как source из любого скрипта и вызов встроенных функций
get_path_grub2 || exit 1 get_path_grub2 || exit 1
FILE_GRUB_VAR_USER="${PATH_GRUB}/ublinux/grub_var_user.cfg" FILE_GRUB_VAR_USER="${PATH_GRUB}/ublinux/grub_var_user.cfg"
[[ -f ${FILE_GRUB_VAR_USER} ]] || touch ${FILE_GRUB_VAR_USER} [[ -f ${FILE_GRUB_VAR_USER} ]] || touch ${FILE_GRUB_VAR_USER}
if [[ ${0##*/} == ${SELF_NAME} && -z $@ ]]; then # Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do while read -r FUNCTION; do
$"${FUNCTION##* }" $"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_") done < <(declare -F | grep "declare -f exec_")
elif [[ ${0##*/} == ${SELF_NAME} ]]; then else
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" ${1}" && shift; } declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" \"${1}\"" && shift; }
done done
eval ${FUNCTION#*; } eval ${FUNCTION#*; }
else
true
fi fi

@ -0,0 +1,124 @@
#!/usr/bin/env bash
ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
unset ROOTFS; [[ -d /usr/lib/ublinux ]] || ROOTFS=.
SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
debug_mode "$0" "$@"
SYSCONF="${ROOTFS}/${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
# Синхронизировать пользователе системы в глобальную конфигурацию USERADD и USERSHADOW
## Синхронизация пользователей системы /etc/passwd с глобальной конфигурацией
## USERADD_SYNC[user_name]='boot,shutdown'
## user_name # Имя пользователя, необязательное поле. Если не указано, то применяется для всех пользователей
## boot # При загрузке системы принудительно применить глобальную конфигурацию на пользователя
## shutdown # При завершении работы системы синхронизировать указанных пользователей в системе с глобальной конфигурацией
exec_useradd_sync(){
FILE_PASSWD="${ROOTFS}/etc/passwd"
FILE_SHADOW="${ROOTFS}/etc/shadow"
sync_user(){
local SELECT_USER="$1"
local SELECT_OPTIONAL=
local SELECT_EXTRAGROUPS=
[[ $(grep ^"${SELECT_USER}:" ${FILE_PASSWD}) =~ ^(.*):(.*):(.*):(.*):(.*):(.*):(.*)$ ]] \
&& SELECT_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& SELECT_UID=${BASH_REMATCH[3]} \
&& SELECT_GROUP=${BASH_REMATCH[4]} \
&& SELECT_GECOS=${BASH_REMATCH[5]} \
&& SELECT_HOMEDIR=${BASH_REMATCH[6]} \
&& SELECT_SHELL=${BASH_REMATCH[7]}
[[ $(grep ^"${SELECT_USER}:" ${FILE_SHADOW}) =~ ^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$ ]] \
&& SELECT_PASSWORD=${BASH_REMATCH[2]} \
&& SELECT_LASTCHANGED=${BASH_REMATCH[3]} \
&& SELECT_MINDAY=${BASH_REMATCH[4]} \
&& SELECT_MAXDAY=${BASH_REMATCH[5]} \
&& SELECT_WARN=${BASH_REMATCH[6]} \
&& SELECT_INACTIVE=${BASH_REMATCH[7]} \
&& SELECT_EXPIRE=${BASH_REMATCH[8]} \
&& SELECT_NOUSE=${BASH_REMATCH[9]}
[[ -n ${SELECT_LASTCHANGED} ]] && SELECT_LASTCHANGED=$(date -d @$((${SELECT_LASTCHANGED}*24*60*60)) +'%Y-%m-%d')
[[ -n ${SELECT_EXPIRE} ]] && SELECT_LASTCHANGED=$(date -d @$((${SELECT_EXPIRE}*24*60*60)) +'%Y-%m-%d')
while IFS= read -r EXTRAGROUP; do [[ "${USERGROUPS},nobody" =~ ${EXTRAGROUP} ]] || SELECT_EXTRAGROUPS+=",${EXTRAGROUP}"; done < <(tr ' ' '\n' <<< $(id -nrG ${SELECT_USER}))
SELECT_EXTRAGROUPS=${SELECT_EXTRAGROUPS:1}
[[ -n ${SELECT_HOMEDIR} && ${SELECT_HOMEDIR} != "/home/${SELECT_USER}" ]] && SELECT_OPTIONAL+=" --home-dir ${SELECT_HOMEDIR}"
[[ -n ${SELECT_SHELL} && ${SELECT_SHELL} != "/bin/bash" ]] && SELECT_OPTIONAL+=" --shell ${SELECT_SHELL}"
${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] USERADD[${SELECT_USER}]="${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}"
${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] USERSHADOW[${SELECT_USER}]="${SELECT_LASTCHANGED}:${SELECT_MINDAY}:${SELECT_MAXDAY}:${SELECT_WARN}:${SELECT_INACTIVE}:${SELECT_EXPIRE}"
}
if [[ ${USERADD_SYNC} =~ 'shutdown' ]]; then
# Все пользователи
UID_MIN=$([[ $(cat "${ROOTFS}/etc/login.defs") =~ [^#[^:space:]]*UID_MIN[[:space:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_USER; do
sync_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN} '$3 >= USER_MIN && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${#USERADD_SYNC[@]} != 0 ]]; then
while IFS= read -u3 SELECT_USER; do
[[ ${USERADD_SYNC[${SELECT_USER}]} =~ 'shutdown' ]] && sync_user ${SELECT_USER}
done 3< <(printf "%s\n" "${!USERADD_SYNC[@]}")
fi
}
# Синхронизировать группы системы в глобальную конфигурацию GROUPADD
## Синхронизация группы системы /etc/groups и их параметры /etc/gshadow с глобальной конфигурацией
## GROUPADD_SYNC[group_name]='boot,shutdown'
## group_name # Имя группы, необязательное поле. Если не указано, то применяется для всех групп
## boot # При загрузке системы принудительно применить глобальную конфигурацию на группу
## shutdown # При завершении работы системы синхронизировать указанные группы в системе с глобальной конфигурацией
exec_groupadd_sync(){
FILE_GROUP="${ROOTFS}/etc/group"
FILE_GSHADOW="${ROOTFS}/etc/gshadow"
sync_group(){
local SELECT_GROUP="$1"
local SELECT_OPTIONAL=
[[ $(grep ^"${SELECT_GROUP}:" ${FILE_GROUP}) =~ ^(.*):(.*):(.*):(.*)$ ]] \
&& SELECT_GPASSWORD=${BASH_REMATCH[2]} \
&& SELECT_GID=${BASH_REMATCH[3]} \
&& SELECT_GUSERS=${BASH_REMATCH[4]}
[[ $(grep ^"${SELECT_GROUP}:" ${FILE_GSHADOW}) =~ ^(.*):(.*):(.*):(.*)$ ]] \
&& SELECT_PASSWORD=${BASH_REMATCH[2]} \
&& SELECT_ADMINISTRATORS=${BASH_REMATCH[3]} \
&& SELECT_SUSERS=${BASH_REMATCH[4]} \
${ROOTFS}/usr/bin/ubconfig --quiet --target global set [users] GROUPADD[${SELECT_GROUP}]="${SELECT_GUSERS}:${SELECT_GID}::${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}"
}
if [[ ${GROUPADD_SYNC} =~ 'shutdown' ]]; then
# Все группы
GID_MIN=$([[ $(cat "${ROOTFS}/etc/login.defs") =~ [^#[^:space:]]*GID_MIN[[:space:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_GROUP; do
sync_group "${SELECT_GROUP}"
done < <(awk -F':' -v GROUP_MIN=${GID_MIN} '$3 >= GROUP_MIN && $1 != "nobody" { print $1}' ${FILE_GROUP})
elif [[ ${#GROUPADD_SYNC[@]} != 0 ]]; then
while IFS= read -u3 SELECT_GROUP; do
[[ ${GROUPADD_SYNC[${SELECT_GROUP}]} =~ 'shutdown' ]] && sync_group ${SELECT_GROUP}
done 3< <(printf "%s\n" "${!GROUPADD_SYNC[@]}")
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
while [[ $# -gt 0 ]]; do
declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" \"${1}\"" && shift; }
done
eval ${FUNCTION#*; }
fi

@ -0,0 +1,57 @@
#!/usr/bin/env bash
ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
. /usr/lib/ublinux/functions
. /usr/lib/ublinux/default
debug_mode "$0" "$@"
SOURCE=${SYSCONF}/config; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null
# Проверка файлов на ошибки /etc/passwd /etc/shadow /etc/group /etc/gshadow
exec_check_user_group(){
local CHECK_MODE=$@
[[ -z ${CHECK_MODE} ]] && CHECK_MODE="user,group"
if [[ ${CHECK_MODE} =~ "user" ]]; then
# Проверка файлов /etc/passwd /etc/shadow
if [[ -x /usr/bin/pwck ]]; then
# Сортировать файл passwd и shadow
/usr/bin/pwck -qs
# Вывести только предупреждение, если файл passwd или shadow повреждён
# /usr/bin/pwck -r
# Вывести предупреждение и исправить, если файл passwd или shadow повреждён
yes | /usr/bin/pwck -q
fi
fi
if [[ ${CHECK_MODE} =~ "group" ]]; then
# Проверка файлов /etc/group /etc/gshadow
if [[ -x /usr/bin/grpck ]]; then
# Сортировать файл group и gshadow
/usr/bin/grpck -qs
# Вывести предупреждение, если файл group или gshadow повреждён
# /usr/bin/grpck -r
# Вывести предупреждение и исправить, если файл group или gshadow повреждён
yes | /usr/bin/grpck -q
fi
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
#rm -f "${FILE_ROOT_USERS}"
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(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

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# #
# Initial script for UBLinux # Initial script for UBLinux
# This script are launching before starting init from initrd script # This script are launching before starting init from initrd script
@ -40,7 +40,7 @@ exec_services_enabledisable(){
if [[ -n ${PARAM} ]]; then if [[ -n ${PARAM} ]]; then
unset SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK unset SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK
unset SERVICES_ENABLE SERVICES_DISABLE SERVICES_MASK SERVICES_UNMASK unset SERVICES_ENABLE SERVICES_DISABLE SERVICES_MASK SERVICES_UNMASK
eval "${PARAM%%=*}='${PARAM#*=}'" eval "${PARAM%%=*}=\${PARAM#*=}"
else else
SERVICESSTART_KERNEL=$(cmdline_value servicesstart) SERVICESSTART_KERNEL=$(cmdline_value servicesstart)
SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable) SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable)
@ -59,26 +59,26 @@ exec_services_enabledisable(){
while IFS= read -ru3 SELECT_SERVICE; do while IFS= read -ru3 SELECT_SERVICE; do
[[ -n ${SELECT_SERVICE} ]] || continue [[ -n ${SELECT_SERVICE} ]] || continue
if [[ -n ${ISSYSTEMD} ]]; then if [[ -n ${ISSYSTEMD} ]]; then
${CMD_CHROOT} systemctl --quiet unmask ${SELECT_SERVICE} ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
fi fi
done 3< <(tr ',; ' '\n' <<< "${SERVICESUNMASK},${SERVICESSTART},${SERVICES_UNMASK},${SERVICES_ENABLE}" | tr -s '\n') done 3< <(tr ',; ' '\n' <<< "${SERVICESUNMASK},${SERVICESSTART},${SERVICES_UNMASK},${SERVICES_ENABLE}" | tr -s '\n')
while IFS= read -ru3 SELECT_SERVICE; do while IFS= read -ru3 SELECT_SERVICE; do
[[ -n ${SELECT_SERVICE} ]] || continue [[ -n ${SELECT_SERVICE} ]] || continue
if [[ -n ${ISSYSTEMD} ]]; then if [[ -n ${ISSYSTEMD} ]]; then
${CMD_CHROOT} systemctl --quiet enable ${SELECT_SERVICE} ${CMD_CHROOT} /usr/bin/systemctl --quiet enable ${SELECT_SERVICE}
fi fi
done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n') done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n')
while IFS= read -ru3 SELECT_SERVICE; do while IFS= read -ru3 SELECT_SERVICE; do
[[ -n ${SELECT_SERVICE} ]] || continue [[ -n ${SELECT_SERVICE} ]] || continue
if [[ -n ${ISSYSTEMD} ]]; then if [[ -n ${ISSYSTEMD} ]]; then
${CMD_CHROOT} systemctl --quiet disable ${SELECT_SERVICE} ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
fi fi
done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n') done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n')
while IFS= read -ru3 SELECT_SERVICE; do while IFS= read -ru3 SELECT_SERVICE; do
[[ -n ${SELECT_SERVICE} ]] || continue [[ -n ${SELECT_SERVICE} ]] || continue
if [[ -n ${ISSYSTEMD} ]]; then if [[ -n ${ISSYSTEMD} ]]; then
${CMD_CHROOT} systemctl --quiet disable ${SELECT_SERVICE} ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
${CMD_CHROOT} systemctl --quiet mask ${SELECT_SERVICE} ${CMD_CHROOT} /usr/bin/systemctl --quiet mask ${SELECT_SERVICE}
fi fi
done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n') done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n')
[[ -n ${ROOTFS} ]] && umount proc [[ -n ${ROOTFS} ]] && umount proc
@ -99,7 +99,7 @@ exec_services_startstop_live(){
if [[ -n ${PARAM} ]]; then if [[ -n ${PARAM} ]]; then
unset SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK unset SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK
unset SERVICES_ENABLE SERVICES_DISABLE SERVICES_MASK SERVICES_UNMASK unset SERVICES_ENABLE SERVICES_DISABLE SERVICES_MASK SERVICES_UNMASK
[[ ${PARAM%%=*} =~ [!\$%\&()*+,./:\;\<\=\>?\@\^\{|\}~-] ]] || eval "${PARAM%%=*}='${PARAM#*=}'" [[ ${PARAM%%=*} =~ [!\$%\&()*+,./:\;\<\=\>?\@\^\{|\}~-] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi fi
while IFS= read -ru3 SELECT_SERVICE; do while IFS= read -ru3 SELECT_SERVICE; do
[[ -n ${SELECT_SERVICE} ]] || continue [[ -n ${SELECT_SERVICE} ]] || continue
@ -136,7 +136,7 @@ exec_services_startstop_live(){
# if [[ -n ${PARAM} ]]; then # if [[ -n ${PARAM} ]]; then
# unset SERVICE # unset SERVICE
# declare -A SERVICE # declare -A SERVICE
# eval "${PARAM%%=*}='${PARAM#*=}'" # eval "${PARAM%%=*}=\${PARAM#*=}"
# else # else
# SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable) # SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable)
# [[ -z ${SERVICES_ENABLE_KERNEL} ]] || while read -u3 SELECT_SERVICE; do # [[ -z ${SERVICES_ENABLE_KERNEL} ]] || while read -u3 SELECT_SERVICE; do
@ -159,21 +159,21 @@ exec_services_startstop_live(){
# [[ -n ${SELECT_SERVICE} ]] || continue # [[ -n ${SELECT_SERVICE} ]] || continue
# if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then # if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet unmask ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
# echo ${CMD_CHROOT} systemctl --quiet enable ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet enable ${SELECT_SERVICE}
# fi # fi
# elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then # elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet disable ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
# fi # fi
# elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(mask) ]]; then # elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(mask) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet disable ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
# echo ${CMD_CHROOT} systemctl --quiet mask ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet mask ${SELECT_SERVICE}
# fi # fi
# elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(unmask) ]]; then # elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(unmask) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet unmask ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
# fi # fi
# fi # fi
# done 3< <(printf "%s\n" "${!SERVICE[@]}") # done 3< <(printf "%s\n" "${!SERVICE[@]}")
@ -194,18 +194,18 @@ exec_services_startstop_live(){
# [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && shift # [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && shift
# local PARAM="$@" # local PARAM="$@"
# if [[ -n ${PARAM} ]]; then # if [[ -n ${PARAM} ]]; then
# unset SERVICE # local SERVICE=
# declare -A SERVICE # declare -A SERVICE
# [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~-] ]] || eval "${PARAM%%=*}='${PARAM#*=}'" # [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~-] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
# fi # fi
# while read -u3 SELECT_SERVICE; do # while read -u3 SELECT_SERVICE; do
# if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then # if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet start ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet start ${SELECT_SERVICE}
# fi # fi
# elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then # elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then
# if [[ -n ${ISSYSTEMD} ]]; then # if [[ -n ${ISSYSTEMD} ]]; then
# echo ${CMD_CHROOT} systemctl --quiet stop ${SELECT_SERVICE} # echo ${CMD_CHROOT} /usr/bin/systemctl --quiet stop ${SELECT_SERVICE}
# fi # fi
# fi # fi
# done 3< <(printf "%s\n" "${!SERVICE[@]}") # done 3< <(printf "%s\n" "${!SERVICE[@]}")

@ -0,0 +1,287 @@
#!/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
[[ -d /usr/lib/ublinux ]] && { unset ROOTFS; unset CMD_CHROOT; } || { ROOTFS="/sysroot"; 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}/logging; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
## Настройка мониторинга и сбора системных событий и записи их в журналы для аудита
## AUDITD=disable|no|none|off # Отключить все созданные правила из конфигурации
## AUDITD[<id_name>]=<rule>
## <id_name> # Уникальное имя правила
## <rule> # Правило
#AUDITD[event_chmod]="-a always,exit -F arch=x86_64 -S chmod,fchmod,fchmodat -F key=event_chmod"
#AUDITD[passwd_changes]="-w /etc/passwd -p wa -k passwd_changes"
exec_auditd(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_PATTERN_AUDITD_CONF="${ROOTFS}/etc/audit/rules.d/00-ubconfig.rules"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
AUDITD_NAME=${PARAM%%=*}
AUDITD_VAR=${PARAM#*=}
fi
[[ -d ${FILE_PATTERN_AUDITD_CONF%/*} ]] || mkdir -p ${FILE_PATTERN_AUDITD_CONF%/*}
[[ -f ${FILE_PATTERN_AUDITD_CONF} ]] || true > "${FILE_PATTERN_AUDITD_CONF}"
if [[ -z ${PARAM} ]]; then
true > "${FILE_PATTERN_AUDITD_CONF}"
while IFS='=' read -u3 AUDITD_NAME AUDITD_VAR; do
[[ ${AUDITD_NAME} =~ ^.*'['(.*)']' ]] && AUDITD_NAME=${BASH_REMATCH[1]}
[[ ${AUDITD_VAR} =~ ^\"(.*)\"$ ]] && AUDITD_VAR=${BASH_REMATCH[1]}
echo "${AUDITD_VAR}" >> "${FILE_PATTERN_AUDITD_CONF}"
done 3< <(grep -E "^[[:space:]]*AUDITD\[" ${SYSCONF}/logging 2>/dev/null)
elif [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
[[ ${AUDITD_NAME} =~ ^.*'['(.*)']' ]] && AUDITD_NAME=${BASH_REMATCH[1]}
[[ ${AUDITD_VAR} =~ ^\"(.*)\"$ ]] && AUDITD_VAR=${BASH_REMATCH[1]}
echo "${AUDITD_VAR}" >> "${FILE_PATTERN_AUDITD_CONF}"
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ -n ${AUDITD_NAME} && ${AUDITD_VAR} != "" ]]; then
[[ ${AUDITD_NAME} =~ ^.*'['(.*)']' ]] && AUDITD_NAME=${BASH_REMATCH[1]}
AUDITD_VAR=${AUDITD[${AUDITD_NAME}]}
fi
[[ ${AUDITD_VAR} =~ ^\"(.*)\"$ ]] && AUDITD_VAR=${BASH_REMATCH[1]}
ESC_AUDITD_VAR=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${AUDITD_VAR}")
sed "/^${ESC_AUDITD_VAR}$/d" -i "${FILE_PATTERN_AUDITD_CONF}"
fi
}
exec_auditd_live(){
[[ -z ${ROOTFS} ]] || return 0
SERVICE_NAME="auditd.service"
if [[ $(pgrep -fc "exec_audit_live") == 1 ]]; then
if systemctl --quiet is-enabled ${SERVICE_NAME} 2>/dev/null; then
sleep 5
systemctl --quiet reset-failed ${SERVICE_NAME}
systemctl --quiet restart ${SERVICE_NAME} 2>/dev/null
fi
fi
}
## Настройка журналов
## https://www.freedesktop.org/software/systemd/man/journald.conf.html
## JOURNALD[<var>]=<value>
## <var> # Имя переменной настройки журнала
## Storage # Указывает, где хранить журнал. Доступны следующие параметры:
## # "volatile" - Журнал хранится в оперативной памяти, т.е. в каталоге /run/log/journal
## # "persistent" - Данные хранятся на диске, т.е. в каталоге /var/log/journal
## # "auto" - используется по-умолчанию
## # "none" - Журнал не ведётся
## Compress # Пороговое значение данных для сжатия и записи в ФС. Может принимать yes, no, цифра. Суффиксы, такие как K, M и G
## SplitMode # Определяет, следует ли разделять файлы журнала для каждого пользователя: «uid» или «none»
## RateLimitIntervalSec # Настраивает ограничение скорости, которое применяется ко всем сообщениям, интервал времени применения =30
## RateLimitBurst # Настраивает ограничение скорости, которое применяется ко всем сообщениям, лимит сообщений =10000
## SystemMaxUse # Указывает максимальное дисковое пространство, которое может использовать журнал в постоянном хранилище
## SystemKeepFree # Указывает объем места, которое журнал должен оставить свободным при добавлении записей журнала в постоянное хранилище
## SystemMaxFileSize # Определяет, до какого размера могут вырасти отдельные файлы журнала в постоянном хранилище перед ротацией
## RuntimeMaxUse # Указывает максимальное дисковое пространство, которое можно использовать в энергозависимом хранилище (в файловой системе /run)
## RuntimeKeepFree # Указывает объем пространства, которое будет выделено для других целей при записи данных в энергозависимое хранилище (в файловой системе /run)
## RuntimeMaxFileSize # Указывает объем места, которое отдельный файл журнала может занимать в энергозависимом хранилище (в файловой системе /run) перед ротацией
## ForwardToConsole # Перенаправить журнал на консоль, yes|no
## TTYPath # Измените используемый консольный TTY, если используется ForwardToConsole=yes. По умолчанию /dev/console.
## MaxLevelConsole # Тип сообщений перенаправляемые в журнал, варианты: emerg|alert|crit|err|warning|notice|info|debug или целочисленные значения в диапазоне 07
## <value> # Значение переменной настройки журнала
#JOURNALD[Storage]=persistent
#JOURNALD[Compress]=yes
#JOURNALD[SystemMaxUse]=8M
#JOURNALD[RuntimeMaxUse]=8M
exec_journald(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_JOURNALD_CONF="${ROOTFS}/etc/systemd/journald.conf.d/00-ubconfig.conf"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local JOURNALD=
declare -A JOURNALD
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ ! -f ${FILE_JOURNALD_CONF} ]] && mkdir -p "${FILE_JOURNALD_CONF%/*}" && touch ${FILE_JOURNALD_CONF}
[[ $(cat ${FILE_JOURNALD_CONF}) =~ "[Journal]" ]] || echo "[Journal]" > ${FILE_JOURNALD_CONF}
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#JOURNALD[@]} != 0 ]]; then
while IFS= read -u3 NAME_VAR; do
if [[ $(cat ${FILE_JOURNALD_CONF}) =~ "${NAME_VAR}=" ]]; then
sed "s/^${NAME_VAR}=.*/${NAME_VAR}=${JOURNALD[${NAME_VAR}]}/g" -i ${FILE_JOURNALD_CONF}
else
echo "${NAME_VAR}=${JOURNALD[${NAME_VAR}]}" >> ${FILE_JOURNALD_CONF}
fi
done 3< <(printf "%s\n" "${!JOURNALD[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
NAME_VAR=${BASH_REMATCH[1]}
sed "/${NAME_VAR}=/d" -i ${FILE_JOURNALD_CONF}
fi
fi
}
exec_journald_live(){
[[ -z ${ROOTFS} ]] || return 0
SERVICE_NAME="systemd-journald.service"
if [[ $(pgrep -fc "exec_journald_live") == 1 ]]; then
sleep 5
systemctl reset-failed ${SERVICE_NAME}
systemctl --quiet restart ${SERVICE_NAME}
fi
}
## Настройка дампа ядра
## https://www.freedesktop.org/software/systemd/man/latest/systemd-coredump.html
## SYSTEMD_COREDUMP[<var>]=<value>
## <var> # Имя переменной настройки журнала
## Storage # Указывает, где хранить дамп ядра. Доступны следующие параметры:
## journal # Дампы будут храниться в журнале и перезаписываться в соответствии со стандартными принципами ротации журналов
## external # Значение по умолчанию, дампы сохраняются в каталоге /var/lib/systemd/coredump/
## none # Дампы ядра записываются (включая обратную трассировку, если возможно), но не сохраняются
## Compress # Используется для сжатия дампов ядра. Принимает логический аргумент - *yes или no
## *yes # Дампы сжимаются при сохранении (значение по умолчанию)
## no # Дампы сохраняются без сжатия.
## ProcessSizeMax # Максимальный размер дампа процесса, который может быть сохранен. Если размер дампа превышает значение этого параметра, то дамп сохранен не будет. Суфиксы: B
## # Параметры Storage=none и ProcessSizeMax=0 отключает всю обработку дампа памяти, за исключением записи журнала
## ExternalSizeMax # Максимальный (сжатый или несжатый) размер дампа процесса, который будет сохранен на диске
## JournalSizeMax # Максимальный (сжатый или несжатый) размер дампа процесса, который будет сохранен в журнале системы
## MaxUse # Максимальный объем общего дискового пространства, который может быть использован для хранения дампов процессов. Суфиксы: B,K,M,G,T,P,E
## KeepFree # Минимальный объем свободного дискового пространства, который должен оставаться на диске при хранении дампов. Суфиксы: B,K,M,G,T,P,E
## <value> # Значение переменной настройки журнала
#SYSTEMD_COREDUMP[Storage]=none
#SYSTEMD_COREDUMP[ProcessSizeMax]=0
exec_systemd_coredump(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_SYSTEMD_COREDUMP_CONF="${ROOTFS}/etc/systemd/coredump.conf.d/00-ubconfig.conf"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local SYSTEMD_COREDUMP=
declare -A SYSTEMD_COREDUMP
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ ! -f ${FILE_SYSTEMD_COREDUMP_CONF} ]] && mkdir -p "${FILE_SYSTEMD_COREDUMP_CONF%/*}" && touch ${FILE_SYSTEMD_COREDUMP_CONF}
[[ $(cat ${FILE_SYSTEMD_COREDUMP_CONF}) =~ "[Coredump]" ]] || echo "[Coredump]" > ${FILE_SYSTEMD_COREDUMP_CONF}
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#SYSTEMD_COREDUMP[@]} != 0 ]]; then
while IFS= read -u3 NAME_VAR; do
if [[ $(cat ${FILE_SYSTEMD_COREDUMP_CONF}) =~ "${NAME_VAR}=" ]]; then
sed "s/^${NAME_VAR}=.*/${NAME_VAR}=${SYSTEMD_COREDUMP[${NAME_VAR}]}/g" -i ${FILE_SYSTEMD_COREDUMP_CONF}
else
echo "${NAME_VAR}=${SYSTEMD_COREDUMP[${NAME_VAR}]}" >> ${FILE_SYSTEMD_COREDUMP_CONF}
fi
done 3< <(printf "%s\n" "${!SYSTEMD_COREDUMP[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
NAME_VAR=${BASH_REMATCH[1]}
sed "/${NAME_VAR}=/d" -i ${FILE_SYSTEMD_COREDUMP_CONF}
fi
fi
}
## Настройка ротации файлов логов утилитой logrotate
## https://man.archlinux.org/man/logrotate.conf.5
## LOGROTATE[<tag>]="<mask_file_1>,<mask_file_2>,<mask_file_n>:<setting_1>,<setting_2>,<setting_n>"
#LOGROTATE[samba]="/var/log/samba/log.smbd,/var/log/samba/log.nmbd,/var/log/samba/*.log:notifempty,missingok,copytruncate"
#LOGROTATE[chrony]="/var/log/chrony/*.log:missingok,nocreate,sharedscripts,postrotate,/usr/bin/chronyc cyclelogs > /dev/null 2>&1 || true,endscript"
#LOGROTATE[clamav]="/var/log/clamav/clamd.log,/var/log/clamav/freshclam.log,/var/log/clamav/clamav-milter.log:create 644 clamav clamav,sharedscripts,missingok,notifempty,postrotate,/bin/kill -HUP \`cat /run/clamav/clamd.pid 2>/dev/null\` 2> /dev/null || true,/bin/kill -HUP \`cat /run/clamav/freshclam.pid 2>/dev/null\` 2> /dev/null || true,/bin/kill -HUP \`cat /run/clamav/clamav-milter.pid 2>/dev/null\` 2> /dev/null || true,endscript"
exec_logrotate(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_PATTERN_LOGROTATE_CONF="${ROOTFS}/etc/logrotate.d/ubconfig-"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local LOGROTATE=
declare -A LOGROTATE
[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ -d ${FILE_PATTERN_LOGROTATE_CONF%/*} ]] || mkdir -p ${PATH_LOGROTATE_CONF%/*}
if [[ ${COMMAND} == "set=" ]] && [[ ${#LOGROTATE[@]} != 0 ]]; then
while IFS= read -u3 NAME_FILE; do
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"; FILES_LOG="${FILES_LOG//,/ }"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
TAB_COUNT='\t'
# Вставляем список файлов логов
echo "${FILES_LOG} {" > "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
# Вставляем правила для вращения логов
while IFS= read -r SELECT_RULES_LOG; do
[[ ${SELECT_RULES_LOG} == "endscript" ]] && TAB_COUNT='\t'
echo -e "${TAB_COUNT}${SELECT_RULES_LOG}" >> "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
[[ ${SELECT_RULES_LOG} == "postrotate" ]] && TAB_COUNT='\t\t'
done < <(tr ',' '\n' <<< ${RULES_LOG})
echo "}" >> "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == @("set+="|"set++=") ]] && [[ ${#LOGROTATE[@]} != 0 ]]; then
while IFS= read -u3 NAME_FILE; do
[[ -f ${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE} ]] || return 0
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
[[ ${FILES_LOG} == ${RULES_LOG} ]] && unset RULES_LOG
FILES_LOG="${FILES_LOG//,/ }"
# Вставить в список файлов последним
[[ -n ${FILES_LOG} ]] && ESC_FILES_LOG=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${FILES_LOG}")
[[ -n ${FILES_LOG} ]] && [[ ! $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${FILES_LOG} ]] \
&& sed -E "0,/ \{/s/ \{/ ${ESC_FILES_LOG} \{/" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
# Вставить в список правил последним
[[ -n ${RULES_LOG} ]] && ESC_RULES_LOG=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${RULES_LOG}")
[[ -n ${RULES_LOG} ]] && [[ ! $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${RULES_LOG} ]] \
&& sed -E "/^\}$/i\\\t${ESC_RULES_LOG}" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == @("set-="|"set--=") ]]; then
while IFS= read -u3 NAME_FILE; do
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
[[ ${FILES_LOG} == ${RULES_LOG} ]] && unset RULES_LOG
FILES_LOG="${FILES_LOG//,/ }"
# Если удаляемая часть относится к файлу, то просто вырезать, если к тексту, то удалить строку
[[ -n ${FILES_LOG} ]] && ESC_FILES_LOG=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${FILES_LOG}")
[[ -n ${FILES_LOG} ]] && [[ $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${FILES_LOG} ]] \
&& sed -E "0,/ \{/s/${ESC_FILES_LOG}//" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
[[ -n ${RULES_LOG} ]] && ESC_RULES_LOG=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${RULES_LOG}")
[[ -n ${RULES_LOG} ]] && [[ $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${RULES_LOG} ]] \
&& sed "/${ESC_RULES_LOG}/d" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == "remove" ]]; then
while IFS= read -u3 NAME_FILE; do
[[ -f ${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE} ]] || return 0
rm -f "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
fi
}
# Применить ротцию принудительно на указанный файл
# $1 # Имя переменной с файлом, пример: LOGROTATE[clamav]
exec_logrotate_live(){
[[ -z ${ROOTFS} ]] || return 0
NAME_FILE=$1
[[ ${NAME_FILE%%=*} =~ ^.*'['(.*)']' ]] && NAME_FILE=${BASH_REMATCH[1]}
[[ -n ${NAME_FILE} ]] || return 0
FILE_PATTERN_LOGROTATE_CONF="${ROOTFS}/etc/logrotate.d/ubconfig-"
if [[ $(pgrep -fc "exec_logrotate_live") == 1 ]]; then
sleep 2
logrotate -f "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
while [[ $# -gt 0 ]]; do
declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" \"${1}\"" && shift; }
done
eval ${FUNCTION#*; }
fi

@ -25,7 +25,7 @@ SOURCE=${SYSCONF}/system; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
# TODO: Сделать отработку по параметру загруженному, убрать парсинг # TODO: Сделать отработку по параметру загруженному, убрать парсинг
AUTHPAM_PROFILE=$(grep -h '^AUTHPAM\[' ${ROOTFS}/usr/lib/ublinux/default ${ROOTFS}/etc/ublinux/system | tail -1 | sed -E 's/AUTHPAM\[([a-z]*)\].*/\1/') #' AUTHPAM_PROFILE=$(grep -h '^AUTHPAM\[' ${ROOTFS}/usr/lib/ublinux/default ${ROOTFS}/etc/ublinux/system | tail -1 | sed -E 's/AUTHPAM\[([a-z]*)\].*/\1/') #'
PROFILE_FEATURE=$(tr ',;' " " <<< ${AUTHPAM[${AUTHPAM_PROFILE}]}) PROFILE_FEATURE=$(tr ',;' " " <<< ${AUTHPAM[${AUTHPAM_PROFILE}]})
${CMD_CHROOT} ${ROOTFS}/usr/bin/authselect select ${AUTHPAM_PROFILE} ${PROFILE_FEATURE} --force --nobackup --quiet ${CMD_CHROOT} /usr/bin/authselect select ${AUTHPAM_PROFILE} ${PROFILE_FEATURE} --force --nobackup --quiet
fi fi
# if [[ -n ${AUTHPAM[@]} && ${AUTHPAM[@],,} != "disable" && ${AUTHPAM} != "-" && ${AUTHPAM,} != "no" && ${AUTHPAM,,} != "off" && ${SYSTEMBOOT_STATEMODE,,} =~ ^"sandbox" ]]; then # if [[ -n ${AUTHPAM[@]} && ${AUTHPAM[@],,} != "disable" && ${AUTHPAM} != "-" && ${AUTHPAM,} != "no" && ${AUTHPAM,,} != "off" && ${SYSTEMBOOT_STATEMODE,,} =~ ^"sandbox" ]]; then

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# #
# Initial script for UBLinux # Initial script for UBLinux
# This script are launching before starting init from initrd script # This script are launching before starting init from initrd script
@ -18,18 +18,18 @@ debug_mode "$0" "$@"
SYSCONF="${ROOTFS}/${SYSCONF}" SYSCONF="${ROOTFS}/${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/desktop; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/desktop; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
AUTOLOGINUSER_CMDLINE=$(cmdline_value autologin) && [[ -n ${AUTOLOGINUSER_CMDLINE} ]] && AUTOLOGINUSER=${AUTOLOGINUSER_CMDLINE} AUTOLOGINUSER_CMDLINE=$(cmdline_value autologin) && [[ -n ${AUTOLOGINUSER_CMDLINE} ]] && AUTOLOGINUSER=${AUTOLOGINUSER_CMDLINE}
if [[ -z ${AUTOLOGINUSER} ]]; then if [[ -z ${AUTOLOGINUSER} ]]; then
PASS_ADMUID=$(grep "^$(grep ":${ADMUID}:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):" ${ROOTFS}/etc/shadow | cut -d: -f2) #" #PASS_ADMUID=$(grep "^$(grep ":${ADMUID}:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):" ${ROOTFS}/etc/shadow | cut -d: -f2) #"
#UID_MIN=$(grep "^UID_MIN" ${ROOTFS}/etc/login.defs | cut -d' ' -f2) #UID_MIN=$(grep "^UID_MIN" ${ROOTFS}/etc/login.defs | cut -d' ' -f2)
UID_MIN=$(read -d '' < "${ROOTFS}/etc/login.defs"; [[ "${REPLY}" =~ [^#[^:space:]]*UID_MIN[[:space:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}") #UID_MIN=$(read -d '' < "${ROOTFS}/etc/login.defs"; [[ "${REPLY}" =~ [^#[^:space:]]*UID_MIN[[:space:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
ONLY_ONE_USER=$(awk -F':' -v USER_MIN=${UID_MIN} '$3 > USER_MIN && $1 != "nobody" { print $1}' ${ROOTFS}/etc/passwd) UID_MIN=$([[ $(cat "${ROOTFS}/etc/login.defs") =~ [^#[^:space:]]*UID_MIN[[:space:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
# Если в системе всего один пользователь и пароль пользователя = паролю по умолчанию = паролю по умолчанию рута ublinux, то автологин MORE_ONE_USER=$(awk -F':' -v USER_MIN=${UID_MIN} '$3 > USER_MIN && $1 != "nobody" { print $1}' ${ROOTFS}/etc/passwd)
[[ -z ${ONLY_ONE_USER} && ${PASS_ADMUID} == ${NOSECUREROOTPASSWD} && ${PASS_ADMUID} == ${DEFAULTPASSWD} ]] && AUTOLOGINUSER=yes # Если в системе всего один пользователь и FIRSTSATART, то автологин
[[ -z ${MORE_ONE_USER} && -n ${FIRSTSTART} ]] && AUTOLOGINUSER=yes
fi fi
FILE_LIGHTDM_CONF="${ROOTFS}/etc/lightdm/lightdm.conf" FILE_LIGHTDM_CONF="${ROOTFS}/etc/lightdm/lightdm.conf"
@ -70,8 +70,8 @@ SOURCE=${SYSCONF}/desktop; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
EOF EOF
AUTOLOGIN_IDGROUP=$(grep -i "g\s*autologin\s*[[:digit:]]\s*" ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers | cut -d: -f2 | xargs | cut -d " " -f3 | head -1) AUTOLOGIN_IDGROUP=$(grep -i "g\s*autologin\s*[[:digit:]]\s*" ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers | cut -d: -f2 | xargs | cut -d " " -f3 | head -1)
[[ -n ${AUTOLOGIN_IDGROUP} ]] && ARG_AUTOLOGIN_IDGROUP="-g ${AUTOLOGIN_IDGROUP}" [[ -n ${AUTOLOGIN_IDGROUP} ]] && ARG_AUTOLOGIN_IDGROUP="-g ${AUTOLOGIN_IDGROUP}"
${CMD_CHROOT} ${ROOTFS}/usr/bin/groupadd -f ${ARG_AUTOLOGIN_IDGROUP} autologin >/dev/null 2>&1 ${CMD_CHROOT} /usr/bin/groupadd -f ${ARG_AUTOLOGIN_IDGROUP} autologin >/dev/null 2>&1
${CMD_CHROOT} ${ROOTFS}/usr/bin/gpasswd -M ${AUTOLOGINUSER} autologin >/dev/null 2>&1 ${CMD_CHROOT} /usr/bin/gpasswd -M ${AUTOLOGINUSER} autologin >/dev/null 2>&1
fi fi
fi fi

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# #
# Initial script for UBLinux # Initial script for UBLinux
# This script are launching before starting init from initrd script # This script are launching before starting init from initrd script
@ -26,10 +26,10 @@ SERVICEAPPARMOR="apparmor.service"
mkdir -p proc mkdir -p proc
mount -o rbind /proc proc mount -o rbind /proc proc
if readlink -fq ${ROOTFS}/usr/bin/init | grep -q "lib/systemd/systemd$"; then if readlink -fq ${ROOTFS}/usr/bin/init | grep -q "lib/systemd/systemd$"; then
${CMD_CHROOT} ${ROOTFS}/usr/bin/systemctl unmask ${SERVICEAPPARMOR} ${CMD_CHROOT} /usr/bin/systemctl unmask ${SERVICEAPPARMOR}
${CMD_CHROOT} ${ROOTFS}/usr/bin/systemctl enable ${SERVICEAPPARMOR} || ${CMD_CHROOT} ${ROOTFS}/usr/bin/chkconfig --add ${SERVICEAPPARMOR} ${CMD_CHROOT} /usr/bin/systemctl enable ${SERVICEAPPARMOR} || ${CMD_CHROOT} ${ROOTFS}/usr/bin/chkconfig --add ${SERVICEAPPARMOR}
else else
${CMD_CHROOT} ${ROOTFS}/usr/bin/chkconfig --add ${SERVICEAPPARMOR} ${CMD_CHROOT} /usr/bin/chkconfig --add ${SERVICEAPPARMOR}
fi fi
umount proc umount proc

@ -11,7 +11,7 @@ DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
unset ROOTFS; [[ -d /usr/lib/ublinux ]] || ROOTFS=. 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/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -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" "$@" debug_mode "$0" "$@"
@ -19,43 +19,42 @@ debug_mode "$0" "$@"
SYSCONF="${ROOTFS}${SYSCONF}" SYSCONF="${ROOTFS}${SYSCONF}"
INIGZFILE=$(find /memory -maxdepth 1 -iname "*.ini.gz") INIGZFILE=$(find /memory -maxdepth 1 -iname "*.ini.gz")
[[ -f ${INIGZFILE} ]] || INIGZFILE=$(find ${ROOTFS}/memory -maxdepth 1 -iname "*.ini.gz")
[[ -f ${INIGZFILE} ]] || INIGZFILE=$(find /tmp -maxdepth 1 -iname "*.ini.gz") [[ -f ${INIGZFILE} ]] || INIGZFILE=$(find /tmp -maxdepth 1 -iname "*.ini.gz")
[[ -f ${INIGZFILE} ]] || echo "Config file '*.ini.gz' not found!" [[ -f ${INIGZFILE} ]] || { echo "Config file '*.ini.gz' not found!"; return 1; }
[[ -d ${SYSCONF} ]] || mkdir -p "${SYSCONF}" [[ -d ${SYSCONF} ]] || mkdir -p "${SYSCONF}"
rm -rf ${SYSCONF}/{..?*,.[!.]*,*} 2>/dev/null rm -rf ${SYSCONF}/{..?*,.[!.]*,*} 2>/dev/null
## Парсим файл ublinux.ini.gz и создаём конфигурацию системы в ${SYSCONF} ## Парсим файл ublinux.ini.gz и создаём конфигурацию системы в ${SYSCONF}
FILE_CONFIG="${SYSCONF}/config" FILE_CONFIG="${SYSCONF}/config"
touch ${FILE_CONFIG} [[ -f ${FILE_CONFIG} ]] || install -Dm0644 /dev/null ${FILE_CONFIG}
zcat ${INIGZFILE} | grep -E '^DEFAULTPASSWD|^DEFAULTROOTPASSWD|^NEEDEDUSERS|^USERADD|^GROUPADD' > /tmp/.ublinux_accounts_credential FILE_ROOT_USERS="${SYSCONF}/.users_credential"
[[ -f ${FILE_ROOT_USERS} ]] || install -Dm0600 /dev/null ${FILE_ROOT_USERS}
zcat ${INIGZFILE} | grep -E '^DEFAULTPASSWD|^DEFAULTROOTPASSWD|^NEEDEDUSERS|^USERADD|^GROUPADD' > ${FILE_ROOT_USERS}
while read LINE; do while read LINE; do
if [[ ${LINE} =~ ^'['.*']' ]]; then if [[ ${LINE} =~ ^'['([^[]*|[^]]*)']'[[:space:]]*([0-9]+|[augo]+[=+-]+[augorstwxX,=+-]*)?[[:space:]]*('['+(.*)']'+)?$ ]]; then
FILE_CONFIG=$(tr '[]' '|' <<< "${LINE}" | cut -d'|' -f2) FILE_CONFIG=${BASH_REMATCH[1]}
FILE_CONFIG_MOD=$(tr '[]' '|' <<< "${LINE}" | cut -d'|' -f3 | tr -d ' ') FILE_CONFIG_MOD=${BASH_REMATCH[2]}
PATH_FILE_CONFIG=${FILE_CONFIG%/*} FILE_CONFIG_EXEC=${BASH_REMATCH[4]}
# Если указан файл без пути, то добавить путь по умолчанию ${SYSCONF} # Если указан файл без пути, то добавить путь по умолчанию ${SYSCONF}
[[ ${PATH_FILE_CONFIG} =~ "/" ]] && FILE_CONFIG="${ROOTFS}${FILE_CONFIG}" || FILE_CONFIG="${SYSCONF}/${FILE_CONFIG}" [[ ${FILE_CONFIG} =~ "/" ]] && FILE_CONFIG="${ROOTFS}/${FILE_CONFIG}" || FILE_CONFIG="${SYSCONF}/${FILE_CONFIG}"
if [[ -n ${FILE_CONFIG_MOD} ]]; then if [[ -n ${FILE_CONFIG_MOD} ]]; then
mkdir -p "${PATH_FILE_CONFIG}" [[ -d ${FILE_CONFIG%/*} ]] || install -d "${FILE_CONFIG%/*}"
[[ -e ${FILE_CONFIG} ]] || touch "${FILE_CONFIG}" [[ -e ${FILE_CONFIG} ]] || touch "${FILE_CONFIG}"
chmod "${FILE_CONFIG_MOD}" "${FILE_CONFIG}" chmod "${FILE_CONFIG_MOD}" "${FILE_CONFIG}"
fi fi
elif [[ ${LINE:0:1} == '-' ]]; then elif [[ ${LINE:0:1} == '-' ]]; then
sed -E "/^${LINE:1}$/d" -i "${FILE_CONFIG}" [[ -e ${FILE_CONFIG} ]] && sed -E "/^${LINE:1}$/d" -i "${FILE_CONFIG}"
elif [[ ${LINE:0:1} == '|' ]]; then elif [[ ${LINE:0:1} == '|' ]]; then
echo "${LINE:1}" >> "${FILE_CONFIG}" echo "${LINE:1}" >> "${FILE_CONFIG}"
elif [[ ${LINE:0:1} == '+' ]]; then elif [[ ${LINE:0:1} == '+' ]]; then
ESC_LINE_NEW=$(sed 's/[^a-zA-Z0-9,_@%]/\\&/g' <<< "${LINE:1}") [[ $(cat "${FILE_CONFIG}" 2>/dev/null) =~ ($'\n'|^)+"${LINE:1}"($'\n'|$)+ ]] || echo "${LINE:1}" >> "${FILE_CONFIG}"
grep -Eq "^${ESC_LINE_NEW}$" "${FILE_CONFIG}" || echo "${LINE:1}" >> "${FILE_CONFIG}"
else else
NAME_VAR=$(cut -d= -f1 <<< "${LINE}") NAME_VAR=${LINE%%=*}
[[ -z ${NAME_VAR} ]] && continue [[ ${LINE} != ${NAME_VAR} ]] || continue
ESC_NAME_VAR=$(sed 's/[^a-zA-Z0-9,_@%]/\\&/g' <<< "${NAME_VAR}") [[ -f ${FILE_CONFIG} && $(cat -n ${FILE_CONFIG}) =~ ($'\n'|^)+[[:blank:]]*([[:digit:]]+)[[:blank:]]*"${NAME_VAR}="[^$'\n']*($'\n'|$)+ ]] && sed "${BASH_REMATCH[2]}d" -i "${FILE_CONFIG}"
[[ -f ${FILE_CONFIG} ]] \ echo "${LINE}" >> "${FILE_CONFIG}"
&& grep -Eq "^\s*${ESC_NAME_VAR}=" "${FILE_CONFIG}" 2>/dev/null \
&& sed -E "/^\s*${ESC_NAME_VAR}=/d" -i "${FILE_CONFIG}"
echo "${LINE}" >> "${FILE_CONFIG}"
fi fi
done < <(zcat ${INIGZFILE} | grep -Ev '^DEFAULTPASSWD|^DEFAULTROOTPASSWD|^NEEDEDUSERS|^USERADD|^GROUPADD|^\s*#|^\s*$') done < <(zcat ${INIGZFILE} | grep -Ev '^DEFAULTPASSWD|^DEFAULTROOTPASSWD|^NEEDEDUSERS|^USERADD|^GROUPADD|^\s*#|^\s*$')
@ -64,4 +63,4 @@ SYSCONF="${ROOTFS}${SYSCONF}"
grep -q "^declare -A" "${FILE_CONFIG}" 2>/dev/null && sed "/^declare -A/d" -i "${FILE_CONFIG}" grep -q "^declare -A" "${FILE_CONFIG}" 2>/dev/null && sed "/^declare -A/d" -i "${FILE_CONFIG}"
DECLARE_A=$(grep -E "^[A-z0-9_]*\[.*\]=.*" "${FILE_CONFIG}" | sed -E "s/\[.*//" | sort -u | tr "\n" " ") DECLARE_A=$(grep -E "^[A-z0-9_]*\[.*\]=.*" "${FILE_CONFIG}" | sed -E "s/\[.*//" | sort -u | tr "\n" " ")
[[ -z ${DECLARE_A} ]] || sed "1i declare -A ${DECLARE_A}" -i "${FILE_CONFIG}" [[ -z ${DECLARE_A} ]] || sed "1i declare -A ${DECLARE_A}" -i "${FILE_CONFIG}"
done < <(find ${SYSCONF} -type f -print) done < <(find ${SYSCONF} -type f -print; echo "${FILE_ROOT_USERS}")

@ -11,7 +11,8 @@ DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
[[ -d /usr/lib/ublinux ]] && { unset ROOTFS; unset CMD_CHROOT; } || { ROOTFS='.'; CMD_CHROOT='chroot . '; } 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
debug_mode "$0" "$@" debug_mode "$0" "$@"
# Filter not variable sell symbols from param kernel # Filter not variable sell symbols from param kernel

@ -11,187 +11,622 @@ DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
[[ -d /usr/lib/ublinux ]] && { unset ROOTFS; unset CMD_CHROOT; } || { ROOTFS='.'; CMD_CHROOT='chroot . '; } 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/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -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" "$@" debug_mode "$0" "$@"
SYSCONF="${ROOTFS}${SYSCONF}" SYSCONF="${ROOTFS}${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/system; [[ -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_PASSWD="${ROOTFS}/etc/passwd"
FILE_SHADOW="${ROOTFS}/etc/shadow" FILE_SHADOW="${ROOTFS}/etc/shadow"
FILE_GROUP="${ROOTFS}/etc/group" FILE_GROUP="${ROOTFS}/etc/group"
FILE_GSHADOW="${ROOTFS}/etc/gshadow" FILE_GSHADOW="${ROOTFS}/etc/gshadow"
FILE_ACCOUNTS_CREDENTIAL="/tmp/.ublinux_accounts_credential" PATH_HOME="/home"
# https://en.wikipedia.org/wiki/Crypt_(C) # Задать пароль пользователю
# https://man.archlinux.org/man/core/libxcrypt/crypt.5.en # /etc/shadow file format # $1 # Имя пользователя
# user:$6$.n.:17736:0:99999:7::: # $2 # Зашифрованный пароля, если не указан, то пароль '!*' запрет авторизации
# [--] [----] [---] - [---] ----
# | | | | | |||+-----------> 9. Неиспользованный
# | | | | | ||+------------> 8. Срок годности
# | | | | | |+-------------> 7. Период бездействия
# | | | | | +--------------> 6. Период предупреждения
# | | | | +------------------> 5. Максимальный возраст пароля
# | | | +----------------------> 4. Минимальный возраст пароля
# | | +--------------------------> 3. Последнее изменение пароля
# | +---------------------------------> 2. Зашифрованный пароль
# +----------------------------------------> 1. Имя пользователя
# Если поле пароля содержит первый символ звездочку (*), то пользователь не сможет войти по паролю, но сможет другим способом (например по ключу через ssh)
# Если поле пароля содержит первый символ восклицательный знак (!), то пользователь вообще не сможет войти, даже по ключу
# Алгоритмы хеширования пароля:
# (empty) # DES
# $_$ # BSDi
# $1$ # MD5
# $2$ # bcrypt based on Blowfish
# $2a$ # Blowfish
# $2b$ # OpenBSD blowfish
# $2x$ # blowfish
# $2y$ # Eksblowfish
# $3$ # NTHASH
# $5$ # SHA-256
# $6$ # SHA-512
# $7$ # scrypt
# $md5$ # Solaris MD5
# $sha1$ # PBKDF1 with SHA1
# $gy$ # gost-yescrypt
# $y$ # yescrypt
# $argon2d$ # Argon2d
# $argon2i$ # Argon2i
# $argon2ds$ # Argon2ds
# $argon2id$ # Argon2id
set_passwd(){ set_passwd(){
USER_NAME="${1}" USER_NAME="${1}"
USER_PASS="${2}" USER_PASS="${2}"
[[ -n ${USER_NAME} ]] || return 1 [[ ${USER_NAME} != "" ]] || return 1
[[ -n ${USER_PASS} ]] || USER_PASS="x" [[ ${USER_PASS} != "" ]] || USER_PASS='!*'
ESC_USER_PASS=$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${USER_PASS}") if [[ -x ${ROOTFS}/usr/bin/chpasswd ]]; then
EPOCH_DAY=$(( $(date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day echo "${USER_NAME}:${USER_PASS}" | ${CMD_CHROOT} /usr/bin/chpasswd --encrypted
USER_FROM_SHADOW=$(grep "^${USER_NAME}:" "${FILE_SHADOW}") else
if [[ -z ${USER_FROM_SHADOW} ]]; then ESC_USER_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${USER_PASS}")
echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" EPOCH_DAY=$(( $(date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day
elif [[ ! ${USER_FROM_SHADOW} =~ ^"${USER_NAME}:${USER_PASS}:" ]]; then USER_FROM_SHADOW=$(grep "^${USER_NAME}:" "${FILE_SHADOW}")
sed -E "s/^${USER_NAME}:[^:]+:[0-9]+:/${USER_NAME}:${ESC_USER_PASS}:${EPOCH_DAY}:/" -i "${FILE_SHADOW}" if [[ -z ${USER_FROM_SHADOW} ]]; then
sed -E "s/${USER_NAME}:[!]*:/${USER_NAME}:\!\*:/" -i "${FILE_SHADOW}" echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}"
#sed /^${USER_NAME}:/d -i "${FILE_SHADOW}" elif [[ ! ${USER_FROM_SHADOW} =~ ^"${USER_NAME}:${USER_PASS}:" ]]; then
#echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" sed -E "s/^${USER_NAME}:[^:]+:[0-9]+:/${USER_NAME}:${ESC_USER_PASS}:${EPOCH_DAY}:/" -i "${FILE_SHADOW}"
fi 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}"
copy_skel_home(){ fi
local SELECT_USERNAME="${1}" fi
[[ -n ${SELECT_USERNAME} ]] || return 1
cp -af ${ROOTFS}/etc/skel ${ROOTFS}/home/"${SELECT_USERNAME}"
#rsync -rlpt --ignore-existing etc/skel/ home/"${SELECT_USERNAME}"
${CMD_CHROOT} ${ROOTFS}/usr/bin/chown -R "${SELECT_USERNAME}":"${SELECT_USERNAME}" ${ROOTFS}/home/"${SELECT_USERNAME}"
${CMD_CHROOT} ${ROOTFS}/usr/bin/chmod -fR u+rw,g-rwx,o-rwx ${ROOTFS}/home/"${SELECT_USERNAME}"/
${CMD_CHROOT} ${ROOTFS}/usr/bin/chmod -f 700 ${ROOTFS}/home/"${SELECT_USERNAME}"
} }
exec_get_users(){ # Задать пароль группе
if [[ -f ${FILE_ACCOUNTS_CREDENTIAL} ]]; then # $1 # Имя группы
GET_DEFAULTPASSWD=$(grep "DEFAULTPASSWD=" "${FILE_ACCOUNTS_CREDENTIAL}" | tail -1 | tr -d "\'\"") # $2 # Зашифрованный пароля, если не указан, то пароль '!*' запрет авторизации
[[ -n ${GET_DEFAULTPASSWD} ]] && DEFAULTPASSWD=${GET_DEFAULTPASSWD#*=} #set_gpasswd(){
GET_DEFAULTROOTPASSWD=$(grep "DEFAULTROOTPASSWD=" "${FILE_ACCOUNTS_CREDENTIAL}" | tail -1 | tr -d "\'\"") # GROUP_NAME="${1}"
[[ -n ${GET_DEFAULTROOTPASSWD} ]] && DEFAULTROOTPASSWD=${GET_DEFAULTROOTPASSWD#*=} # GROUP_PASS="${2}"
GET_NEEDEDUSERS=$(grep "NEEDEDUSERS=" "${FILE_ACCOUNTS_CREDENTIAL}" | tail -1 | tr -d "\'\"") # [[ ${GROUP_NAME} != "" ]] || return 1
[[ -n ${GET_NEEDEDUSERS} ]] && NEEDEDUSERS=${GET_NEEDEDUSERS#*=} # [[ ${GROUP_PASS} != "" ]] || GROUP_PASS="!*"
rm -f "${FILE_ACCOUNTS_CREDENTIAL}" # if [[ -x ${ROOTFS}/usr/bin/chgpasswd ]]; then
fi # echo "${GROUP_NAME}:${GROUP_PASS}" | ${CMD_CHROOT} /usr/bin/chgpasswd --encrypted
[[ -z ${NEEDEDUSERS} ]] && NEEDEDUSERS="${DEFAULTUSER}:${ADMUID}:${DEFAULTPASSWD}:Администратор" # else
[[ -z $(cmdline_value users) ]] || NEEDEDUSERS=$(cmdline_value users) # ESC_GROUP_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${GROUP_PASS}")
[[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes # 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}"
} }
exec_add_groups(){
# Создаём группы из ${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS} c ID из /usr/share/ublinux-sysusers/*.sysusers # Создаём группы из ${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS} c ID из /usr/share/ublinux-sysusers/*.sysusers
while read SELECT_GROUP; do exec_01_add_groups(){
FINDGROUP=$(grep -i "g\s*${SELECT_GROUP}\s*[[:digit:]]\s*" ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers 2>/dev/null | xargs) #echo "exec_01_add_groups"
IFS=" " read -r NULL FINDGROUP_NAME FINDGROUP_ID NULL <<< "${FINDGROUP}" [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
if [[ -n ${FINDGROUP} ]]; then [[ -n ${COMMAND} ]] || COMMAND="set="
if grep -q "^${SELECT_GROUP}:.*:${FINDGROUP_ID}:" ${FILE_GROUP} 2>/dev/null; then 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%*,}
#echo "==>::${GROUPADD_GROUPS}::"
[[ -n ${GROUPADD_GROUPS} ]] && while IFS= read -u3 SELECT_GROUP; do
unset ARG_FINDGROUP_ID
# FINDGROUP=$(grep -i "g\s*${SELECT_GROUP}\s*[[:digit:]]\s*" ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers 2>/dev/null | xargs)
# IFS=" " read -r NULL FINDGROUP_NAME FINDGROUP_ID NULL <<< "${FINDGROUP}"
# if [[ -n ${FINDGROUP} ]]; then
# if grep -q "^${SELECT_GROUP}:.*:${FINDGROUP_ID}:" ${FILE_GROUP} 2>/dev/null; then
# # Группа найдена, имя и id совпадают, пропускаем добавление
# continue
# elif grep -q "^${SELECT_GROUP}:" ${FILE_GROUP} 2>/dev/null; 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}'"
#echo ${CMD_CHROOT} /usr/bin/groupdel -f ${SELECT_GROUP}
# ${CMD_CHROOT} /usr/bin/groupdel -f ${SELECT_GROUP}
# fi
# fi
# [[ ${FINDGROUP_ID} == "" ]] || [[ ${FINDGROUP_ID} == "-" ]] || FINDGROUP_ID="--gid ${FINDGROUP_ID}"
#echo ${CMD_CHROOT} /usr/bin/groupadd --force ${FINDGROUP_ID} ${SELECT_GROUP}
## ${CMD_CHROOT} /usr/bin/groupadd --force ${FINDGROUP_ID} ${SELECT_GROUP}
[[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID=
#[[ $(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 совпадают, пропускаем добавление # Группа найдена, имя и id совпадают, пропускаем добавление
continue continue
elif grep -q "^${SELECT_GROUP}:" ${FILE_GROUP} 2>/dev/null; then elif [[ ${FINDGROUP_ID} != "" && $(cat ${FILE_GROUP} 2>/dev/null) =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*($'\n'|$)+ ]]; then
# Группа найдена, имя и id несовпадают, удаляем группу # Группа найдена, имя и 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}'" 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} ${ROOTFS}/usr/bin/groupdel -f ${SELECT_GROUP} ${CMD_CHROOT} /usr/bin/groupdel -f ${SELECT_GROUP}
fi fi
fi [[ ${FINDGROUP_ID} == @(""|"-") ]] || ARG_FINDGROUP_ID="--gid ${FINDGROUP_ID}"
[[ ${FINDGROUP_ID} == "" ]] || [[ ${FINDGROUP_ID} == "-" ]] || FINDGROUP_ID="-g ${FINDGROUP_ID}" ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_FINDGROUP_ID} ${SELECT_GROUP}
${CMD_CHROOT} ${ROOTFS}/usr/bin/groupadd -f ${FINDGROUP_ID} ${SELECT_GROUP} done 3<<< "${GROUPADD_GROUPS//,/$'\n'}"
done < <(tr ",;" "\n" <<< "${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS}") fi
} }
exec_neededusers(){ # Задаём пароль root пользователю
while read SELECT_USER; do exec_02_defaultrootpasswd(){
IFS=: read -r SELECT_USERNAME SELECT_UID SELECT_PASS SELECT_GECOS NULL <<< "${SELECT_USER}" #echo "exec_02_defaultrootpasswd"
[[ ${SELECT_PASS} == "x" ]] && SELECT_PASS="${DEFAULTPASSWD}" [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
ADDGROUPS="${USERGROUPS}" [[ -n ${COMMAND} ]] || COMMAND="set="
[[ ${SELECT_UID} == ${ADMUID} && ${ADDADM} == "yes" ]] && ADDGROUPS="${USERGROUPS},${ADMGROUPS}" local PARAM="$@"
# Создаём пользователя if [[ -n ${PARAM} ]]; then
if ! grep -q ^"${SELECT_USERNAME}": ${FILE_PASSWD} 2>/dev/null; then [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
[[ -n ${SELECT_UID} ]] && ARG_SELECT_UID="-u ${SELECT_UID}" || unset ARG_SELECT_UID fi
[[ -n ${DEFAULTGROUP} ]] && ARG_DEFAULTGROUP="-G ${DEFAULTGROUP}" || unset ARG_DEFAULTGROUP # Удалить параметр из локальной конфигурации
if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then [[ -z ${ROOTFS} && -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users"
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-c ${SELECT_GECOS}" || unset ARG_SELECT_GECOS if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${DEFAULTROOTPASSWD} && ! ${DEFAULTROOTPASSWD,,} == @(no|none|disable) ]]; then
${CMD_CHROOT} ${ROOTFS}/usr/bin/useradd -M ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME} #>/dev/null 2>&1 [[ -n ${DEFAULTROOTPASSWD} ]] && DEFAULTROOTPASSWD=$(return_hash_password hash ${HASHPASSWD} ${DEFAULTROOTPASSWD})
elif [[ -x ${ROOTFS}/usr/bin/adduser ]]; then set_passwd root "${DEFAULTROOTPASSWD}"
[[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g ${SELECT_GECOS}" || unset ARG_SELECT_GECOS fi
${CMD_CHROOT} ${ROOTFS}/usr/bin/adduser -D -H "${ARG_DEFAULTGROUP}" "${ARG_SELECT_UID}" "${ARG_SELECT_GECOS}" "${SELECT_USERNAME}" >/dev/null 2>&1 }
# Создаем пользователей из ${NEEDEDUSERS} и добавляем в группы
# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 Для команды set=|set+=|set++= параметр со значением, пример:
# Для команды set-=|set--=|remove параметр только с именем, пример:
# null Если отсутствует $@, то применяем из системной конфигурации
exec_03_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
# Удалить параметр из локальной конфигурации
[[ -z ${ROOTFS} && -f "${SYSCONF}/users" ]] && sed "/NEEDEDUSERS=/d" -i "${SYSCONF}/users"
if [[ -n ${NEEDEDUSERS} ]]; then
while IFS= read -ru3 SELECT_USER; do
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 fi
fi # Создаём пользователя
# Добавляем пользователя в группу if ! grep -q ^"${SELECT_USERNAME}": ${FILE_PASSWD} 2>/dev/null; then
USER_GROUPS="${ADDGROUPS//;/,}" [[ -n ${SELECT_UID} ]] && ARG_SELECT_UID="-u ${SELECT_UID}" || unset ARG_SELECT_UID
${CMD_CHROOT} ${ROOTFS}/usr/bin/usermod -a -G ${USER_GROUPS%*,} ${SELECT_USERNAME} #>/dev/null 2>&1 if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then
# Задаём пароль пользователю [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-c ${SELECT_GECOS}" || unset ARG_SELECT_GECOS
set_passwd "${SELECT_USERNAME}" "${SELECT_PASS}" [[ -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
if [[ ! -d ${ROOTFS}/home/"${SELECT_USERNAME}" ]]; then elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then
copy_skel_home "${SELECT_USERNAME}" # busybox adduser
elif [[ ${UPDATEHOME,,} == @(yes|y|enable) ]]; then [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g ${SELECT_GECOS}" || unset ARG_SELECT_GECOS
copy_skel_home "${SELECT_USERNAME}" [[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}"
fi ${CMD_CHROOT} /usr/bin/busybox adduser -D -H "${ARG_DEFAULTGROUP}" "${ARG_SELECT_UID}" "${ARG_SELECT_GECOS}" "${SELECT_USERNAME}" #>/dev/null 2>&1
done < <(tr ",;" "\n" <<< "${NEEDEDUSERS}") 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
} }
exec_set_root_pass(){ #declare -A UPDATEHOME
if [[ -n ${DEFAULTROOTPASSWD} && ! ${DEFAULTROOTPASSWD} =~ @(no|none|disable) ]]; then #UPDATEHOME[user-4]=yes
set_passwd root "${DEFAULTROOTPASSWD}" #declare -A USERADD_SYNC
#USERADD_SYNC[user-4]="shutdown,boot"
#USERADD_SYNC="shutdown,boot"
#declare -A USERADD
#USERADD[superadmin]='Администратор:1000:x:x:x:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
#USERADD[user-1]='Пользователь-1:x:x:vboxusers,libvirt:-s /usr/bin/bash -o:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
#USERADD[user-2]='Пользователь-2::users:vboxusers,libvirt:-s /usr/bin/bash -o:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
#USERADD[user-3]=':::::x'
#USERADD[user-4]='Пользователь-4::users:user-2,user-3:-s /usr/bin/sh:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60'
#declare -A USERSHADOW
#USERSHADOW[user-4]=19695:0:99999:7::
#USERSHADOW[user-4]=18000:0:120:7:14:
#USERSHADOW[user-4]="2023-12-31:0:120:7:14:2024-12-31"
# Добавить пользователя системы в /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_04_useradd(){
#echo "exec_04_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
[[ ${#USERADD[@]} == 0 ]] && USERADD[${DEFAULTUSER}]="Administrator:${ADMUID}:x:x:x:${DEFAULTPASSWD}"
# Если в 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))
# Удалить параметр из локальной конфигурации
[[ -z ${ROOTFS} && -f "${SYSCONF}/users" ]] && sed "/USERADD\[.*\]=/d" -i "${SYSCONF}/users"
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERADD[@]} != 0 ]]; then
exec_06_groupadd
[[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes
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}]}"
[[ ${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} == "" ]] || exec_01_add_groups "${SELECT_EXTRAGROUPS}"
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}"
# Если указана обязательная синхронизация при каждом запуске, то пользователя удалить и создать нового
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
# Проверяем наличие пользователя в системе
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} ]] && ARG_SELECT_UID="--uid ${SELECT_UID}" || unset ARG_SELECT_UID
# Если указана основная группа, но она не создана, то создать
unset ARG_GROUPADD_GID ARG_GROUPADD_GROUPNAME
# Если группа не найдена
if [[ -n ${SELECT_GROUP} && ! $(cat ${FILE_GROUP}) =~ ($'\n'|^)+(${SELECT_GROUP}:|[^$'\n']*:${SELECT_GROUP}:) ]]; then
# Группа имет цифровой 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_06_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} =~ ("-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
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_05_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
done 3< <(printf "%s\n" "${!USERADD[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
SELECT_USERNAME=${BASH_REMATCH[1]}
${CMD_CHROOT} /usr/bin/userdel --force ${SELECT_USERNAME}
fi
fi fi
} }
exec_firststart(){ # Параметры пользователя системы /etc/shadow. Если пользователь существует, то без изменений
# Autodetect firststart # $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# Если пароли по умолчанию, то firststart # $2 Для команды set=|set+=|set++= параметр со значением, пример: USERSHADOW[superadmin]=2023-01-01:0:99999:7::2025-01-01
if ! grep -q "^FIRSTSTART$" ${SYSCONF}/config 2>/dev/null; then # Для команды set-=|set--=|remove параметр только с именем, пример: USERSHADOW[superadmin]
grep -q "^root:${DEFAULTROOTPASSWD}:" ${ROOTFS}/etc/shadow \ # null Если отсутствует $@, то применяем из системной конфигурации USERSHADOW[*]
&& grep -q "^$(grep ".*:x:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):${DEFAULTPASSWD}:" ${ROOTFS}/etc/shadow \
&& echo "FIRSTSTART=yes" >> ${SYSCONF}/config ## 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_05_usershadow(){
#echo "exec_05_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
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]}
${CMD_CHROOT} /usr/bin/chage --mindays 0 --maxdays 99999 --warndays 7 --inactive -1 --expiredate -1 ${SELECT_USERNAME}
fi
fi fi
} }
exec_verify_passwd(){ # Функция добавление/удаление групп в систему. Если группа существует, то изменить под параметры
if [[ -x ${ROOTFS}/usr/bin/pwck ]]; then # $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
#yes | ${ROOTFS}/usr/bin/pwck --root ${PWD} > /dev/null # $2 Для команды set=|set+=|set++= параметр со значением, пример: GROUPADD[g_department_1]=ob.ivanov,rv.smirnov
${ROOTFS}/usr/bin/pwck -s --root ${PWD} # Для команды 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_06_groupadd(){
#echo "exec_06_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 fi
if [[ -x ${ROOTFS}/usr/bin/grpck ]]; then # Удалить параметр из локальной конфигурации
#yes | ${ROOTFS}/usr/bin/grpck --root ${PWD} > /dev/null [[ -z ${ROOTFS} && -f "${SYSCONF}/users" ]] && sed "/GROUPADD\[.*\]/d" -i "${SYSCONF}/users"
${ROOTFS}/usr/bin/grpck -s --root ${PWD} if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#GROUPADD[@]} != 0 ]]; then
while IFS= read -ru3 SELECT_GROUP; do
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})
# Поиск имени и GID в шаблонах пользователей/групп 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
[[ -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
# Создаём группу, если создана то изменяем под установленные параметры
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}
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") ]] && 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
done 3< <(printf "%s\n" "${!GROUPADD[@]}")
# Выполнить отдельно только если указан параметр функции
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
SELECT_GROUP=${BASH_REMATCH[1]}
${CMD_CHROOT} /usr/bin/groupdel --force ${SELECT_GROUP}
fi
fi
}
# Autodetect firststart
# Если пароли по умолчанию, то firststart
exec_99_firststart(){
#echo "exec_99_firststart"
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 fi
} }
################ ################
##### MAIN ##### ##### MAIN #####
################ ################
exec_get_users # Если файл подключен как ресурс с функциями, то выйти
exec_add_groups return 0 2>/dev/null && return 0
exec_neededusers $@ #rm -f "${FILE_ROOT_USERS}"
exec_set_root_pass if [[ -z $@ ]]; then
exec_firststart while read -ru3 FUNCTION; do
exec_verify_passwd $"${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

@ -186,7 +186,7 @@ SERVICES_ENABLE=dbus-broker,NetworkManager,sshd,systemd-swap,cups,cockpit.socket
## You can cpecify users there whithout using "user=" boot parameter ## You can cpecify users there whithout using "user=" boot parameter
## Пользователи системы (аналог параметра users) ## Пользователи системы (аналог параметра users)
## NEEDEDUSERS='name_user:id:password:show_name:, ... ' password=x=$DEFAULTPASSWD ## NEEDEDUSERS='name_user:id:password:show_name:, ... ' password=x=$DEFAULTPASSWD
NEEDEDUSERS='superadmin:1000:x:Администратор' #NEEDEDUSERS='superadmin:1000:x:Администратор'
## Добавить пользователя системы в /etc/passwd. Если пользователь существует, то без изменений ## Добавить пользователя системы в /etc/passwd. Если пользователь существует, то без изменений
## USERADD=no|none|disable # Отключить управление прользователями конфигурации ## USERADD=no|none|disable # Отключить управление прользователями конфигурации
@ -269,8 +269,88 @@ NEEDEDUSERS='superadmin:1000:x:Администратор'
## no # Не выполнять действие ## no # Не выполнять действие
[/etc/ublinux/update] [/etc/ublinux/update]
## Настройка обновления системы ## Настройка репозиториев и обновления системы
################################################################################ ################################################################################
## Настройка подключения репозиториев
## REPOSITORY[<name_repo>]=disable | <siglevel>:<usage>:<server_path_1>,<server_path_2>,...,<server_path_n>
## <name_repo> # Произвольное имя репозитория. Обязательный
## disable # Отключить отдин из репозиториев по умолчанию: core,extra,community,multilib,ublinux,modules
## <siglevel> # Уровень проверки подписи репозитория, можно выбрать одну из основных и вторую из дополнительных, разделитель запятая. Не обязательный
## # Последовательность имеет значение, т.к. накладываются правила каскадно. По умолчанию: Required,DatabaseOptional
## Never # Проверка подписи выполняться не будет. Основная
## PackageNever # Только для пакетов. Дополнительная
## DatabaseNever # Только для базы данных. Дополнительная
## Optional # Подписи будут проверяться при их наличии, но неподписанные базы данных и пакеты также будут приниматься. Основная
## PackageOptional # Только для пакетов. Дополнительная
## *DatabaseOptional # Только для базы данных. Дополнительная
## *Required # Подписи будут необходимы для всех пакетов и баз данных. Основная
## PackageRequired # Только для пакетов. Дополнительная
## DatabaseRequired # Только для базы данных. Дополнительная
## TrustedOnly # Если подпись проверяется для пакетов и базы, она должна находиться в связке ключей и быть полностью доверенной; маргинальное доверие не применимо
## PackageTrustedOnly # Если подпись проверяется только для пакетов
## DatabaseTrustedOnly # Если подпись проверяется только для базы данных
## TrustAll # Если подпись проверена, она должна находиться в связке ключей, но ей не требуется назначать уровень доверия (например, неизвестное или предельное доверие)
## PackageTrustAll # Если подпись проверена только для пакетов
## DatabaseTrustAll # Если подпись проверена только для базы данных
## <usage> # Уровень использования этого репозитория. Не обязательный
## *All # Включать все перечисленные функции для репозитория. Это значение по умолчанию
## Sync # Включать обновления для этого репозитория
## Search # Включать поиск этого репозитория
## Install # Включать установку пакетов из этого репозитория во время операции --sync
## Upgrade # Позволить этому репозиторию быть действительным источником пакетов при выполнении --sysupgrade
## <server_path_n> # Полный URL-адрес места, где можно найти базу данных, пакеты и подписи (если доступны) для этого репозитория. Обязательный
## # Возможно указать несколько, через запятую.
## <file> # Если указан доступный файл, то подключить как дополнительный файл расширения конфигурации
## file:// # URL префикс для репозитория в каталоге
## ftp:// # URL префикс для репозитория FTP
## http:// # URL префикс для репозитория HTTP
## https:// # URL префикс для репозитория HTTPS
## REPOSITORY[modules]=::http://192.168.0.1:8080/repo/2204
## REPOSITORY[webmyrepo]=never::http://myweb.org/myrepo
## REPOSITORY[localmyrepo]=never::file:///home/myrepo
## Опубликовать локальный репозиторий в локальной сети, подключиться к сети распределённых репозиториев.
## При установке пакета пакет ищется в распределённой сети репозиториев и устанавливается самой последней доступной версией.
## REPOPUBLIC_NET=<name_repos_1>,...,<name_repos_n>
## <name_repo> # Подключенное имя репозитория, например: core,extra,community,multilib,ublinux,modules
## all # Если name_repo=all, то опубликовать все подключенные репозитории
## REPOPUBLIC_NET=all
## REPOPUBLIC_NET=modules
## Опубликовать локальный репозиторий в виде локального WEB ресурса
## REPOPUBLIC_WEB[<path>]=enable|disable,listing:<port>:<auth_name>:<auth_pass>:<auth_hash>
## <path> # Путь до каталога репозитория, который будет опубликован
## enable # Включить публикацию
## disable # Выключить публикацию
## listing # Включить WEB обозреватель файлов. Не обязятельный
## <port> # Порт по которому доступен репозиторий. По умолчанию: 8080. Не обязательный
## <auth_name> # Параметры авторизации, имя пользователя. Не обязательный
## <auth_pass> # Параметры авторизации, открытый пароль или тип хеша. Не обязательный
## password # Не зашифрованный пароль
## sha256 # Использовать зашифрованный пароль SHA256
## sha512 # Использовать зашифрованный пароль SHA512
## <auth_hash> # Параметры авторизации, зашифроваггый пароль SHA256 или SHA512. Не обязательный
## REPOPUBLIC_WEB[/home/myrepo]=enable
## Опубликовать ленивое зеркало подключенных репозиториев в виде локального WEB ресурса.
## Получая запрос от пользователя, загружает с удалённого репозитория пакет и сохраняет в кеше передавая его пользователю.
## REPOPUBLIC_CACHE[<path>]=enable|disable:<port>:<server_name_1>@<server_url_1>,...,<server_name_n>@<server_url_n>
## <path> # Путь до каталога файлов кеша, если не указан, то по умолчанию: /mnt/livedata/ublinux-data/repopublic_cache
## enable # Включить публикацию
## disable # Выключить публикацию
## <port> # Порт по которому доступен репозиторий. По умолчанию: 8080. Не обязательный
##
## <server_name> # Произвольное имя репозитория
## <server_url> # Полный адрес репозитория URL или файл
## # Если не указано <server_name>@<server_url>, то по умолчанию системные /etc/pacman.d/mirrorlist
## # Возможно указать несколько, через запятую.
## <file> # Файл списка зеркал, подключается как список зеркал с синтаксисом /etc/pacman.d/mirrorlist
## # Важно: в подключенном списке не должно быть адреса текущего сервера
## http:// # URL префикс для репозитория на HTTP
## https:// # URL префикс для репозитория на HTTPS
## REPOPUBLIC_CACHE[/mnt/livedata/ublinux-data/repopublic_cache]=enable
## REPOPUBLIC_CACHE[/mnt/livedata/ublinux-data/repopublic_cache]=enable:80:myrepo@http://192.168.0.1:8080/repo/2204
## Автообновление системы ## Автообновление системы
## UBLINUXUPDATE= ## UBLINUXUPDATE=
## =auto # автоматически ## =auto # автоматически
@ -524,6 +604,12 @@ GRUB_BOOT_SILENT="splash"
#SERVER_DOMAIN[type]=samba #SERVER_DOMAIN[type]=samba
#SERVER_DOMAIN[admin]=administrator:0J3QvtCy0YvQuV/QlNC10L3RjCEK #SERVER_DOMAIN[admin]=administrator:0J3QvtCy0YvQuV/QlNC10L3RjCEK
#TODO: Переоценить необходимость
## Адрес сервера ublinux-server по умолчанию
#UBLINUXSERVER=192.168.1.31
## Адрес сети по умолчанию
#NETWORKIP=192.168.1.
[/etc/ublinux/save] [/etc/ublinux/save]
## Настройка сохранений ## Настройка сохранений
################################################################################ ################################################################################
@ -662,14 +748,6 @@ GRUB_BOOT_SILENT="splash"
## NETWORK[Проводное соединение 2@connmod]="802-3-ethernet.cloned-mac-address 00:22:22:22:22:22" ## NETWORK[Проводное соединение 2@connmod]="802-3-ethernet.cloned-mac-address 00:22:22:22:22:22"
## NETWORK[wlan0@connmod]="wifi.cloned-mac-address 70:70:70:70:70:70" ## NETWORK[wlan0@connmod]="wifi.cloned-mac-address 70:70:70:70:70:70"
## ublinux-server ip addres
## Адрес сервера по умолчанию
#UBLINUXSERVER=192.168.1.31
## Local network base address
## Адрес сети по умолчанию
#NETWORKIP=192.168.1.
## Switch on ipv6 at start on all interfaces ## Switch on ipv6 at start on all interfaces
## Включение ipv6 по умолчанию на всех интерфейсах ## Включение ipv6 по умолчанию на всех интерфейсах
IPV6=no IPV6=no
@ -736,13 +814,6 @@ NSSWITCHWINBIND=yes
## Должна быть включена служба tor! ## Должна быть включена служба tor!
#TORUSERS=500-999 #TORUSERS=500-999
## Автоматически менять MAC адрес интерфейса при подключении
#MACCHANGE=wlan0
## По умолчанию используется алгоритм -e не меняющей тип и производителя
#MACCHANGEROPTIONS='-a'
## Можно назначить конкретный адрес для интерфейса
#MACCHANGEROPTIONS='--mac=XX:XX:XX:XX:XX:XX'
[/etc/ublinux/security] [/etc/ublinux/security]
## Настройка безопасности, ограничений ## Настройка безопасности, ограничений
################################################################################ ################################################################################
@ -833,16 +904,16 @@ NSSWITCHWINBIND=yes
## Отключить пользовательские nosuid nodev noexec на смонтированные цели ## Отключить пользовательские nosuid nodev noexec на смонтированные цели
## MOUNT_ATTR[<source_1>,<source_n>]=<attribut_1>,<attribut_n> ## MOUNT_ATTR[<source_1>,<source_n>]=<attribut_1>,<attribut_n>
## Source: ## <source>:
## LABEL=<label> # specifies device by filesystem label ## <label> # specifies device by filesystem LABEL=label
## UUID=<uuid> # specifies device by filesystem UUID ## <uuid> # specifies device by filesystem UUID=uuid
## PARTLABEL=<label> # specifies device by partition label ## <partlabel> # specifies device by partition PARTLABEL=partlabel
## PARTUUID=<uuid> # specifies device by partition UUID ## <partuuid> # specifies device by partition PARTUUID=partuuid
## ID=<id> # specifies device by udev hardware ID ## <id> # specifies device by udev hardware ID=id
## <device> # specifies device by path ## <device> # specifies device by path
## <directory> # mountpoint for bind mounts (see --bind/rbind) ## <directory> # mountpoint for bind mounts (see --bind/rbind)
## <file> # regular file for loopdev setup ## <file> # regular file for loopdev setup
## Attributs: # Разделённые: , или ; ## <attributs>: # Разделение , или ;
## nosuid # Block the operation of suid, and sgid bits. | Блокировать работу suid и sgid бит. ## nosuid # Block the operation of suid, and sgid bits. | Блокировать работу suid и sgid бит.
## nodev # Don't interpret block special devices on the filesystem. | Не интерпретируйте блокировку специальных устройств в файловой системе. ## nodev # Don't interpret block special devices on the filesystem. | Не интерпретируйте блокировку специальных устройств в файловой системе.
## noexec # Don't allow the execution of executable binaries | Не позволить выполнять исполняемые двоичные файлы ## noexec # Don't allow the execution of executable binaries | Не позволить выполнять исполняемые двоичные файлы

Loading…
Cancel
Save