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

1725 lines
105 KiB

This file contains ambiguous Unicode characters!

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

#!/usr/bin/env bash
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#
[[ -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="${ROOTFS}/usr/share/locale"
export TEXTDOMAIN="ublinux_functions"
ere_quote_grep() {
# Что экранировать
sed 's/[][\.|$(){}?+*^]/\\&/g' <<< "$*"
# Что не экранировать
#sed 's/[^a-zA-Z0-9=",;/_@#%&<> -]/\\&/g' <<< "$*"
}
ere_quote_sed() {
# Что экранировать
sed 's/[][\.|$(){}!?+*^;/]/\\&/g' <<< "$*"
# Что не экранировать
#sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "$*"
}
# https://en.wikipedia.org/wiki/Crypt_(C)
# https://man.archlinux.org/man/core/libxcrypt/crypt.5.en # /etc/shadow file format
# user:$6$.n.:17736:0:99999:7:::
# [--] [----] [---] - [---] ----
# | | | | | |||+-----------> 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
# Получить хеш пароля, тип хеша
# $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 # Пароль пользователя шифрованный или не шифрованный. Если шифрованный, то вернётся как есть
# Применяется в ubconfig
return_hash_password(){
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
DEFAULT_HASHPASSWD="yescrypt"
[[ $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="${DEFAULT_HASHPASSWD}"
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=${BASH_REMATCH[1]} && HASH_PASSWORD=${ARG_PASSWORD} || ARG_MODE='hash'
[[ ${ARG_PASSWORD} =~ ^'!*'(.*) ]] && ARG_PASSWORD=${BASH_REMATCH[1]} && HASH_PASSWORD=${ARG_PASSWORD} && BLOCK_PASSWORD="!*"
[[ ${ARG_PASSWORD} =~ ^[!]+(.*) ]] && ARG_PASSWORD=${BASH_REMATCH[1]} && HASH_PASSWORD=${ARG_PASSWORD} && BLOCK_PASSWORD="!"
[[ ${ARG_PASSWORD} =~ ^[*]+(.*) ]] && ARG_PASSWORD=${BASH_REMATCH[1]} && HASH_PASSWORD=${ARG_PASSWORD} && BLOCK_PASSWORD="*"
if [[ ${ARG_PASSWORD} != @("*"|"") && ${ARG_MODE} == 'hash' ]]; then
if [[ ${ARG_HASH} =~ (yescrypt|gost-yescrypt|scrypt|bcrypt|bcrypt-a|sha512crypt|sha256crypt|md5crypt|descrypt) ]]; then
HASH_PASSWORD=$(echo "${ARG_PASSWORD}" | ${ROOTFS}/usr/bin/mkpasswd2 -sm ${ARG_HASH})
elif [[ ${ARG_HASH} =~ (sunmd5|bsdicrypt|nt) ]]; then
# Алгоритм отключен, использует алгоритм по умолчанию ${DEFAULT_HASHPASSWD}
HASH_PASSWORD=$(echo "${ARG_PASSWORD}" | ${ROOTFS}/usr/bin/mkpasswd2 -sm ${DEFAULT_HASHPASSWD})
elif [[ ${ARG_HASH} =~ (argon2d|argon2i|argon2ds|argon2id) ]]; then
# Алгоритм отключен, использует алгоритм по умолчанию ${DEFAULT_HASHPASSWD}
HASH_PASSWORD=$(echo "${ARG_PASSWORD}" | ${ROOTFS}/usr/bin/mkpasswd2 -sm ${DEFAULT_HASHPASSWD})
else
HASH_PASSWORD=$(echo "${ARG_PASSWORD}" | ${ROOTFS}/usr/bin/mkpasswd2 -sm ${DEFAULT_HASHPASSWD})
fi
fi
fi
echo "${BLOCK_PASSWORD}${HASH_PASSWORD}"
}
# Если параметр $1 известный хеш, то вернуть true, иначе false
# Применяется ubl-settings-usergroup
is_hash_password(){
local HASH_PASSWORD="$1"
[[ -n ${HASH_PASSWORD} ]] || return 0
[[ ${HASH_PASSWORD} =~ ^('!*'|'!'|'!!'|'*')*'$'(_|1|2|2a|2b|2x|2y|3|4|5|6|7|md5|sha1|gy|y|argon2d|argon2i|argon2ds|argon2id)'$' ]] || return 1
}
# Remove user home directories. Used ubl-settings-usergroup
# $1 # Users name a comma separated list
# TODO: Запросить хомяк по умолчанию из /etc/default/useradd HOME=
remove_userhome(){
local LIST_USERNAME="$@"
[[ ${LIST_USERNAME} != "" ]] || return 1
while IFS= read -r SELECT_USERNAME; do
rm -rdf ${ROOTFS}/home/"${SELECT_USERNAME}"
done < <(tr ',;' '\n' <<< ${LIST_USERNAME})
}
# Convert plain passwords to a hash in the global configuration
# Конвертировать не шифрованные пароли в шифрованные для глобальных переменных USERADD GROUPADD DEFAULTPASSWD DEFAULTROOTPASSWD
# $1 # Параметр конфигурации, где содержится пароль который нужно конвертировать, если первые символы %%, то пароль останется не шифрованным
# Если запущенно без параметра, то все пароли зашифровать в переменных USERADD GROUPADD DEFAULTPASSWD DEFAULTROOTPASSWD
globalconf_convert_pass_plain_to_hash(){
[[ -z ${ROOTFS} ]] || return 0
local PARAM="$@"
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} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
else
SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/.users_credential; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
fi
# Проверим DEFAULTPASSWD, если не указан в $1, то подгрузить из глобальной конфигурации
[[ -n ${PARAM} ]] || DEFAULTPASSWD=$(ubconfig --raw --source global get [users] DEFAULTPASSWD)
if [[ -n ${DEFAULTPASSWD} && ${DEFAULTPASSWD} != "(null)" ]]; then
if [[ -n ${PARAM} && $(is_hash_password ${DEFAULTPASSWD}) ]]; then
ubconfig set [users] DEFAULTPASSWD="${DEFAULTPASSWD}"
else
#return_hash_password "${DEFAULTPASSWD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] DEFAULTPASSWD="${HASH_PASSWORD_NEW}"
ubconfig 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} && $(is_hash_password ${DEFAULTROOTPASSWD}) ]]; then
ubconfig set [users] DEFAULTROOTPASSWD="${DEFAULTROOTPASSWD}"
else
#return_hash_password "${DEFAULTROOTPASSWD}"
#[[ -n ${HASH_PASSWORD_NEW} ]] && ubconfig --noexecute --target global set [users] DEFAULTROOTPASSWD="${HASH_PASSWORD_NEW}"
ubconfig 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} && $(is_hash_password ${SELECT_PASSWORD}) ]]; then
ubconfig set [users] USERADD[${SELECT_USERNAME}]="${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}"
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 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} && $(is_hash_password ${SELECT_PASSWORD}) ]]; then
ubconfig set [users] GROUPADD[${SELECT_GROUP}]="${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}"
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 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
}
#####################################################################################
###
### Функции управления пользователями и группами с помощью тектовых процессоров ###
###
#####################################################################################
# Добавить пользователя в /etc/passwd /etc/shadow
# user_add $1:$2:$3:$4:$5:$6:$7:$8:$9:$10:$11:$12:$13
# $1 # Имя пользователя
# $2 # GECOS пользователя
# $3 # UID идентификатор пользователя
# # = 's' | 'system' # Вычисляется автоматически, первый свободный системного диапазона
# # Если не задан, то вычисляется автоматически, первый свободный пользовательского диапазона
# $4 # GID первичной группы пользователя
# # Если не задана, то создать группу по имени пользователя и взять GID
# $5 # Зашифрованный пароль
# # = '' # Если не задано, то пароль '!*' запрет авторизации
# # = ' ' # Если пробел, то без пароля
# # = 'lock' | 'l' # Заблокировать авторизация, добавив '!' перед хешем
# # = 'unlock' | 'u' # Разблокировать авторизация, убрав '!' или '!!' или '!*' или '*' перед хешем
# $6 # HOME пользователя
# $7 # SHELL пользователя
# $8 # LASTCHANGED
# $9 # MINDAY
# $10 # MAXDAY
# $11 # WARN
# $12 # INACTIVE
# $13 # EXPIRE
# Для изменения параметров существующего пользователя, обязательный параметр: $1 или $3 пользователя
# Если одно из полей содержит "+" то значение поля не менять в файле
# Пример: user_add user-1:Пользователь-1
# Пример: user_add user-1:Пользователь-1:1001:1001
# Пример: user_add user-1:Пользователь-1:1001:1001:!*:/home/user-1:/bin/bash:19788:0:99999:7:2:19800
# Пример: user_add root:+:+:+:!*:+:+::+:+:+:+:+
user_add(){
[[ $1 == @("-v"|"--verbose") ]] && local VERBOSE='yes' && shift
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local FILE_SHADOW="${ROOTFS}/etc/shadow"
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
local FILE_DEFAULT_USERADD="${ROOTFS}/etc/default/useradd"
local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
local DATA_FILE_SHADOW=$(< ${FILE_SHADOW})
local DATA_FILE_LOGINDEFS=$(< ${FILE_LOGINDEFS})
local DATA_FILE_DEFAULT_USERADD=$(< ${FILE_DEFAULT_USERADD})
[[ ${DATA_FILE_DEFAULT_USERADD} =~ ($'\n'|^)+HOME=([^$'\n']*)($'\n'|$)+ ]] && local DEFAULT_HOME_USER=${BASH_REMATCH[2]:-/home}
[[ ${DATA_FILE_DEFAULT_USERADD} =~ ($'\n'|^)+SHELL=([^$'\n']*)($'\n'|$)+ ]] && local DEFAULT_SHELL_USER=${BASH_REMATCH[2]:-/bin/bash}
local DEFAULT_HOME_SYSTEM="/"
local DEFAULT_SHELL_SYSTEM="/usr/bin/nologin"
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+PASS_MAX_DAYS[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && local DEFAULT_MAXDAY=${BASH_REMATCH[2]:-99999}
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+PASS_MIN_DAYS[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && local DEFAULT_MINDAY=${BASH_REMATCH[2]:-0}
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+PASS_WARN_AGE[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && local DEFAULT_WARN=${BASH_REMATCH[2]:-7}
get_free_uid(){
local PARAM="$@"
local UID_MIN= UID_MAX= UID_NEW=
if [[ ${PARAM} == "@system" ]]; then
# Свободный номер системного списка группы
#UID_MIN=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*SYS_UID_MIN[[:blank:]]+([[:digit:]]+) ]]; printf "%d" "${BASH_REMATCH[1]}")
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+SYS_UID_MIN[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && UID_MIN=${BASH_REMATCH[2]:-500}
#UID_MAX=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*SYS_UID_MAX[[:blank:]]+([[:digit:]]+) ]]; printf "%d" "${BASH_REMATCH[1]}")
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+SYS_UID_MAX[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && UID_MAX=${BASH_REMATCH[2]:-999}
UID_NEW=$(awk -F':' -v USER_MIN=${UID_MIN} -v USER_MAX=${UID_MAX} '{ uid[$3]=USER_MAX } END {for (x=USER_MAX; x>=USER_MIN; x--) if (!uid[x]) {print x; exit}}' ${FILE_PASSWD}) #'
[[ ${UID_NEW} == "" ]] && UID_NEW=${UID_MAX}
else
# Свободный номер списка групп, кроме системного списка
#UID_MIN=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*UID_MIN[[:blank:]]+([[:digit:]]+) ]]; printf "%d" "${BASH_REMATCH[1]}")
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+UID_MIN[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && UID_MIN=${BASH_REMATCH[2]:-1000}
#UID_MAX=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*UID_MAX[[:blank:]]+([[:digit:]]+) ]]; printf "%d" "${BASH_REMATCH[1]}")
[[ ${DATA_FILE_LOGINDEFS} =~ ($'\n'|^)+UID_MAX[[:blank:]]+([[:digit:]]+)($'\n'|$)+ ]] && UID_MAX=${BASH_REMATCH[2]:-60000}
UID_NEW=$(awk -F':' -v USER_MIN=${UID_MIN} -v USER_MAX=${UID_MAX} '{ uid[$3]=USER_MIN } END {for (x=USER_MIN; x<=USER_MAX; x++) if (!uid[x]) {print x; exit}}' ${FILE_PASSWD}) #'
[[ ${UID_NEW} == "" ]] && UID_NEW=${UID_MIN}
fi
printf "%d" "${UID_NEW}"
}
is_uid_system(){
local UID_MIN=
UID_MIN=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*UID_MIN[[:blank:]]+([[:digit:]]+) ]]; printf "%d" "${BASH_REMATCH[1]}")
[[ ${SELECT_UID} -lt ${UID_MIN:=1000} ]] && printf "%d" "1" || printf "%d" "0"
}
local PARAM="$@"
# Получаем из аргумента значения
local IS_USER_SYSTEM=
local SELECT_NOUSE=
local SELECT_USERNAME= SELECT_GECOS= SELECT_UID= SELECT_GID= SELECT_PASSWORD= SELECT_HOME= SELECT_SHELL= SELECT_LASTCHANGED= SELECT_MINDAY= SELECT_MAXDAY= SELECT_WARN= SELECT_INACTIVE= SELECT_EXPIRE= NULL=
IFS=: read -r SELECT_USERNAME SELECT_GECOS SELECT_UID SELECT_GID SELECT_PASSWORD SELECT_HOME SELECT_SHELL SELECT_LASTCHANGED SELECT_MINDAY SELECT_MAXDAY SELECT_WARN SELECT_INACTIVE SELECT_EXPIRE NULL <<< "${PARAM}"
[[ ${SELECT_USERNAME} == "" && ${SELECT_UID} == "" ]] && { >&2 echo "ERROR: not added/changed '${SELECT_USERNAME}' username"; return 1; }
# Получаем из файла значения
local VOL_FILEP_PLAINPASSWORD= VOL_FILEP_UID= VOL_FILEP_GID= VOL_FILEP_GECOS= VOL_FILEP_HOME= VOL_FILEP_SHELL= VOL_FILEP_USERNAME=
if [[ ${SELECT_USERNAME} != @(""|"+") ]]; then
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEP_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEP_UID=${BASH_REMATCH[3]} \
&& VOL_FILEP_GID=${BASH_REMATCH[4]} \
&& VOL_FILEP_GECOS=${BASH_REMATCH[5]} \
&& VOL_FILEP_HOME=${BASH_REMATCH[6]} \
&& VOL_FILEP_SHELL=${BASH_REMATCH[7]}
VOL_FILEP_USERNAME=${SELECT_USERNAME}
elif [[ ${SELECT_USERNAME} == @(""|"+") && ${SELECT_UID} =~ ^[[:digit:]]+$ ]]; then
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_UID}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEP_USERNAME=${BASH_REMATCH[2]} \
&& VOL_FILEP_PLAINPASSWORD=${BASH_REMATCH[3]} \
&& VOL_FILEP_GID=${BASH_REMATCH[4]} \
&& VOL_FILEP_GECOS=${BASH_REMATCH[5]} \
&& VOL_FILEP_HOME=${BASH_REMATCH[6]} \
&& VOL_FILEP_SHELL=${BASH_REMATCH[7]}
VOL_FILEP_UID=${SELECT_UID}
SELECT_USERNAME=${VOL_FILEP_USERNAME}
fi
[[ ${SELECT_USERNAME} == @(""|"+") ]] && { >&2 echo "ERROR: not added/changed empty username"; return 1; }
[[ ${SELECT_PASSWORD} == "+" ]] && SELECT_PLAINPASSWORD=${VOL_FILEP_PLAINPASSWORD}
[[ ${SELECT_PLAINPASSWORD} == "" ]] && SELECT_PLAINPASSWORD='x'
if [[ ${SELECT_UID} == "+" && ${VOL_FILEP_UID} != "" ]]; then
SELECT_UID=${VOL_FILEP_UID}
elif [[ ${SELECT_UID} == @("s"|"system") ]]; then
SELECT_UID=$(get_free_uid @system)
elif [[ ${SELECT_UID} =~ ^[[:digit:]]+$ ]]; then
true
else
# Если UID не задан, то берём первый свободный
SELECT_UID=$(get_free_uid)
fi
if [[ ${SELECT_GID} == "+" && ${VOL_FILEP_GID} != "" ]]; then
SELECT_GID=${VOL_FILEP_GID}
elif [[ ${SELECT_GID} =~ ^[[:digit:]]+$ ]]; then
true
else
# Если GID не задан, то создаём группу по имени пользователя ${SELECT_UID} и получаем GID от созданной группы
IFS=: read -r NULL SELECT_GID NULL NULL NULL NULL <<< $(group_add --verbose "${SELECT_USERNAME}:+:+:+:+")
[[ ${SELECT_GID} == "" ]] && SELECT_GID=${SELECT_UID}
fi
[[ ${SELECT_GECOS} == "+" ]] && SELECT_GECOS=${VOL_FILEP_GECOS}
if [[ ${SELECT_HOME} == "+" && ${VOL_FILEP_HOME} != "" ]]; then
SELECT_HOME=${VOL_FILEP_HOME}
elif [[ ${SELECT_HOME} == @(""|"+") ]]; then
[[ $(is_uid_system) == 1 ]] && SELECT_HOME=${DEFAULT_HOME_SYSTEM} || SELECT_HOME="${DEFAULT_HOME_USER}/${SELECT_USERNAME}"
fi
if [[ ${SELECT_SHELL} == "+" && ${VOL_FILEP_SHELL} != "" ]]; then
SELECT_SHELL=${VOL_FILEP_SHELL}
elif [[ ${SELECT_SHELL} == @(""|"+") ]]; then
[[ $(is_uid_system) == 1 ]] && SELECT_SHELL=${DEFAULT_SHELL_SYSTEM} || SELECT_SHELL=${DEFAULT_SHELL_USER}
fi
local VOL_FILEPS_PASSWORD= VOL_FILEPS_LASTCHANGED= VOL_FILEPS_MINDAY= VOL_FILEPS_MAXDAY= VOL_FILEPS_WARN= VOL_FILEPS_INACTIVE= VOL_FILEPS_EXPIRE= VOL_FILEPS_NOUSE=
[[ ${DATA_FILE_SHADOW} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEPS_PASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEPS_LASTCHANGED=${BASH_REMATCH[3]} \
&& VOL_FILEPS_MINDAY=${BASH_REMATCH[4]} \
&& VOL_FILEPS_MAXDAY=${BASH_REMATCH[5]} \
&& VOL_FILEPS_WARN=${BASH_REMATCH[6]} \
&& VOL_FILEPS_INACTIVE=${BASH_REMATCH[7]} \
&& VOL_FILEPS_EXPIRE=${BASH_REMATCH[8]} \
&& VOL_FILEPS_NOUSE=${BASH_REMATCH[9]}
if [[ ${SELECT_PASSWORD} == "+" && ${VOL_FILEPS_PASSWORD} != "" ]]; then
SELECT_PASSWORD=${VOL_FILEPS_PASSWORD}
elif [[ ${SELECT_PASSWORD} == @("lock"|"l") && ${VOL_FILEPS_PASSWORD} != "" ]]; then
if [[ ${VOL_FILEPS_PASSWORD:0:1} == "!" ]]; then
SELECT_PASSWORD=${VOL_FILEPS_PASSWORD}
else
SELECT_PASSWORD="!${VOL_FILEPS_PASSWORD}"
fi
elif [[ ${SELECT_PASSWORD} == @("unlock"|"u") && ${VOL_FILEPS_PASSWORD} != "" ]]; then
if [[ ${VOL_FILEPS_PASSWORD:0:2} == "!!" ]]; then
SELECT_PASSWORD="${VOL_FILEPS_PASSWORD:2}"
elif [[ ${VOL_FILEPS_PASSWORD:0:2} == "!*" ]]; then
SELECT_PASSWORD="${VOL_FILEPS_PASSWORD:2}"
elif [[ ${VOL_FILEPS_PASSWORD:0:1} == "*" ]]; then
SELECT_PASSWORD="${VOL_FILEPS_PASSWORD:1}"
elif [[ ${VOL_FILEPS_PASSWORD:0:1} == "!" ]]; then
SELECT_PASSWORD="${VOL_FILEPS_PASSWORD:1}"
else
SELECT_PASSWORD="${VOL_FILEPS_PASSWORD}"
fi
elif [[ ${SELECT_PASSWORD} == " " ]]; then
SELECT_PASSWORD=
elif [[ ${SELECT_PASSWORD} == @(""|"+") ]]; then
SELECT_PASSWORD="!*"
fi
if [[ ${SELECT_LASTCHANGED} == "+" && ${VOL_FILEPS_LASTCHANGED} != "" ]]; then
SELECT_LASTCHANGED=${VOL_FILEPS_LASTCHANGED}
elif [[ ${SELECT_LASTCHANGED} =~ ^[[:digit:]]{4,4}'-'[[:digit:]]{1,2}'-'[[:digit:]]{1,2}$ ]]; then
SELECT_LASTCHANGED=$(( $(${CMD_CHROOT} date --date="${SELECT_LASTCHANGED} 0000" +"%s")/(60*60*24) ))
elif [[ ${SELECT_LASTCHANGED} =~ ^[[:digit:]]{1,5}$ ]]; then
true
else
SELECT_LASTCHANGED=$(( $(${CMD_CHROOT} date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day
fi
if [[ ${SELECT_MINDAY} == "+" && ${VOL_FILEPS_MINDAY} != "" ]]; then
SELECT_MINDAY=${VOL_FILEPS_MINDAY}
elif [[ ${SELECT_MINDAY} =~ ^[[:digit:]]+$ ]]; then
true
else
[[ $(is_uid_system) == 1 ]] && SELECT_MINDAY= || SELECT_MINDAY=${DEFAULT_MINDAY}
fi
if [[ ${SELECT_MAXDAY} == "+" && ${VOL_FILEPS_MAXDAY} != "" ]]; then
SELECT_MAXDAY=${VOL_FILEPS_MAXDAY}
elif [[ ${SELECT_MAXDAY} =~ ^[[:digit:]]+$ ]]; then
true
else
[[ $(is_uid_system) == 1 ]] && SELECT_MAXDAY= || SELECT_MAXDAY=${DEFAULT_MAXDAY}
fi
if [[ ${SELECT_WARN} == "+" && ${VOL_FILEPS_WARN} != "" ]]; then
SELECT_WARN=${VOL_FILEPS_WARN}
elif [[ ${SELECT_WARN} =~ ^[[:digit:]]+$ ]]; then
true
else
[[ $(is_uid_system) == 1 ]] && SELECT_WARN= || SELECT_WARN=${DEFAULT_WARN}
fi
if [[ ${SELECT_INACTIVE} == "+" && ${VOL_FILEPS_INACTIVE} != "" ]]; then
SELECT_INACTIVE=${VOL_FILEPS_INACTIVE}
elif [[ ${SELECT_INACTIVE} =~ (-1|^[[:digit:]]+$) ]]; then
true
else
SELECT_INACTIVE=
fi
if [[ ${SELECT_EXPIRE} == "+" && ${VOL_FILEPS_EXPIRE} != "" ]]; then
SELECT_EXPIRE=${VOL_FILEPS_EXPIRE}
elif [[ ${SELECT_EXPIRE} =~ ^[[:digit:]]{4,4}'-'[[:digit:]]{1,2}'-'[[:digit:]]{1,2}$ ]]; then
SELECT_EXPIRE=$(( $(${CMD_CHROOT} date --date="${SELECT_EXPIRE} 0000" +"%s")/(60*60*24) ))
elif [[ ${SELECT_EXPIRE} =~ ^[[:digit:]]{1,5}$ ]]; then
true
else
SELECT_EXPIRE=
fi
SELECT_NOUSE=""
# Если нет изменений, то ничего не делать
if [[ "${SELECT_USERNAME}" != "${VOL_FILEP_USERNAME}" && "${SELECT_PLAINPASSWORD}" != "${VOL_FILEP_PLAINPASSWORD}" || "${SELECT_UID}" != "${VOL_FILEP_UID}" || "${SELECT_GID}" != "${VOL_FILEP_GID}" || "${SELECT_GECOS}" != "${VOL_FILEP_GECOS}" \
|| "${SELECT_HOME}" != "${VOL_FILEP_HOME}" || "${SELECT_SHELL}" != "${VOL_FILEP_SHELL}" ]]; then
#sed "/^${SELECT_USERNAME}:/d" -i "${FILE_PASSWD}"
#printf "%s:%s:%d:%d:%s:%s:%s\n" "${SELECT_USERNAME}" "${SELECT_PLAINPASSWORD}" "${SELECT_UID}" "${SELECT_GID}" "${SELECT_GECOS}" "${SELECT_HOME}" "${SELECT_SHELL}" >> "${FILE_PASSWD}"
#sed -e "/^${SELECT_USERNAME}:/d" -e "\$a${SELECT_USERNAME}:${SELECT_PLAINPASSWORD}:${SELECT_UID}:${SELECT_GID}:${SELECT_GECOS}:${SELECT_HOME}:${SELECT_SHELL}" -i "${FILE_PASSWD}"
#sed -e "\$a${SELECT_USERNAME}:${SELECT_PLAINPASSWORD}:${SELECT_UID}:${SELECT_GID}:${SELECT_GECOS}:${SELECT_HOME}:${SELECT_SHELL}" -i "${FILE_PASSWD}"
while [[ ${DATA_FILE_PASSWD} =~ ^(.*)(^|$'\n')"${SELECT_USERNAME}:"([^$'\n'])+($'\n'|$)(.*)$ ]]; do DATA_FILE_PASSWD="${BASH_REMATCH[1]}${BASH_REMATCH[5]}"; done
[[ ${DATA_FILE_PASSWD} =~ ^(.*)($'\n')+$ ]] && DATA_FILE_PASSWD="${BASH_REMATCH[1]}"
printf "%s\n%s:%s:%d:%d:%s:%s:%s\n" "${DATA_FILE_PASSWD}" "${SELECT_USERNAME}" "${SELECT_PLAINPASSWORD}" "${SELECT_UID}" "${SELECT_GID}" "${SELECT_GECOS}" "${SELECT_HOME}" "${SELECT_SHELL}" > "${FILE_PASSWD}"
fi
if [[ "${SELECT_PASSWORD}" != "${VOL_FILEPS_PASSWORD}" || "${SELECT_LASTCHANGED}" != "${VOL_FILEPS_LASTCHANGED}" || "${SELECT_MINDAY}" != "${VOL_FILEPS_MINDAY}" || "${SELECT_MAXDAY}" != "${VOL_FILEPS_MAXDAY}" \
|| "${SELECT_WARN}" != "${VOL_FILEPS_WARN}" || "${SELECT_INACTIVE}" != "${VOL_FILEPS_INACTIVE}" || "${SELECT_EXPIRE}" != "${VOL_FILEPS_EXPIRE}" ]]; then
#sed "/^${SELECT_USERNAME}:/d" -i "${FILE_SHADOW}"
#printf "%s:%s:%d:%s:%s:%s:%s:%s:%s\n" "${SELECT_USERNAME}" "${SELECT_PASSWORD}" "${SELECT_LASTCHANGED}" "${SELECT_MINDAY}" "${SELECT_MAXDAY}" "${SELECT_WARN}" "${SELECT_INACTIVE}" "${SELECT_EXPIRE}" "${SELECT_NOUSE}" >> "${FILE_SHADOW}"
#sed -e "/^${SELECT_USERNAME}:/d" -e "\$a${SELECT_USERNAME}:${SELECT_PASSWORD}:${SELECT_LASTCHANGED}:${SELECT_MINDAY}:${SELECT_MAXDAY}:${SELECT_WARN}:${SELECT_INACTIVE}:${SELECT_EXPIRE}:${SELECT_NOUSE}" -i "${FILE_SHADOW}"
#sed -e "\$a${SELECT_USERNAME}:${SELECT_PASSWORD}:${SELECT_LASTCHANGED}:${SELECT_MINDAY}:${SELECT_MAXDAY}:${SELECT_WARN}:${SELECT_INACTIVE}:${SELECT_EXPIRE}:${SELECT_NOUSE}" -i "${FILE_SHADOW}"
while [[ ${DATA_FILE_SHADOW} =~ ^(.*)(^|$'\n')"${SELECT_USERNAME}:"([^$'\n'])+($'\n'|$)(.*)$ ]]; do DATA_FILE_SHADOW="${BASH_REMATCH[1]}${BASH_REMATCH[5]}"; done
[[ ${DATA_FILE_SHADOW} =~ ^(.*)($'\n')+$ ]] && DATA_FILE_SHADOW="${BASH_REMATCH[1]}"
printf "%s\n%s:%s:%d:%s:%s:%s:%s:%s:%s\n" "${DATA_FILE_SHADOW}" "${SELECT_USERNAME}" "${SELECT_PASSWORD}" "${SELECT_LASTCHANGED}" "${SELECT_MINDAY}" "${SELECT_MAXDAY}" "${SELECT_WARN}" "${SELECT_INACTIVE}" "${SELECT_EXPIRE}" "${SELECT_NOUSE}" > "${FILE_SHADOW}"
fi
[[ -z ${VERBOSE} ]] || printf "%s:%s:%d:%d:%s:%s:%s:%d:%s:%s:%s:%s:%s\n" "${SELECT_USERNAME}" "${SELECT_GECOS}" "${SELECT_UID}" "${SELECT_GID}" "${SELECT_PASSWORD}" "${SELECT_HOME}" "${SELECT_SHELL}" "${SELECT_LASTCHANGED}" "${SELECT_MINDAY}" "${SELECT_MAXDAY}" "${SELECT_WARN}" "${SELECT_INACTIVE}" "${SELECT_EXPIRE}"
}
# Удалить пользователя из /etc/passwd /etc/shadow
# user_del $1:$2
# $1 # Имя пользователя
# $2 # UID идентификатор пользователя
# Что-бы удалить пользователя можно указать $1 или $2 или оба одновременно $1:$2
# Пример: user_del user-1
# user_del :1001
# user_del user-2:1002
user_del(){
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local FILE_SHADOW="${ROOTFS}/etc/shadow"
local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local DATA_FILE_GROUP=$(< ${FILE_GROUP})
local PARAM="$@"
local SELECT_USERNAME= SELECT_UID=
IFS=: read -r SELECT_USERNAME SELECT_UID NULL <<< "${PARAM}"
[[ ${SELECT_USERNAME} == "" && ${SELECT_UID} == "" ]] && { >&2 echo "ERROR: not delete '${SELECT_USERNAME}' username"; return 1; }
SELECT_USERNAME=$@
local VOL_FILEP_PLAINPASSWORD VOL_FILEP_UID VOL_FILEP_GID VOL_FILEP_GECOS VOL_FILEP_HOME VOL_FILEP_SHELL
# Ищем пользователя вначале по имени, после по UID
[[ -n ${SELECT_USERNAME} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEP_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEP_UID=${BASH_REMATCH[3]} \
&& VOL_FILEP_GID=${BASH_REMATCH[4]} \
&& VOL_FILEP_GECOS=${BASH_REMATCH[5]} \
&& VOL_FILEP_HOME=${BASH_REMATCH[6]} \
&& VOL_FILEP_SHELL=${BASH_REMATCH[7]}
[[ -n ${SELECT_UID} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_UID}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_USERNAME=${BASH_REMATCH[2]} \
&& VOL_FILEP_PLAINPASSWORD=${BASH_REMATCH[3]} \
&& VOL_FILEP_UID=${SELECT_UID} \
&& VOL_FILEP_GID=${BASH_REMATCH[4]} \
&& VOL_FILEP_GECOS=${BASH_REMATCH[5]} \
&& VOL_FILEP_HOME=${BASH_REMATCH[6]} \
&& VOL_FILEP_SHELL=${BASH_REMATCH[7]}
sed "/^${SELECT_USERNAME}:/d" -i "${FILE_PASSWD}"
sed "/^${SELECT_USERNAME}:/d" -i "${FILE_SHADOW}"
# Если имеется группа с таким же именем пользователя и она является основной группой указанного пользователя и в ней нет других пользователей
local VOL_FILEG_PLAINPASSWORD= VOL_FILEG_GID= VOL_FILEG_MEMBERS= OTHER_USERNAME=
[[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEG_GID=${BASH_REMATCH[3]} \
&& VOL_FILEG_MEMBERS=${BASH_REMATCH[4]}
# и она не является основной у других пользователей
[[ -n ${VOL_FILEP_GID} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):([^$'\n']*):"${VOL_FILEP_GID}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& OTHER_USERNAME=${BASH_REMATCH[2]}
# то удаляем группу
if [[ ${VOL_FILEP_GID} == ${VOL_FILEG_GID} && -z ${VOL_FILEG_MEMBERS} && -z ${OTHER_USERNAME} ]]; then
sed /^${SELECT_USERNAME}:/d -i "${FILE_GROUP}"
sed /^${SELECT_USERNAME}:/d -i "${FILE_GSHADOW}"
fi
# Удаляем пользователя из всех групп
sed "s/:${SELECT_USERNAME}$/:/g;s/:${SELECT_USERNAME},/:/g;s/,${SELECT_USERNAME}$//g;s/,${SELECT_USERNAME},/,/g" -i "${FILE_GROUP}"
sed "s/:${SELECT_USERNAME}$/:/g;s/:${SELECT_USERNAME},/:/g;s/,${SELECT_USERNAME}$//g;s/,${SELECT_USERNAME},/,/g" -i "${FILE_GSHADOW}"
}
# Добавить группу в /etc/group /etc/gshadow
# group_add $1:$2:$3:$4:$5
# $1 # Имя группы
# $2 # GID идентификатор группы
# # = 's' | 'system' # Вычисляется автоматически, первый свободный системного диапазона
# # Если не задан, то вычисляется автоматически, первый свободный пользовательского диапазона
# $3 # Члены группы, разделённые запятыми
# $4 # Зашифрованный пароль
# # = '' # Если не задано, то пароль '!*' запрет авторизации
# # = ' ' # Если пробел, то без пароля
# # = 'lock' | 'l' # Заблокировать авторизация, добавив '!' перед хешем
# # = 'unlock' | 'u' # Разблокировать авторизация, убрав '!' или '!!' или '!*' или '*' перед хешем
# $5 # Администраторы группы, разделённые запятыми
# Для изменения параметров существующей группы, обязательный параметр: $1 или $2 пользователя
# Если одно из полей содержит "+" то значение поля не менять в файле
# Пример: g_department_1
# Пример: g_department_1:1010
# Пример: g_department_1:1010:user-1,user-2::superadmin
# Пример: g_department_1:+:+:+:+
# Пример: g_department_1:1010:+:+:+
group_add(){
[[ $1 == @("-v"|"--verbose") ]] && local VERBOSE='yes' && shift
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
local DATA_FILE_GROUP=$(< ${FILE_GROUP})
local DATA_FILE_GSHADOW=$(< ${FILE_GSHADOW})
local DATA_FILE_LOGINDEFS=$(< ${FILE_LOGINDEFS})
get_free_gid(){
local PARAM="$@"
local GID_MIN= GID_MAX= GID_NEW=
if [[ ${PARAM} == "@system" ]]; then
# Свободный номер системного списка группы
GID_MIN=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*SYS_GID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
GID_MAX=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*SYS_GID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
GID_NEW=$(awk -F':' -v GROUP_MIN=${GID_MIN:=500} -v GROUP_MAX=${GID_MAX:=999} '{ gid[$3]=GROUP_MAX } END {for (x=GROUP_MAX; x>=GROUP_MIN; x--) if (!gid[x]) {print x; exit}}' ${FILE_GROUP}) #'
[[ ${GID_NEW} == "" ]] && GID_NEW=${GID_MAX}
else
# Свободный номер списка групп, кроме системного списка
GID_MIN=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*GID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
GID_MAX=$([[ ${DATA_FILE_LOGINDEFS} =~ [^#[^:blank:]]*GID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
# Предоставить свободный номер с начала списка
GID_NEW=$(awk -F':' -v GROUP_MIN=${GID_MIN:=1000} -v GROUP_MAX=${GID_MAX:=6000} '{ gid[$3]=GROUP_MIN } END {for (x=GROUP_MIN; x<=GROUP_MAX; x++) if (!gid[x]) {print x; exit}}' ${FILE_GROUP}) #'
[[ ${GID_NEW} == "" ]] && GID_NEW=${GID_MIN}
# Предоставить свободный номер с конца списка
#GID_NEW=$(awk -F':' -v GROUP_MIN=${GID_MIN:=1000} -v GROUP_MAX=${GID_MAX:=60000} '{ gid[$3]=GROUP_MAX } END {for (x=GROUP_MAX; x>=GROUP_MIN; x--) if (!gid[x]) {print x; exit}}' ${FILE_GROUP}) #'
#[[ ${GID_NEW} == "" ]] && GID_NEW=${GID_MAX}
fi
printf "%d" "${GID_NEW}"
}
local PARAM="$@"
# Получаем из аргумента значения
local SELECT_GROUPNAME= SELECT_GID= SELECT_MEMBERS= SELECT_PASSWORD= SELECT_ADMINISTRATORS= NULL=
IFS=: read -r SELECT_GROUPNAME SELECT_GID SELECT_MEMBERS SELECT_PASSWORD SELECT_ADMINISTRATORS NULL <<< "${PARAM}"
[[ ${SELECT_GROUPNAME} == "" && ${SELECT_GID} == "" ]] && { >&2 echo "ERROR: not added/changed '${SELECT_GROUPNAME}' groupname"; return 1; }
# Получаем из файла значения
local VOL_FILEG_PLAINPASSWORD= VOL_FILEG_GID= VOL_FILEG_MEMBERS= VOL_FILEG_GROUPNAME=
local SELECT_PLAINPASSWORD=
if [[ ${SELECT_GROUPNAME} != @(""|"+") ]]; then
[[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEG_GID=${BASH_REMATCH[3]} \
&& VOL_FILEG_MEMBERS=${BASH_REMATCH[4]}
VOL_FILEG_GROUPNAME=${SELECT_GROUPNAME}
elif [[ ${SELECT_GROUPNAME} == @(""|"+") && ${SELECT_GID} =~ ^[[:digit:]]+$ ]]; then
[[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_GID}":([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEG_GROUPNAME=${BASH_REMATCH[2]} \
&& VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[3]} \
&& VOL_FILEG_MEMBERS=${BASH_REMATCH[4]}
VOL_FILEG_GID=${SELECT_GID}
SELECT_GROUPNAME=${VOL_FILEG_GROUPNAME}
fi
[[ ${SELECT_GROUPNAME} == @(""|"+") ]] && { >&2 echo "ERROR: not added/changed empty groupname"; return 1; }
[[ ${SELECT_PASSWORD} == "+" ]] && SELECT_PLAINPASSWORD=${VOL_FILEG_PLAINPASSWORD} || SELECT_PLAINPASSWORD='x'
[[ ${SELECT_PASSWORD} == "" || ${SELECT_PLAINPASSWORD} == "" ]] && SELECT_PLAINPASSWORD='x'
if [[ ${SELECT_GID} == "+" && ${VOL_FILEG_GID} != "" ]]; then
SELECT_GID=${VOL_FILEG_GID}
elif [[ ${SELECT_GID} == @("s"|"system") ]]; then
SELECT_GID=$(get_free_gid @system)
elif [[ ${SELECT_GID} =~ ^[[:digit:]]+$ ]]; then
true
else
SELECT_GID=$(get_free_gid)
fi
[[ ${SELECT_MEMBERS} == "+" ]] && SELECT_MEMBERS=${VOL_FILEG_MEMBERS}
local VOL_FILEGS_PASSWORD= VOL_FILEGS_ADMINISTRATORS= VOL_FILEGS_MEMBERS=
[[ ${DATA_FILE_GSHADOW} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEGS_PASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEGS_ADMINISTRATORS=${BASH_REMATCH[3]} \
&& VOL_FILEGS_MEMBERS=${BASH_REMATCH[4]}
if [[ ${SELECT_PASSWORD} == "+" && ${VOL_FILEGS_PASSWORD} != "" ]]; then
SELECT_PASSWORD=${VOL_FILEGS_PASSWORD}
elif [[ ${SELECT_PASSWORD} == @("lock"|"l") && ${VOL_FILEGS_PASSWORD} != "" ]]; then
if [[ ${VOL_FILEGS_PASSWORD:0:1} == "!" ]]; then
SELECT_PASSWORD=${VOL_FILEGS_PASSWORD}
else
SELECT_PASSWORD="!${VOL_FILEGS_PASSWORD}"
fi
elif [[ ${SELECT_PASSWORD} == @("unlock"|"u") && ${VOL_FILEGS_PASSWORD} != "" ]]; then
if [[ ${VOL_FILEGS_PASSWORD:0:2} == "!!" ]]; then
SELECT_PASSWORD="${VOL_FILEGS_PASSWORD:2}"
elif [[ ${VOL_FILEGS_PASSWORD:0:2} == "!*" ]]; then
SELECT_PASSWORD="${VOL_FILEGS_PASSWORD:2}"
elif [[ ${VOL_FILEGS_PASSWORD:0:1} == "*" ]]; then
SELECT_PASSWORD="${VOL_FILEGS_PASSWORD:1}"
elif [[ ${VOL_FILEGS_PASSWORD:0:1} == "!" ]]; then
SELECT_PASSWORD="${VOL_FILEGS_PASSWORD:1}"
else
SELECT_PASSWORD="${VOL_FILEGS_PASSWORD}"
fi
elif [[ ${SELECT_PASSWORD} == " " ]]; then
SELECT_PASSWORD=
elif [[ ${SELECT_PASSWORD} == @(""|"+") ]]; then
SELECT_PASSWORD="!*"
fi
[[ ${SELECT_ADMINISTRATORS} == "+" ]] && SELECT_ADMINISTRATORS=${VOL_FILEGS_ADMINISTRATORS}
# Если нет изменений, то ничего не делать
if [[ "${SELECT_GROUPNAME}" != "${VOL_FILEG_GROUPNAME}" && "${SELECT_PLAINPASSWORD}" != "${VOL_FILEG_PLAINPASSWORD}" || "${SELECT_GID}" != "${VOL_FILEG_GID}" || "${SELECT_MEMBERS}" != "${VOL_FILEG_MEMBERS}" ]]; then
#sed /^${SELECT_GROUPNAME}:/d -i "${FILE_GROUP}"
#printf "%s:%s:%d:%s\n" "${SELECT_GROUPNAME}" "${SELECT_PLAINPASSWORD}" "${SELECT_GID}" "${SELECT_MEMBERS}" >> "${FILE_GROUP}"
#sed -e "/^${SELECT_GROUPNAME}:/d" -e "\$a${SELECT_GROUPNAME}:${SELECT_PLAINPASSWORD}:${SELECT_GID}:${SELECT_MEMBERS}" -i "${FILE_GROUP}"
while [[ ${DATA_FILE_GROUP} =~ ^(.*)(^|$'\n')"${SELECT_GROUPNAME}:"([^$'\n'])+($'\n'|$)(.*)$ ]]; do DATA_FILE_GROUP="${BASH_REMATCH[1]}${BASH_REMATCH[5]}"; done
[[ ${DATA_FILE_GROUP} =~ ^(.*)($'\n')+$ ]] && DATA_FILE_GROUP="${BASH_REMATCH[1]}"
printf "%s\n%s:%s:%d:%s\n" "${DATA_FILE_GROUP}" "${SELECT_GROUPNAME}" "${SELECT_PLAINPASSWORD}" "${SELECT_GID}" "${SELECT_MEMBERS}" > "${FILE_GROUP}"
#printf "%s:%s:%d:%s\n" "${SELECT_GROUPNAME}" "${SELECT_PLAINPASSWORD}" "${SELECT_GID}" "${SELECT_MEMBERS}"
fi
if [[ "${SELECT_PASSWORD}" != "${VOL_FILEGS_PASSWORD}" || "${SELECT_ADMINISTRATORS}" != "${VOL_FILEGS_ADMINISTRATORS}" || "${SELECT_MEMBERS}" != "${VOL_FILEGS_MEMBERS}" ]]; then
#sed /^${SELECT_GROUPNAME}:/d -i "${FILE_GSHADOW}"
#printf "%s:%s:%s:%s\n" "${SELECT_GROUPNAME}" "${SELECT_PASSWORD}" "${SELECT_ADMINISTRATORS}" "${SELECT_MEMBERS}" >> "${FILE_GSHADOW}"
#sed -e "/^${SELECT_GROUPNAME}:/d" -e "\$a${SELECT_GROUPNAME}:${SELECT_PASSWORD}:${SELECT_ADMINISTRATORS}:${SELECT_MEMBERS}" -i "${FILE_GSHADOW}"
while [[ ${DATA_FILE_GSHADOW} =~ ^(.*)(^|$'\n')"${SELECT_GROUPNAME}:"([^$'\n'])+($'\n'|$)(.*)$ ]]; do DATA_FILE_GSHADOW="${BASH_REMATCH[1]}${BASH_REMATCH[5]}"; done
[[ ${DATA_FILE_GSHADOW} =~ ^(.*)($'\n')+$ ]] && DATA_FILE_GSHADOW="${BASH_REMATCH[1]}"
printf "%s\n%s:%s:%s:%s\n" "${DATA_FILE_GSHADOW}" "${SELECT_GROUPNAME}" "${SELECT_PASSWORD}" "${SELECT_ADMINISTRATORS}" "${SELECT_MEMBERS}" > "${FILE_GSHADOW}"
#printf "%s:%s:%s:%s\n" "${SELECT_GROUPNAME}" "${SELECT_PASSWORD}" "${SELECT_ADMINISTRATORS}" "${SELECT_MEMBERS}"
fi
[[ -z ${VERBOSE} ]] || printf "%s:%d:%s:%s:%s\n" "${SELECT_GROUPNAME}" "${SELECT_GID}" "${SELECT_MEMBERS}" "${SELECT_PASSWORD}" "${SELECT_ADMINISTRATORS}"
}
# Удалить группу из /etc/group /etc/gshadow
# group_del $1
# $1 # Имя группы
# $2 # GID идентификатор группы
# Что-бы удалить группу можно указать $1 или $2 или оба одновременно $1:$2
# Пример: group_del user-1
# group_del :1001
# group_del user-2:1002
group_del(){
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local DATA_FILE_GROUP=$(< ${FILE_GROUP})
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
local PARAM="$@"
local SELECT_GROUPNAME= SELECT_GID= NULL=
IFS=: read -r SELECT_GROUPNAME SELECT_GID NULL <<< "${PARAM}"
local VOL_FILEG_PLAINPASSWORD= VOL_FILEG_GID= VOL_FILEG_MEMBERS=
[[ -n ${SELECT_GROUPNAME} && ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& VOL_FILEG_GID=${BASH_REMATCH[3]} \
&& VOL_FILEG_MEMBERS=${BASH_REMATCH[4]}
[[ -n ${SELECT_GID} && ${DATA_FILE_GROUP} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_GID}":([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_GROUPNAME=${BASH_REMATCH[2]} \
&& VOL_FILEG_PLAINPASSWORD=${BASH_REMATCH[3]} \
&& VOL_FILEG_GID=${SELECT_GID} \
&& VOL_FILEG_MEMBERS=${BASH_REMATCH[4]}
local VOL_FILEP_PLAINPASSWORD VOL_FILEP_UID VOL_FILEP_GID VOL_FILEP_GECOS VOL_FILEP_HOME VOL_FILEP_SHELL
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):([^$'\n']*):"${VOL_FILEG_GID}":([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEP_USERNAME=${BASH_REMATCH[2]} \
&& VOL_FILEP_PLAINPASSWORD=${BASH_REMATCH[3]} \
&& VOL_FILEP_UID=${BASH_REMATCH[4]} \
&& VOL_FILEP_GECOS=${BASH_REMATCH[5]} \
&& VOL_FILEP_HOME=${BASH_REMATCH[6]} \
&& VOL_FILEP_SHELL=${BASH_REMATCH[7]}
if [[ -n ${VOL_FILEP_USERNAME} ]]; then
>&2 echo "ERROR: cannot remove the primary group of user '${VOL_FILEP_USERNAME}'"
else
sed "/^${SELECT_GROUPNAME}:/d" -i "${FILE_GROUP}"
sed "/^${SELECT_GROUPNAME}:/d" -i "${FILE_GSHADOW}"
fi
}
# Добавить пользователей в группы /etc/group /etc/gshadow
# user_add_group $1,$1,... $2,$2,$2,...
# $1 # Имя пользователя и/или UID. Разделённых ','
# # <username_1>:<uid_1>,<username_1>:<uid_1>,...
# $2 # Имена групп разделённых ','
# Пример: user_add_group user-1 wheel,lp,disk
# Пример: user_add_group user-1,user-2 wheel,lp,disk
# Пример: user_add_group :1001 wheel,lp,disk
# Пример: user_add_group user-1:1001 wheel,lp,disk
user_add_group(){
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local DATA_FILE_GROUP=$(< ${FILE_GROUP})
local DATA_FILE_GSHADOW=$(< ${FILE_GSHADOW})
local SELECT_USERNAME_UID_LIST=$1
local SELECT_GROUPS=$2
while IFS= read -r SELECT_USERNAME_UID; do
[[ ${SELECT_USERNAME_UID_LIST} == "" ]] && continue
local SELECT_USERNAME= SELECT_UID= NULL=
IFS=: read -ru3 SELECT_USERNAME SELECT_UID NULL 3<<< "${SELECT_USERNAME_UID}"
local SELECT_GID= SELECT_GROUPNAME= VOL_FILEP_GID=
# Ищем пользователя вначале по имени, после по UID
[[ -n ${SELECT_USERNAME} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& VOL_FILEP_GID=${BASH_REMATCH[4]}
[[ -n ${SELECT_UID} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_UID}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_USERNAME=${BASH_REMATCH[2]} \
&& VOL_FILEP_GID=${BASH_REMATCH[4]}
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}": ]] || { >&2 echo "ERROR: user '${SELECT_USERNAME}' not found"; return 1; }
[[ -n ${SELECT_GROUPS} ]] || { >&2 echo "ERROR: groups should not be empty"; return 1; }
SELECT_GID=${VOL_FILEP_GID}
[[ -n ${SELECT_GID} && ${DATA_FILE_GROUP} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_GID}":([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_GROUPNAME=${BASH_REMATCH[2]}
# Убираем дубликаты групп
SELECT_GROUPS=$(sort -u <<< ${SELECT_GROUPS//,/$'\n'}); SELECT_GROUPS=${SELECT_GROUPS//$'\n'/,}
# Проверяем, если группа является основной у пользователя, то исключить из списка групп
SELECT_GROUPS=$(sed "s/^${SELECT_GROUPNAME}$//g;s/^${SELECT_GROUPNAME},//g;s/,${SELECT_GROUPNAME}$//g;s/,${SELECT_GROUPNAME},/,/g" <<< "${SELECT_GROUPS}")
while IFS= read -ru4 SELECT_GROUPNAME; do
[[ ${SELECT_GROUPNAME} == "" ]] && continue
if [[ ! ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*)(:|:[-a-z0-9_,]+,)"${SELECT_USERNAME}"(,|$'\n'|$)+ ]]; then
DATA_FILE_GROUP=$(sed "/^${SELECT_GROUPNAME}:.*[^:]$/ s/$/,${SELECT_USERNAME}/" <<< ${DATA_FILE_GROUP})
DATA_FILE_GROUP=$(sed "/^${SELECT_GROUPNAME}:.*:$/ s/$/${SELECT_USERNAME}/" <<< ${DATA_FILE_GROUP})
fi
if [[ ! ${DATA_FILE_GSHADOW} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*)(:|:[-a-z0-9_,]+,)"${SELECT_USERNAME}"(,|$'\n'|$)+ ]]; then
DATA_FILE_GSHADOW=$(sed "/^${SELECT_GROUPNAME}:.*[^:]$/ s/$/,${SELECT_USERNAME}/" <<< ${DATA_FILE_GSHADOW})
DATA_FILE_GSHADOW=$(sed "/^${SELECT_GROUPNAME}:.*:$/ s/$/${SELECT_USERNAME}/" <<< ${DATA_FILE_GSHADOW})
fi
done 4<<< ${SELECT_GROUPS//,/$'\n'}
done <<< ${SELECT_USERNAME_UID_LIST//,/$'\n'}
echo "${DATA_FILE_GROUP}" > "${FILE_GROUP}"
echo "${DATA_FILE_GSHADOW}" > "${FILE_GSHADOW}"
}
# Удалить пользователя из групп /etc/group /etc/gshadow
# user_remove_group $1,$1,$1 $2,$2,$2,...
# $1 # Список имён пользователей и/или UID. Разделитель ','
# # <username1>:<uid1>,<username2>:<uid2>,...
# $2 # Имена групп разделённых ','
# # Если указано '%all' то все группы
# Пример: user_remove_group user-1 wheel,lp,disk
# Пример: user_remove_group user-1,user-2 wheel,lp,disk
# Пример: user_remove_group :1001 wheel,lp,disk
# Пример: user_remove_group user-1:1001 %all
user_remove_group(){
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local DATA_FILE_GROUP=$(< ${FILE_GROUP})
local DATA_FILE_GSHADOW=$(< ${FILE_GSHADOW})
local SELECT_USERNAME_UID_LIST=$1
local SELECT_GROUPS=$2
local SELECT_USERNAME_UID=
while IFS= read -r SELECT_USERNAME_UID; do
[[ ${SELECT_USERNAME_UID} == "" ]] && continue
local SELECT_USERNAME= SELECT_UID= NULL=
IFS=: read -ru3 SELECT_USERNAME SELECT_UID NULL 3<<< "${SELECT_USERNAME_UID}"
if [[ ${SELECT_GROUPS} == '%all' ]]; then
DATA_FILE_GROUP=$(sed "s/:${SELECT_USERNAME}$/:/g;s/:${SELECT_USERNAME},/:/g;s/,${SELECT_USERNAME}$//g;s/,${SELECT_USERNAME},/,/g" <<< ${DATA_FILE_GROUP})
DATA_FILE_GSHADOW=$(sed "s/:${SELECT_USERNAME}$/:/g;s/:${SELECT_USERNAME},/:/g;s/,${SELECT_USERNAME}$//g;s/,${SELECT_USERNAME},/,/g" <<< ${DATA_FILE_GSHADOW})
else
# Ищем пользователя вначале по имени, после по UID
#[[ -n ${SELECT_USERNAME} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]]
[[ -n ${SELECT_UID} && ${DATA_FILE_PASSWD} =~ ($'\n'|^)+([^$'\n']*):([^$'\n']*):"${SELECT_UID}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_USERNAME=${BASH_REMATCH[2]}
# Если пользователя нет среди пользователей. Отключил, чтобы всех без проверки удалять.
#[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}": ]] || { >&2 echo "ERROR: user '${SELECT_USERNAME}' not found"; continue; }
[[ -n ${SELECT_GROUPS} ]] || { >&2 echo "ERROR: groups should not be empty"; return 1; }
#[[ ${SELECT_GROUPS} == '%all' ]] && SELECT_GROUPS=$(sed -En 's/^([^:]+):.*/\1/p' <<< ${DATA_FILE_GROUP}) #'
locale SELECT_GROUPNAME=
while IFS= read -ru4 SELECT_GROUPNAME; do
[[ ${SELECT_GROUPNAME} == "" ]] && continue
if [[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*)(:|:[-a-z0-9_,]+,)"${SELECT_USERNAME}"(,|$'\n'|$)+ ]]; then
DATA_FILE_GROUP=$(sed "/^${SELECT_GROUPNAME}:/ s/:${SELECT_USERNAME}$/:/g;\
/^${SELECT_GROUPNAME}:/ s/:${SELECT_USERNAME},/:/g;\
/^${SELECT_GROUPNAME}:/ s/,${SELECT_USERNAME}$//g;\
/^${SELECT_GROUPNAME}:/ s/,${SELECT_USERNAME},/,/g" <<< ${DATA_FILE_GROUP})
fi
if [[ ${DATA_FILE_GSHADOW} =~ ($'\n'|^)+"${SELECT_GROUPNAME}":([^$'\n']*):([^$'\n']*)(:|:[-a-z0-9_,]+,)"${SELECT_USERNAME}"(,|$'\n'|$)+ ]]; then
DATA_FILE_GSHADOW=$(sed "/^${SELECT_GROUPNAME}:/ s/:${SELECT_USERNAME}$/:/g;\
/^${SELECT_GROUPNAME}:/ s/:${SELECT_USERNAME},/:/g;\
/^${SELECT_GROUPNAME}:/ s/,${SELECT_USERNAME}$//g;\
/^${SELECT_GROUPNAME}:/ s/,${SELECT_USERNAME},/,/g" <<< ${DATA_FILE_GSHADOW})
fi
done 4<<< "${SELECT_GROUPS//,/$'\n'}"
fi
done <<< "${SELECT_USERNAME_UID_LIST//,/$'\n'}"
echo "${DATA_FILE_GROUP}" > "${FILE_GROUP}"
echo "${DATA_FILE_GSHADOW}" > "${FILE_GSHADOW}"
}
#####################################################################################
###
### Функции получения от системы текущих настроек вида параметров от конфигурации ###
###
#####################################################################################
# Получить запись вида конфигурации USERADD из системного пользователя
# Если системный пользователь имеет настройки аналогичные настройкам создаваемого пользователя через .sysusers, то не выводим
# $1 # Опции не обязательные
# --not-only-changes # Отключить проверку изменений .sysusers, выводить любого пользователя системы
# $2 # Варианты пользователей, можно указывать несколько через пробел, кроме nobody
# <пуо> # Эквивалентно '@users @systems'
# @users # Все пользователи кроме системных, MIN_UID и MAX_UID взять из /etc/login.defs
# @systems # Только системные, SYS_MIN_UID и SYS_MAX_UID взять из /etc/login.defs
# @all # Все с UID от 0 до 65535
# <digital>-<digital> # Все пользователи диапазона
# <digital> # UID пользователя
# <username> # Имя пользователя
get_conf_useradd_from_system(){
local SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local FILE_SHADOW="${ROOTFS}/etc/shadow"
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
local FILE_DEFAULT_USERADD="${ROOTFS}/etc/default/useradd"
[[ -r ${FILE_PASSWD} ]] && local DATA_FILE_PASSWD=$(< ${FILE_PASSWD})
[[ -r ${FILE_SHADOW} ]] && local DATA_FILE_SHADOW=$(< ${FILE_SHADOW})
local DATA_FILE_DEFAULT_USERADD=$(< ${FILE_DEFAULT_USERADD})
[[ ${DATA_FILE_DEFAULT_USERADD} =~ ($'\n'|^)+[[:blank:]]*HOME=([^$'\n']+)($'\n'|$)+ ]] && local DEFAULT_HOME=${BASH_REMATCH[2]:-/home}
[[ ${DATA_FILE_DEFAULT_USERADD} =~ ($'\n'|^)+[[:blank:]]*SHELL=([^$'\n']+)($'\n'|$)+ ]] && local DEFAULT_SHELL=${BASH_REMATCH[2]:-/usr/bin/bash}
show_user(){
local SELECT_USER="$1"
local SELECT_PLAINPASSWORD SELECT_UID SELECT_GROUP SELECT_GECOS SELECT_HOME SELECT_SHELL
local SELECT_OPTIONAL=
local SELECT_EXTRAGROUPS=
[[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${SELECT_USER}:([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& SELECT_UID=${BASH_REMATCH[3]} \
&& SELECT_GROUP=${BASH_REMATCH[4]} \
&& SELECT_GECOS=${BASH_REMATCH[5]} \
&& SELECT_HOME=${BASH_REMATCH[6]} \
&& SELECT_SHELL=${BASH_REMATCH[7]}
[[ ${DATA_FILE_SHADOW} =~ ($'\n'|^)+${SELECT_USER}:([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_PASSWORD=${BASH_REMATCH[2]}
[[ ${SELECT_PASSWORD} == "!*" && ${SELECT_PLAINPASSWORD} != "x" ]] && SELECT_PASSWORD="${SELECT_PLAINPASSWORD}"
# Все дополнительные группы по умолчанию для всех пользователей ${USERGROUPS} ${DEFAULTGROUP}
#SYSTEM_EXTRAGROUPS="${USERGROUPS//,/$'\n'}"$'\n'"${DEFAULTGROUP//,/$'\n'}"
# Все дополнительные группы полученные из системы на пользователя ${SELECT_USER}
# У id -nrG первая група в выводе является основной, её убираем
USER_EXTRAGROUPS=$(${CHROOT} id -nrG ${SELECT_USER} | tr " " '\n' | tail +2 | sort -u)
# Нет основной группы пользовтеля - это хорошо но медленнее чем id
#local FILE_GROUP="${ROOTFS}/etc/group"
#[[ -r ${FILE_GROUP} ]] && local DATA_FILE_GROUP=$(< ${FILE_GROUP})
# USER_EXTRAGROUPS=$(${CHROOT} sed -Enr "s/^([^:]+):([^:]+):([^:]+):.*${SELECT_USER}.*/\1/p" <<< ${DATA_FILE_GROUP} | sort -u) #"
#SELECT_EXTRAGROUPS=$(comm --nocheck-order -13 <(printf "%s\n" ${USERGROUPS//,/ } ${DEFAULTGROUP//,/ } | sort -u) <(printf "%s\n" $(${CHROOT} id -nrG ${SELECT_USER}) | sort -u) | xargs | tr " " ",") #'
# Общие группы из по умолчанию и системные + только уникальные системные исключающие "по умолчанию"
#SELECT_EXTRAGROUPS=$(sort -u <<< "$(comm --nocheck-order -12 <(printf "${SYSTEM_EXTRAGROUPS}") <(printf "${USER_EXTRAGROUPS}"))"$'\n'"$(comm --nocheck-order -13 <(printf "${SYSTEM_EXTRAGROUPS}") <(printf "${USER_EXTRAGROUPS}"))" | xargs | tr " " ",") #"
SELECT_EXTRAGROUPS="${USER_EXTRAGROUPS//$'\n'/,}"
[[ -n ${SELECT_HOME} && ${SELECT_HOME} != "${DEFAULT_HOME}/${SELECT_USER}" ]] && SELECT_OPTIONAL+=" --home-dir ${SELECT_HOME}"
[[ -n ${SELECT_SHELL} && ${SELECT_SHELL} != ${DEFAULT_SHELL} ]] && SELECT_OPTIONAL+=" --shell ${SELECT_SHELL}"
[[ -r ${SELECT_HOME}/.config/locale.conf && $(< ${SELECT_HOME}/.config/locale.conf) =~ (^|$'\n')[[:blank:]]*LANG=([^$|$'\n']+)[[:blank:]]*($|$'\n') ]] && SELECT_OPTIONAL+=" --lang ${BASH_REMATCH[2]}"
if [[ -z ${NOT_ONLY_CHANGES} && ${SELECT_PASSWORD} == @("!*"|"!"|"*") ]]; then
local DATA_SYSUSERS_GROUP DATA_SYSUSERS_GECOS DATA_SYSUSERS_HOME DATA_SYSUSERS_SHELL
# Выриант1: u vault 319 "Vault daemon" /var/lib/vault
# Выриант2: u varnishlog 318:varnish "Varnish Cache Proxy"
[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'u'[[:blank:]]+${SELECT_USER}[[:blank:]]+(${SELECT_UID}|${SELECT_UID}:([^$'\n' ]*))[[:blank:]]*(\"([^$'\n']*)\"|\-)[[:blank:]]*([^$'\n' ]*)[[:blank:]]*([^$'\n' ]*)($'\n'|$)+ ]] \
&& DATA_SYSUSERS_GROUP=${BASH_REMATCH[3]} \
&& DATA_SYSUSERS_GECOS=${BASH_REMATCH[5]} \
&& DATA_SYSUSERS_HOME=${BASH_REMATCH[6]} \
&& DATA_SYSUSERS_SHELL=${BASH_REMATCH[7]}
[[ ${DATA_SYSUSERS_GECOS} == "-" ]] && unset DATA_SYSUSERS_GECOS
[[ ${DATA_SYSUSERS_HOME} == @(""|"-") ]] && DATA_SYSUSERS_HOME="/"
[[ ${DATA_SYSUSERS_SHELL} == @(""|"-") ]] && DATA_SYSUSERS_SHELL="/usr/bin/nologin"
# Поиск группы, если группа найдена, то номер как в системе, если не найдена, то номер должен быть по UID пользователя
[[ ${DATA_SYSUSERS_GROUP} != "" ]] && FIND_GROUP=${DATA_SYSUSERS_GROUP} || FIND_GROUP=${SELECT_USER}
[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+${FIND_GROUP}[[:blank:]]+${SELECT_GROUP}[[:blank:]]*([^$'\n' ]*)[[:blank:]]*([^$'\n' ]*)($'\n'|$)+ ]] \
&& DATA_SYSUSERS_GROUP=${SELECT_GROUP} || DATA_SYSUSERS_GROUP=${SELECT_UID}
DATA_SYSUSERS_EXTRAGROUPS=$(sed -Enr "s/^m ${SELECT_USER} (.*)/\1/p" <<< ${DATA_SYSUSERS} | sort -u | xargs | tr " " ",") #"
[[ ${SELECT_GROUP} == ${DATA_SYSUSERS_GROUP} && ${SELECT_EXTRAGROUPS} == ${DATA_SYSUSERS_EXTRAGROUPS} && ${SELECT_GECOS} == ${DATA_SYSUSERS_GECOS} && ${SELECT_HOME} == ${DATA_SYSUSERS_HOME} && ${SELECT_SHELL} == ${DATA_SYSUSERS_SHELL} ]] \
&& return 0
fi
echo "USERADD[${SELECT_USER}]='${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}'"
}
# is_systemd_user(){
# # Пользователь присутстует в systemd sysusers.d
# local SELECT_USER=$1
# [[ $(cat ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) =~ ($'\n'|^)+'u'[[:blank:]]+"${SELECT_USER}" ]] && return 1 || return 0
# [[ -d ${ROOTFS}/run/sysusers.d && $(cat ${ROOTFS}/run/sysusers.d/*.conf) =~ ($'\n'|^)+'u'[[:blank:]]+"${SELECT_USER}" ]] && return 1 || return 0
# }
[[ ${1} == "--not-only-changes" ]] && local NOT_ONLY_CHANGES=yes && shift
local PARAM_ALL="$@"
[[ -n ${PARAM_ALL} ]] || PARAM_ALL="@users @systems"
# Загрузить файлы которые совпадают в каталогах /usr/lib/sysusers.d/ и /usr/share/ublinux-sysusers/. И загрузить которые уникальные в /usr/lib/sysusers.d/
#[[ -z ${NOT_ONLY_CHANGES} ]] && local DATA_SYSUSERS=$(cat \
# $(comm --nocheck-order -12 <(cd /usr/lib/sysusers.d/ && ls -v1 *.conf | sed "s/\.conf//g") <(cd /usr/share/ublinux-sysusers/ && ls -v1 *.sysusers | sed "s/\.sysusers//g") | sed 's|^|/usr/share/ublinux-sysusers/|;s|$|.sysusers|') \
# <(echo) \
# $(comm --nocheck-order -23 <(cd /usr/lib/sysusers.d/ && ls -v1 *.conf | sed "s/\.conf//g") <(cd /usr/share/ublinux-sysusers/ && ls -v1 *.sysusers | sed "s/\.sysusers//g") | sed 's|^|/usr/lib/sysusers.d/|;s|$|.conf|') \
#)
# Загрузить данные из /usr/share/ublinux-sysusers/*.sysusers /usr/lib/sysusers.d/*.conf. Вжно что-бы имена файлов не содержали :
[[ -z ${NOT_ONLY_CHANGES} ]] && local DATA_SYSUSERS=$(grep -rEv '^\s*#|^\s*$' /usr/share/ublinux-sysusers/*.sysusers /usr/lib/sysusers.d/*.conf | sed -Enr "s/^[^:]+:(.*)/\1/p") #"
while IFS= read -r SELECT_PARAM; do
if [[ ${SELECT_PARAM} == "@users" ]]; then
# Все пользователи кроме системных
UID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
UID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=1000} -v USER_MAX=${UID_MAX:=65534} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} == "@systems" ]]; then
# Пользователи системные
UID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
UID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=500} -v USER_MAX=${UID_MAX:=999} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} == "@all" ]]; then
# Все пользователи
while IFS= read -ru4 SELECT_USER; do
show_user "${SELECT_USER}"
done 4< <(awk -F':' '$1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} =~ ^([[:digit:]]+)'-'*([[:digit:]]*)$ ]]; then
UID_MIN=${BASH_REMATCH[1]}
UID_MAX=${BASH_REMATCH[2]}
[[ -n ${UID_MAX} ]] || UID_MAX=${UID_MIN}
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=1000} -v USER_MAX=${UID_MAX:=65534} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif grep -q ^"${SELECT_PARAM}:" ${FILE_PASSWD} &>/dev/null; then
show_user "${SELECT_PARAM}"
fi
done <<< "${PARAM_ALL// /$'\n'}"
}
# Получить запись вида конфигурации USERSHADOW из системного пользователя: USERSHADOW[superadmin]='2024-03-06:0:99999:7::'
# Если системный пользователь имеет настройки аналогичные настройкам создаваемого пользователя через .sysusers, то не выводим
# $1 # Опции не обязательные
# --not-only-changes # Отключить проверку изменений .sysusers, выводить любого пользователя системы
# $2 # Варианты пользователей, можно указывать несколько через пробел, кроме nobody
# <пуо> # Эквивалентно '@users @systems'
# @users # Все пользователи кроме системных, MIN_UID и MAX_UID взять из /etc/login.defs
# @systems # Только системные, SYS_MIN_UID и SYS_MAX_UID взять из /etc/login.defs
# @all # Все с UID от 0 до 65535
# <digital>-<digital> # Все пользователи диапазона
# <digital> # UID пользователя
# <username> # Имя пользователя
get_conf_usershadow_from_system(){
local FILE_PASSWD="${ROOTFS}/etc/passwd"
local FILE_SHADOW="${ROOTFS}/etc/shadow"
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
[[ -r ${FILE_SHADOW} ]] && local DATA_FILE_SHADOW=$(< ${FILE_SHADOW})
show_user(){
local SELECT_USER="$1"
[[ ${DATA_FILE_SHADOW} =~ ($'\n'|^)+${SELECT_USER}:([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& 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')
if [[ -z ${NOT_ONLY_CHANGES} && -z ${SELECT_MINDAY} && -z ${SELECT_MAXDAY} && -z ${SELECT_WARN} && -z ${SELECT_INACTIVE} && -z ${SELECT_EXPIRE} ]]; then
local DATE_STARTUP_SYSTEM=$(date -d "$(cut -f1 -d. /proc/uptime) seconds ago" +'%Y-%m-%d') #"
[[ ${SELECT_LASTCHANGED} == ${DATE_STARTUP_SYSTEM} ]] && return 0
# Дата когда был установлен пакет и впервые добавлены пользователи
local DATE_SYSUSERS=$(stat --printf=%y ${ROOTFS}/usr/share/ublinux-sysusers/README | cut -d' ' -f1)
# Сравнить дату впервые созданных пользователей с датой установки пакета ublinux-sysusers
[[ ${SELECT_LASTCHANGED} == ${DATE_SYSUSERS} ]] && return 0
# # Найти файл 'sysusers' где встречается пользователь и сравнить дату создания файла с датой создания пользователя
# FILE_NAME_SYSTEMD=$(grep -E "^u[[:blank:]]+${SELECT_USER}" ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers ${ROOTFS}/usr/share/ublinux-sysusers/dynamic/*.sysusers 2>/dev/null | cut -d: -f1 | xargs stat --printf=%y | cut -d' ' -f1;)
fi
echo "USERSHADOW[${SELECT_USER}]='${SELECT_LASTCHANGED}:${SELECT_MINDAY}:${SELECT_MAXDAY}:${SELECT_WARN}:${SELECT_INACTIVE}:${SELECT_EXPIRE}'"
}
[[ ${1} == "--not-only-changes" ]] && local NOT_ONLY_CHANGES=yes && shift
local PARAM_ALL="$@"
[[ -n ${PARAM_ALL} ]] || PARAM_ALL="@users @systems"
while IFS= read -r SELECT_PARAM; do
if [[ ${SELECT_PARAM} == "@users" ]]; then
# Все пользователи кроме системных
UID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
UID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=1000} -v USER_MAX=${UID_MAX:=65534} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} == "@systems" ]]; then
# Пользователи системные
UID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
UID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_UID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=500} -v USER_MAX=${UID_MAX:=999} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} == "@all" ]]; then
# Все пользователи
while IFS= read -ru4 SELECT_USER; do
show_user "${SELECT_USER}"
done 4< <(awk -F':' '$1 != "nobody" { print $1}' ${FILE_PASSWD})
elif [[ ${SELECT_PARAM} =~ ^([[:digit:]]+)'-'*([[:digit:]]*)$ ]]; then
UID_MIN=${BASH_REMATCH[1]}
UID_MAX=${BASH_REMATCH[2]}
[[ -n ${UID_MAX} ]] || UID_MAX=${UID_MIN}
while IFS= read -r SELECT_USER; do
show_user "${SELECT_USER}"
done < <(awk -F':' -v USER_MIN=${UID_MIN:=1000} -v USER_MAX=${UID_MAX:=65534} '$3 >= USER_MIN && $3 <= USER_MAX && $1 != "nobody" { print $1}' ${FILE_PASSWD})
elif grep -q ^"${SELECT_PARAM}:" ${FILE_PASSWD} &>/dev/null; then
show_user "${SELECT_PARAM}"
fi
done <<< "${PARAM_ALL// /$'\n'}"
}
# Получить запись вида конфигурации GROUPADD из систеных групп
# Если системная группа имеет настройки аналогичные настройкам создаваемой группы через .sysusers, то не выводим
# $1 # Опции не обязательные
# --not-only-changes # Отключить проверку изменений .sysusers, выводить любую группу системы
# $2 # Варианты групп, можно указывать несколько через пробел, кроме nobody
# <пусто> # Эквивалентно '@groups @systems'
# @groups # Все кроме системных, MIN_GID и MAX_GID взять из /etc/login.defs
# @systems # Только системные, SYS_MIN_GID и SYS_MAX_GID взять из /etc/login.defs
# @all # Все c GID от 0 до 65535
# <digital>-<digital> # Все пользователи диапазона
# <digital> # GID группы
# <groupname> # Имя группы
get_conf_groupadd_from_system(){
local FILE_GROUP="${ROOTFS}/etc/group"
local FILE_GSHADOW="${ROOTFS}/etc/gshadow"
local FILE_LOGINDEFS="${ROOTFS}/etc/login.defs"
[[ -r ${FILE_GROUP} ]] && local DATA_FILE_GROUP=$(< ${FILE_GROUP})
[[ -r ${FILE_GSHADOW} ]] && local DATA_FILE_GSHADOW=$(< ${FILE_GSHADOW})
show_group(){
local SELECT_GROUP="$1"
local SELECT_PLAINPASSWORD SELECT_GID SELECT_MEMBERS
[[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}:([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_PLAINPASSWORD=${BASH_REMATCH[2]} \
&& SELECT_GID=${BASH_REMATCH[3]} \
&& SELECT_MEMBERS=${BASH_REMATCH[4]}
local SELECT_PASSWORD SELECT_ADMINISTRATORS SELECT_GMEMBERS
[[ ${DATA_FILE_GSHADOW} =~ ($'\n'|^)+${SELECT_GROUP}:([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]] \
&& SELECT_PASSWORD=${BASH_REMATCH[2]} \
&& SELECT_ADMINISTRATORS=${BASH_REMATCH[3]} \
&& SELECT_GMEMBERS=${BASH_REMATCH[4]}
[[ ${SELECT_PASSWORD} == "!*" && ${SELECT_PLAINPASSWORD} != "x" ]] && SELECT_PASSWORD="${SELECT_PLAINPASSWORD}"
local SELECT_OPTIONAL
if [[ -z ${NOT_ONLY_CHANGES} && ${SELECT_PASSWORD} == @("!*"|"!") && ${SELECT_MEMBERS} == ${SELECT_GMEMBERS} && -z ${SELECT_ADMINISTRATORS} ]]; then
# Выбираем пользователей которые входят в выбранную группу из systemd sysusers
local DATA_SYSUSERS_MEMBERS=$(sed -Enr "s/^m[[:blank:]]+(.*)[[:blank:]]+${SELECT_GROUP}/\1/p" <<< ${DATA_SYSUSERS} | sort -u | xargs | tr " " ",") #"
local RETURN_DATA_SYSUSERS_MEMBERS
[[ -n ${DATA_SYSUSERS_MEMBERS} ]] && SELECT_MEMBERS=$(sort -u <<< ${SELECT_MEMBERS//,/$'\n'} | xargs | tr " " ",")
[[ ${SELECT_MEMBERS} == ${DATA_SYSUSERS_MEMBERS} ]] && RETURN_DATA_SYSUSERS_MEMBERS=yes || RETURN_DATA_SYSUSERS_MEMBERS=no
# Выбираем GID группы из systemd sysusers. По явному наличию 'g x2godesktopsharing 500'
local DATA_SYSUSERS_GID=$(sed -Enr "s/^g[[:blank:]]+${SELECT_GROUP}[[:blank:]]+([[:digit:]]+).*/\1/p" <<< ${DATA_SYSUSERS} | head -1) #"
# Выбираем GID группы из systemd sysusers. Если нет явного, то GID по UID пользователя
[[ -n ${DATA_SYSUSERS_GID} ]] || DATA_SYSUSERS_GID=$(sed -Enr "s/^u[[:blank:]]+${SELECT_GROUP}[[:blank:]]+([[:digit:]]+).*/\1/p" <<< ${DATA_SYSUSERS} | head -1) #"
local RETURN_DATA_SYSUSERS_GID
[[ -n ${DATA_SYSUSERS_GID} ]] && [[ ${SELECT_GID} == ${DATA_SYSUSERS_GID} ]] && RETURN_DATA_SYSUSERS_GID=yes || RETURN_DATA_SYSUSERS_GID=no
# Если в systemd sysusers MEMBERS и GID совпадают с системными, то выход
[[ ${RETURN_DATA_SYSUSERS_MEMBERS} == "yes" && ${RETURN_DATA_SYSUSERS_GID} == "yes" ]] && return 0
# Если в systemd sysusers MEMBERS совпадает с системным, а GID не указан (динамический), то выход
# Если не показывать такие группы, то можно ложно не вывести, если вдруг намеренно пользоваель указал GID у динамической группы
# Из за возможной ошибки, отключаю
#[[ ${RETURN_DATA_SYSUSERS_MEMBERS} == "yes" && -z ${RETURN_DATA_SYSUSERS_GID} ]] && return 0
fi
echo "GROUPADD[${SELECT_GROUP}]='${SELECT_MEMBERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}'"
}
[[ ${1} == "--not-only-changes" ]] && local NOT_ONLY_CHANGES=yes && shift
local PARAM_ALL="$@"
[[ -n ${PARAM_ALL} ]] || PARAM_ALL="@groups @systems"
# Загрузить файлы которые совпадают в каталогах /usr/lib/sysusers.d/ и /usr/share/ublinux-sysusers/. И загрузить которые уникальные в /usr/lib/sysusers.d/
#[[ -z ${NOT_ONLY_CHANGES} ]] && local DATA_SYSUSERS=$(cat \
# $(comm --nocheck-order -12 <(cd /usr/lib/sysusers.d/ && ls -v1 *.conf | sed "s/\.conf//g") <(cd /usr/share/ublinux-sysusers/ && ls -v1 *.sysusers | sed "s/\.sysusers//g") | sed 's|^|/usr/share/ublinux-sysusers/|;s|$|.sysusers|') \
# <(echo) \
# $(comm --nocheck-order -23 <(cd /usr/lib/sysusers.d/ && ls -v1 *.conf | sed "s/\.conf//g") <(cd /usr/share/ublinux-sysusers/ && ls -v1 *.sysusers | sed "s/\.sysusers//g") | sed 's|^|/usr/lib/sysusers.d/|;s|$|.conf|') \
#)
# Загрузить данные из /run/sysusers.d/*.sysusers /usr/lib/sysusers.d/*.conf. Вжно что-бы имена файлов не содержали :
[[ -z ${NOT_ONLY_CHANGES} ]] && local DATA_SYSUSERS=$(grep -rEv '^\s*#|^\s*$' /run/sysusers.d/*.conf /usr/lib/sysusers.d/*.conf | sed -Enr "s/^[^:]+:(.*)/\1/p") #"
while IFS= read -r SELECT_PARAM_ALL; do
if [[ ${SELECT_PARAM_ALL} == "@groups" ]]; then
# Все группы кроме системных
GID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*GID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
GID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*GID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_GROUP; do
show_group "${SELECT_GROUP}"
done < <(awk -F':' -v GROUP_MIN=${GID_MIN:=1000} -v GROUP_MAX=${GID_MAX:=60000} '$3 >= GROUP_MIN && $3 <= GROUP_MAX && $1 != "nobody" { print $1}' ${FILE_GROUP})
elif [[ ${SELECT_PARAM_ALL} == "@systems" ]]; then
# Группы системные
GID_MIN=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_GID_MIN[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
GID_MAX=$([[ $(< "${FILE_LOGINDEFS}") =~ [^#[^:blank:]]*SYS_GID_MAX[[:blank:]]+([[:digit:]]+) ]]; echo -n "${BASH_REMATCH[1]}")
while IFS= read -r SELECT_GROUP; do
show_group "${SELECT_GROUP}"
done < <(awk -F':' -v GROUP_MIN=${GID_MIN:=500} -v GROUP_MAX=${GID_MAX:=999} '$3 >= GROUP_MIN && $3 <= GROUP_MAX && $1 != "nobody" { print $1}' ${FILE_GROUP})
elif [[ ${SELECT_PARAM_ALL} == "@all" ]]; then
# Все группы
while IFS= read -ru4 SELECT_GROUP; do
show_group "${SELECT_GROUP}"
done 4< <(awk -F':' '$1 != "nobody" { print $1}' ${FILE_GROUP})
elif [[ ${SELECT_PARAM_ALL} =~ ^([[:digit:]]+)'-'*([[:digit:]]*)$ ]]; then
GID_MIN=${BASH_REMATCH[1]}
GID_MAX=${BASH_REMATCH[2]}
[[ -n ${GID_MAX} ]] || GID_MAX=${GID_MIN}
while IFS= read -r SELECT_GROUP; do
show_group "${SELECT_GROUP}"
done < <(awk -F':' -v GROUP_MIN=${GID_MIN:=1000} -v GROUP_MAX=${GID_MAX:=60000} '$3 >= GROUP_MIN && $3 <= GROUP_MAX && $1 != "nobody" { print $1}' ${FILE_GROUP})
elif grep -q ^"${SELECT_PARAM_ALL}:" ${FILE_GROUP} &>/dev/null; then
show_group "${SELECT_PARAM_ALL}"
fi
done <<< "${PARAM_ALL// /$'\n'}"
}
#####################################################################################
#####################################################################################
detectDE(){
[[ -z ${SESSION} && ${KDE_FULL_SESSION} == true ]] && SESSION=kde
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == XFCE ]] && SESSION=xfce
[[ -z ${SESSION} && ${DESKTOP_SESSION} == LXDE ]] && SESSION=lxde
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == LXQt ]] && SESSION=lxqt
[[ -z ${SESSION} && ${DESKTOP_SESSION} == i3 ]] && SESSION=i3
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == i3 ]] && SESSION=i3
[[ -z ${SESSION} && ${DESKTOP_SESSION} == i3term ]] && SESSION=i3term
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == i3term ]] && SESSION=i3term
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == MATE ]] && SESSION=mate
[[ -z ${SESSION} && ${XDG_CURRENT_DESKTOP} == Pantheon ]] && SESSION=pantheon
if [[ -z ${SESSION} ]]; then
SESSION_COMMANDS=$(ps xo args)
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+"xfce4-session"($'\n'|$)+ ]] && SESSION=xfce
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"kdeinit"($'\n'|$)+ ]] && SESSION=kde
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"i3"($'\n'|$)+ ]] && SESSION=i3
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"i3term"($'\n'|$)+ ]] && SESSION=i3term
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"gnome-panel"($'\n'|$)+ ]] && SESSION=gnome
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"gnome-shell"($'\n'|$)+ ]] && SESSION=gnome-shell
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)"plasmashell"($'\n'|$)+ ]] && SESSION=plasma
[[ -z ${SESSION} && ${SESSION_COMMANDS} =~ ($'\n'|^)+([^$'\n']*)" --session=pantheon"([^$'\n']*)($'\n'|$)+ ]] && SESSION=pantheon
fi
[[ -z ${SESSION} && -x /usr/bin/startxfce4 ]] && SESSION=xfce
[[ -z ${SESSION} && -x /usr/bin/startlxde ]] && SESSION=lxde
[[ -z ${SESSION} && -x /usr/bin/startlxqt ]] && SESSION=lxqt
[[ -z ${SESSION} && -x /usr/bin/plasmashell ]] && SESSION=plasma
[[ ${SESSION} == "kde" && -x /usr/bin/plasmashell ]] && SESSION=plasma
# SESSION=budgie
# SESSION=cinnamon
# SESSION=sway
echo ${SESSION}
}
# ===========================================================
# liblinuxlive functions
# ===========================================================
debug_log(){
if grep -q "debug" /proc/cmdline ; then
echo "- debug: $*" >&2
log "- debug: $*"
fi
}
log(){
echo "$@" 2>/dev/null >>/var/log/ublinux.log
}
debug_mode(){
if [ "$(cmdline_parameter debug)" -o "$DEBUGMODE" == "yes" ] ; then
name=$(basename $0)
slash="/"
[ "$(pwd)" == "/union" ] && slash=""
if ! test -f ${slash}var/log/ublinux/${name}.log ; then
echo "$0 -- debug mode enabled"
test -d ${slash}var/log/ublinux || mkdir -p ${slash}var/log/ublinux
echo $(date) > ${slash}var/log/ublinux/${name}.log || echo "can not create log file"
$0 "$@" 2>&1 | tee -a ${slash}var/log/ublinux/${name}.log
exit 0
fi
fi
}
echodebug(){
[ "$DEBUG_IS_ENABLED" -o "$DEBUGMODE" == "yes" ] && echo "$1"
if [ -n "$2" ] ;then
command=$2
shift ; shift
if [ -z $1 ] ;then
$command
else
$command "$@"
fi
fi
}
# Create module
# call mksquashfs with apropriate arguments
# $1 = directory which will be compressed to squashfs module
# $2 = output filesystem module file
# $3..$9 = optional arguments like -keep-as-directory or -b 123456789
create_module(){
. /usr/lib/ublinux/default
. /etc/ublinux/config 2>/dev/null
. /etc/ublinux/system 2>/dev/null
echo " $@ " | grep -Eq ' -comp | -noD ' && MKSQFS_OPTS=
mksquashfs "$1" "$2" $MKSQFS_OPTS $3 $4 $5 $6 $7 $8 $9 -noappend >/dev/null || return 1
chmod 444 "$2"
}
# look into cmdline and echo $1 back if $1 is set
# $1 = value name, case sensitive, for example 'debug'
cmdline_parameter(){
. /etc/ublinux/config 2>/dev/null || . etc/ublinux/config 2>/dev/null
echo -n " $CMDLINE " | cat /proc/cmdline - 2>/dev/null | tr "[:cntrl:]" " " | grep -Em1 -o "(^|[[:space:]])$1([[:space:]]|\$)" | head -1 | tr -d " "
}
# look into cmdline and echo value of $1 option
# $1 = value name, case sensitive, for example 'changes'
cmdline_value(){
. /etc/ublinux/config 2>/dev/null || . etc/ublinux/config 2>/dev/null
echo -n " $CMDLINE " | cat /proc/cmdline - 2>/dev/null | tr "[:cntrl:]" " " | grep -Em1 -o "(^|[[:space:]])$1=[^[:space:]]+" | head -1 | cut -d "=" -f 2-
}
# Find and run all scripts from the given module
# This function is used by the activate and deactivate script when the distro
# is already started, not during live setup
# $1 = mounted module full path
# $2..$n = optional arguments for the scripts, eg. 'start'
find_n_run_scripts(){
debug_log "find_n_run_scripts" "$*"
local MOD
MOD="$1"
shift
RCPATH=/etc/init.d
[ -d $RCPATH ] || RCPATH=/etc/rc.d/init.d
RUNLEVEL=$(runlevel | awk '{print $2}')
[ -d "/etc/rc$RUNLEVEL.d" ] && RCPATH=/etc/rc$RUNLEVEL.d
[ -d "/etc/rc.d/rc$RUNLEVEL.d" ] && RCPATH=/etc/rc.d/rc$RUNLEVEL.d
RUNSCRIPTS="$MOD$RCPATH|$MOD/usr/lib/ublinux/rc.local|$MOD/usr/lib/ublinux/rc.post"
echo $@ | grep -q start || RUNSCRIPTS="$MOD$RCPATH"
find "$MOD" | grep -E "$RUNSCRIPTS" | cut -b "${#MOD}"- | cut -b 2- | xargs -n 1 -r readlink -f | sort -u | \
while read SCRIPT; do
if [ "$SCRIPT" != "" -a -x "$SCRIPT" -a ! -d "$SCRIPT" ]; then
# call the script by real path, not from the module
log "starting '"$SCRIPT" $@'"
"${SCRIPT}" "$@"
fi
done
}
# test if the script is started by root user. If not, exit
allow_only_root(){
if [ "0$UID" -ne 0 ]; then
echo "Only root can run $(basename $0)"; exit 1
fi
}
#####################
# Hotkeys functions #
#####################
notify_send(){
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_UID=$(id -u ${FIND_USER})
[[ -n ${FIND_DISPLAY} && -n ${FIND_USER} && -n ${FIND_UID} ]] || return 1
sudo -u ${FIND_USER} DISPLAY=${FIND_DISPLAY} DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${FIND_UID}/bus notify-send "$@"
}
show_run(){
DE=$(detectDE)
if [ "$DE" = "kde" -o "$DE" = "plasma" ] ; then
krunner
elif [ "$DE" = "gnome" ] ; then
gnome-panel-control --run-dialog
elif [ "$DE" = "lxqt" ] ; then
lxqt-runner
else
rofi -config /usr/share/ublinux/i3/rofi.cfg -show
fi
}
lock_session(){
DE=$(detectDE)
# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Lock
xterm -geometry 0x0+1+1 -e "dbus-send --dest=org.freedesktop.ScreenSaver --print-reply /ScreenSaver org.freedesktop.ScreenSaver.Lock"
if [ "$DE" != "kde" -a "$DE" != "plasma" ] ; then
ps -U $(id -u) | grep -q xscreensaver || xscreensaver -no-splash &
sleep 0.5s
xscreensaver-command -lock
fi
}
xss_slideshow(){
chbg -xscreensaver -randomize -R -effect 1 -interval 0.2 -mode smart -max_size 100 -R /usr/share/ublinux/screensaver/Default >/dev/null 2>&1
}
xss_heartbeat(){
. /usr/lib/ublinux/default
. /etc/ublinux/config 2>/dev/null
SSAVERBLOCKAPPS="$(echo "$SSAVERBLOCKAPPS"| tr ',; ' '|' )"
bash -c "while true ;do top -bn1 -u $(id -un) | awk '{ print \$7 FS \$NF }' | grep ^[1-9] | grep -Eq \"$SSAVERBLOCKAPPS\" && xscreensaver-command -deactivate >/dev/null ; sleep 20s ; done " &
}
show_hotkeys(){
MSG1=$(gettext -s "UBLinux magic keys:")
echo "$MSG1" > /tmp/listkeys
echo " " >> /tmp/listkeys
cat $HOME/.xbindkeysrc | sed -e 's/^".*"//' -e 's/Mod4/WIN/' -e '/^#.*#/ d' -e '/^ *$/ d' -e 's/^# *//' | while read a ; do
gettext -s "$a" >> /tmp/listkeys
done
mdialog --textbox /tmp/listkeys 600 600
rm -f /tmp/listkeys
}
show_info(){
. /usr/lib/os-release
FILE_INFO="/tmp/info.txt"
LIVECDNAME="$NAME"
UPTIME=$(uptime | awk '{print "time - "$1", up - "$3}').
RAM=$(free -m | grep Mem | awk '{ print "total - "$2", free - "$4}')
SWAP=$(free -m | grep Swap | awk '{ print "total - "$2", free - "$4}')
CPU="$(cat /proc/cpuinfo | sed -e '/model name/!d' -e 's/^.*://')"
CPUARCH=$(uname -p)
KERNEL=$(uname -r)
VIDEO=$(lspci | sed -e '/VGA/!d' -e 's/^.*://')
GLXINFO=$(glxinfo | sed '2,3!d')
AUDIO=$(lspci | sed -e '/Audio/!d' -e 's/^.*://')
CMDLINE=$(< /proc/cmdline)
VERSION=$(< /etc/ublinux-release)
if [ $(cmdline_parameter unionfs) ] ;then
PROF_SIZE=$(df -h / |grep unionfs | awk '{print " ["$5"] total - "$2", free - "$4}')
else
PROF_SIZE=$(df -h / |grep aufs | awk '{print " ["$5"] total - "$2", free - "$4}')
fi
echo "$LIVECDNAME ($VERSION)" > "${FILE_INFO}"
echo "UPTIME: $UPTIME" >> "${FILE_INFO}"
echo "KERNEL: $KERNEL" >> "${FILE_INFO}"
echo "RAM: $RAM" >> "${FILE_INFO}"
echo "SWAP: $SWAP" >> "${FILE_INFO}"
[ "$(cat /proc/cmdline | grep changes= )" ] && echo "PROFILE: $PROF_SIZE" >> "${FILE_INFO}"
echo -e "CPU: ($CPUARCH) \n$CPU" >> "${FILE_INFO}"
echo "VIDEO: $VIDEO" >> "${FILE_INFO}"
echo "$GLXINFO" >> "${FILE_INFO}"
echo "AUDIO: $AUDIO" >> "${FILE_INFO}"
echo "CMDLINE: $CMDLINE" >> "${FILE_INFO}"
echo "MODULES:" >> "${FILE_INFO}"
grep squashfs /proc/mounts | awk '{print $2}' | sort >> "${FILE_INFO}"
zenity --text-info \
--width=640 \
--height=480 \
--title="Show info" \
--filename="${FILE_INFO}"
rm -f "${FILE_INFO}"
}
touchpad(){
MSG2=$(gettext -s "Touchpad disabled, WIN+t to enable again")
if [ $(synclient -l | grep TouchpadOff | awk '{ print $3 }') -eq 0 ] ;then
synclient TouchpadOff=1
mdialog --passivepopup "$MSG2"
else
synclient TouchpadOff=0
fi
}
rfswitch(){
MSG3=$(gettext -s "bluetooth, WI-FI interfaces disabled, WIN+w to enable again")
rfkill list | grep yes
if [ $? -eq 0 ] ;then
rfkill unblock all
else
rfkill block all
mdialog --passivepopup "$MSG3"
fi
}
recordvideo(){
MSG1=$(gettext -s "Recording are stoped, please wait for encoding")
MSG2=$(gettext -s "Video are encoded and placed to your home dir")
RMDOPT=
. /etc/ublinux/config 2>/dev/null
ps -U $UID | grep -q pulseaudio && RMDOPT="$RMDOPT --device pulse"
PID=$(ps -U $UID -o pid,comm | grep recordmydesktop | awk '{print $1}')
if [ -z "$PID" ] ;then
recordmydesktop $RMDOPT &
else
kill "$PID"
mdialog --passivepopup "$MSG1"
bash -c "while true ;do ps -A -o pid | grep -q ^$PID$ || break ; sleep 1s ;done ; mdialog --passivepopup \"$MSG2\""
fi
}
show_network(){
echo "netstat --inet" > ~/network.txt
netstat --inet >> ~/network.txt
echo -e "\nlsof -i" >> ~/network.txt
/usr/sbin/lsof -i >> ~/network.txt
mdialog --textbox $HOME/network.txt 600 250
rm -f $HOME/info.txt
}
google_search(){
xclip -o | sed -r '2~1d;s/(^\s+|\s+$)//g;s/%/%25/g;s/#/%23/g;s/\$/%24/g;s/&/%26/g;s/\+/%2B/;s/,/%2C/g;s/:/%3A/g;s/;/%3B/g;s/=/%3D/g;s/\?/%3F/g;s/@/%40/g;s/\s/+/g' | awk '{print "http://www.google.ru/search?hl=ru&q=" $1}' | xargs firefox -new-tab
}
translate_en_rus(){
[ "$1" == "passive" ] && mdialog --passivepopup "$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xclip -o | sed "s/[\"'<>]//g")&sl=auto&tl=ru" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
[ "$1" == "msgbox" ] && mdialog --msgbox "$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xclip -o | sed "s/[\"'<>]//g")&sl=auto&tl=ru" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
[ "$1" == "firefox" ] && xclip -o | sed -r '2~1d;s/(^\s+|\s+$)//g;s/%/%25/g;s/#/%23/g;s/\$/%24/g;s/&/%26/g;s/\+/%2B/;s/,/%2C/g;s/:/%3A/g;s/;/%3B/g;s/=/%3D/g;s/\?/%3F/g;s/@/%40/g;s/\s/+/g' | awk '{print "translate.google.com/translate_t?hl=en#en|ru|" $1}' | xargs firefox -new-tab
}
translate_rus_en(){
[ "$1" == "passive" ] && mdialog --passivepopup "$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xclip -o | sed "s/[\"'<>]//g")&sl=auto&tl=en" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
[ "$1" == "msgbox" ] && mdialog --msgbox "$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xclip -o | sed "s/[\"'<>]//g")&sl=auto&tl=en" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
[ "$1" == "firefox" ] && xclip -o | sed -r '2~1d;s/(^\s+|\s+$)//g;s/%/%25/g;s/#/%23/g;s/\$/%24/g;s/&/%26/g;s/\+/%2B/;s/,/%2C/g;s/:/%3A/g;s/;/%3B/g;s/=/%3D/g;s/\?/%3F/g;s/@/%40/g;s/\s/+/g' | awk '{print "translate.google.com/translate_t?hl=ru#ru|en|" $1}' | xargs firefox -new-tab
}
open_url(){
xclip -o | sed -n 1p | xargs firefox -new-tab
}
userkeys(){
string=$(head -n $1 $HOME/.userkeys | tail -n 1)
TMPFILE=$HOME/tmp/userkey-$(id -un)
> $TMPFILE
echo "#!/bin/bash" > $TMPFILE
echo "$string" >> $TMPFILE
chmod +x $TMPFILE
$TMPFILE
rm -f $TMPFILE
}
screen_scale(){
scale_[1]=1x1
scale_[2]=1x1.2
scale_[3]=1.2x1.2
scale_[4]=1.2x1.5
scale_[5]=1.5x1.5
scale=2
[ -f /tmp/scale ] && scale=$(cat /tmp/scale)
xrandr --output LVDS1 --scale ${scale_[$scale]}
if [ $scale == 5 ] ; then
echo 1 > /tmp/scale
else
echo $(expr $scale + 1) > /tmp/scale
fi
}
#####################################
### ::: UBCONFIG EXEC ::: ###
#####################################
ubconfig_exec_system(){
SYSCONF=${SYSCONF//${ROOTFS}/}
local SECTION_NAME=$1
local COMMAND_MODE_VAR=$2
local NAME_VAR=$3
local VALUE_VAR=$4
local NO_FIND_EXCUTE=
case "[${SECTION_NAME}]" in
"[${SYSCONF}/config]"|"[config]")
case "${NAME_VAR}" in
# --> OLD config
HOSTNAME) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/30-network-hostname ;;
SERVICESSTART|SERVICESNOSTART|SERVICESMASK|SERVICESUNMASK|\
SERVICES_ENABLE|SERVICES_DISABLE|SERVICES_MASK|SERVICES_UNMASK)
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/20-services exec_services_enabledisable "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/20-services exec_services_startstop_live "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
# <-- OLD config
;;
DM_HINT_PASSWORD) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_99_dm_hint_password "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/system]"|"[system]")
case "${NAME_VAR}" in
ENVIRONMENT) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/10-system exec_environment ;;
HOSTNAME) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/30-network-hostname ;;
SERVICESSTART|SERVICESNOSTART|SERVICESMASK|SERVICESUNMASK|\
SERVICES_ENABLE|SERVICES_DISABLE|SERVICES_MASK|SERVICES_UNMASK)
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/20-services exec_services_enabledisable "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/20-services exec_services_startstop_live "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
;;
AUTHPAM) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/40-authpam "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
AUTHPAM\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/40-authpam "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/users]"|"[users]")
case "${NAME_VAR}" in
DEFAULTROOTPASSWD) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_01_defaultrootpasswd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
DEFAULTPASSWD) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_02_defaultpasswd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
DEFAULTGROUP) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_03_add_groups "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
ADMGROUPS) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_03_add_groups "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
USERGROUPS) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_03_add_groups "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
NEEDEDUSERS) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_05_neededusers "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
USERADD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_06_useradd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
USERSHADOW\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_07_usershadow "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
GROUPADD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit/10-accounts exec_04_groupadd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
USERADD_SYNC) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/25-accounts-sync exec_01_useradd_sync "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
USERADD_SYNC\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/25-accounts-sync exec_01_useradd_sync "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
GROUPADD_SYNC) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/25-accounts-sync exec_02_groupadd_sync "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
GROUPADD_SYNC\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/25-accounts-sync exec_02_groupadd_sync "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/update]"|"[update]")
case "${NAME_VAR}" in
REPOSITORY) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_01_repository "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
REPOSITORY\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_01_repository "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
REPOPUBLIC_NET) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_02_repopublic_net "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
REPOPUBLIC_WEB\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_03_repopublic_web "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
REPOPUBLIC_CACHE) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_04_repopublic_cache "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
REPOPUBLIC_CACHE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_04_repopublic_cache "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
AUTOUPDATE) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_autoupdate "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
AUTOUPDATE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/43-repository exec_autoupdate "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/mount]"|"[mount]")
case "${NAME_VAR}" in
AUTOMOUNT_SHARE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/09-automount exec_mount_direct ;;
PUBLICDIR) ${ROOTFS}/usr/lib/ublinux/rc.post.d/23-publicdir ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/boot]"|"[boot]")
case "${NAME_VAR}" in
GRUB_TIMEOUT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_timeout ;;
GRUB_DEFAULT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_default ;;
GRUB_SUPERUSERS) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_superusers ;;
GRUB_PASSWORD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_password ;;
GRUB_BOOT_SILENT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_boot_silent ;;
GRUB_TERMINAL_INPUT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_terminal_input ;;
GRUB_TERMINAL_OUTPUT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_terminal_output ;;
GRUB_PLAY) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_play ;;
GRUB_CMDLINE_LINUX) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_cmdline_linux ;;
GRUB_VMLINUZ_FILES) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_vmlinuz_file ;;
GRUB_UBLINUX_FILES) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_ublinux_file ;;
GRUB_ADDON_FILES) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_addon_file ;;
KERNEL_BOOT) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_kernel_boot ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/logging]"|"[logging]")
case "${NAME_VAR}" in
AUDITD) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_auditd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
setsid ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_auditd_live & ;;
AUDITD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_auditd "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
setsid ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_auditd_live & ;;
JOURNALD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_journald "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
setsid ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_journald_live & ;;
LOGROTATE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_logrotate "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}"
setsid ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_logrotate_live "${NAME_VAR}" & ;;
SYSTEMD_COREDUMP\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/24-logging exec_systemd_coredump "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
JOURNALD_NOTIFY\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.pamsession.d/02-journald-notify exec_01_journald_notify "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/server]"|"[server]")
case "${NAME_VAR}" in
STORAGE_CONTAINERS_PATH) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/80-server-storage exec_storage_containers_path ;;
STORAGE_DOCKER_PATH) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/80-server-storage exec_storage_docker_path ;;
STORAGE_LIBVIRT_PATH) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/80-server-storage exec_storage_libvirt_path ;;
UBPILE_DB) ${ROOTFS}/usr/lib/ublinux/rc.local.d/98-ubpile exec_01_ubpile_db "${COMMAND_MODE_VAR}" ;; # Специально без параметров
UBPILE_DB\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/98-ubpile exec_01_ubpile_db "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
UBPILE) ${ROOTFS}/usr/lib/ublinux/rc.local.d/98-ubpile exec_02_ubpile "${COMMAND_MODE_VAR}" ;; # Специально без параметров, что-бы читались дефолтные параметры при =admin и =worker
UBPILE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/98-ubpile exec_02_ubpile "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
UBPILE_REVERSE_PROXY) ${ROOTFS}/usr/lib/ublinux/rc.local.d/98-ubpile exec_03_ubpile_reverse_proxy "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/desktop]"|"[desktop]")
case "${NAME_VAR}" in
MULTISEAT_SIMPLE\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/55-multiseat ;;
AUTOEXEC) ${ROOTFS}/usr/lib/ublinux/rc.desktop/all/autoexec "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
AUTOEXEC\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.desktop/all/autoexec "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
LIGHTDM_XDMCP) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/60-lightdm-settings exec_lightdm_xdmcp "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
LIGHTDM_XDMCP\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/60-lightdm-settings exec_lightdm_xdmcp "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
LIGHTDM_GREETER\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/60-lightdm-settings exec_lightdm_greeter "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
X11VNC\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.local.d/41-x11vnc ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/video]"|"[video]")
case "${NAME_VAR}" in
VGADRV_AUTO) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_vgadrv_auto ;;
VGADRV_NOFREE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/50-xorg ;;
XORG_MONITOR\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_xorg_monitor ;;
XORG_EXT) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_xorg_ext;;
XORG_DPI) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/63-xorg-dpi
${ROOTFS}/usr/lib/ublinux/rc.xorg/20-video-xorg-dpi ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/save]"|"[save]")
case "${NAME_VAR}" in
SAVE_ALL_CACHE) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/85-save-cache ;;
SAVE_ROOTCOPY_CHANGES) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/86-save-rootcopy ;;
SAVE_ROOTCOPY_INCLUDE) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/86-save-rootcopy ;;
SAVE_ROOTCOPY_EXCLUDE) ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/86-save-rootcopy ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/network]"|"[network]")
case "${NAME_VAR}" in
DOMAIN) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd exec_domain "${COMMAND_MODE_VAR}" ;;
DOMAIN\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;;
REALM_SSSD\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;;
REALM_PERMIT_USER) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;;
REALM_PERMIT_GROUP) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/23-realmd domain_configure_live "${COMMAND_MODE_VAR}" ;;
NTPSERVERS) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/21-ntp "${COMMAND_MODE_VAR}" ;;
NETWORK\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.network.d/10-network exec_network ;;
PROXY_SYSTEM\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/31-network-proxy-system ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/security]"|"[security]")
case "${NAME_VAR}" in
OPENSSL_ENGINE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/56-openssl-engine ;;
ACCESS_DENIED_VTX11) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/57-access-denied-vtx11 ;;
ACCESS_ALLOWED_LOGIN) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/58-access-login exec_access_allowed_login ;;
ACCESS_DENIED_LOGIN) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/58-access-login exec_access_denied_login ;;
ACCESS_ALLOWED_SUID\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/42-access-suid-sgid exec_access_allowed_suid ;;
ACCESS_ALLOWED_SGID\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/42-access-suid-sgid exec_access_allowed_sgid ;;
ACCESS_ALLOWED_INTERPRETER\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/43-access-interpreter ;;
MOUNT_ATTR\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/44-mountattr ;;
MOUNT_QUOTA\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/45-disk-quota "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
CGROUP_QUOTA\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/46-cgroup-quota "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
POLKIT\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/59-polkit exec_polkit;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/kiosk]"|"[kiosk]")
case "${NAME_VAR}" in
XFCE4_KIOSK\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.post.d/18-kiosk-xfce4-kioskrc ;;
XFCE4_KIOSK_USER_LOCKED) ${ROOTFS}/usr/lib/ublinux/rc.post.d/18-kiosk-xfce4-kioskrc ;;
XFCE4_KIOSK_USER_UNLOCKED) ${ROOTFS}/usr/lib/ublinux/rc.post.d/18-kiosk-xfce4-kioskrc ;;
APPDESKTOP_PLACEONDESKTOP_INIT) ${ROOTFS}/usr/lib/ublinux/rc.pamsession.d/01-placeondesktop exec_02_place_on_desktop_init "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
APPDESKTOP_PLACEONDESKTOP_INIT\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.pamsession.d/01-placeondesktop exec_02_place_on_desktop_init "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
APPDESKTOP_PLACEONDESKTOP) ${ROOTFS}/usr/lib/ublinux/rc.pamsession.d/01-placeondesktop exec_03_place_on_desktop "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
APPDESKTOP_PLACEONDESKTOP\[*\]) ${ROOTFS}/usr/lib/ublinux/rc.pamsession.d/01-placeondesktop exec_03_place_on_desktop "${COMMAND_MODE_VAR}" "${NAME_VAR}=${VALUE_VAR}" ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/clock]"|"[clock]")
case "${NAME_VAR}" in
ZONE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/10-system exec_timezone ;;
HWCLOCK_SYNC)
${ROOTFS}/usr/lib/ublinux/rc.halt/20-timesave
${ROOTFS}/usr/lib/ublinux/rc.post.d/02-hwclock
;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/locale]"|"[locale]")
case "${NAME_VAR}" in
LOCALE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_01_set_locale ;;
LANG)
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_01_set_locale
${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_02_set_lang
;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
"[${SYSCONF}/keyboard]"|"[keyboard]")
case "${NAME_VAR}" in
NUMLOCK) ${ROOTFS}/usr/lib/ublinux/rc.xorg/10-fixkeyboard_layout ;;
XKBMODEL) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_mkkbdfxorg ;;
XKBLAYOUT) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_mkkbdfxorg ;;
XKBVARIANT) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_mkkbdfxorg ;;
XKBOPTIONS) ${ROOTFS}/usr/lib/ublinux/rc.post.d/11-xorg exec_mkkbdfxorg ;;
CONSOLE_FONT) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_03_set_vconsole ;;
CONSOLE_FONT_MAP) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_03_set_vconsole ;;
CONSOLE_FONT_UNIMAP) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_03_set_vconsole ;;
CONSOLE_KEYMAP) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_03_set_vconsole ;;
CONSOLE_KEYMAP_TOGGLE) ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/53-language exec_03_set_vconsole ;;
*) NO_FIND_EXCUTE=1 ;;
esac
;;
\[*\])
case "${NAME_VAR}" in
*) NO_FIND_EXCUTE=1 ;;
esac
;;
*) NO_FIND_EXCUTE=1 ;;
esac
[[ $? -eq 0 ]] && return 0 || return 1
}
################
##### 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
[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1//\'/}'"; }
shift
done
eval ${FUNCTION#*; }
fi