diff --git a/ublinux/functions b/ublinux/functions index 7fb79ea..848b116 100755 --- a/ublinux/functions +++ b/ublinux/functions @@ -190,6 +190,584 @@ globalconf_convert_pass_plain_to_hash(){ 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=$(cat ${FILE_PASSWD}) + local DATA_FILE_SHADOW=$(cat ${FILE_SHADOW}) + local DATA_FILE_LOGINDEFS=$(cat ${FILE_LOGINDEFS}) + local DATA_FILE_DEFAULT_USERADD=$(cat ${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}" + 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}" + fi + [[ -n ${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=$(cat ${FILE_PASSWD}) + local FILE_GROUP="${ROOTFS}/etc/group" + local FILE_GSHADOW="${ROOTFS}/etc/gshadow" + local DATA_FILE_GROUP=$(cat ${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= + [[ ${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]} + if [[ ${VOL_FILEP_GID} == ${VOL_FILEG_GID} && -z ${VOL_FILEG_MEMBERS} ]]; 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=$(cat ${FILE_GROUP}) + local DATA_FILE_GSHADOW=$(cat ${FILE_GSHADOW}) + local DATA_FILE_LOGINDEFS=$(cat ${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}" + #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}" + #printf "%s:%s:%s:%s\n" "${SELECT_GROUPNAME}" "${SELECT_PASSWORD}" "${SELECT_ADMINISTRATORS}" "${SELECT_MEMBERS}" + fi + [[ -n ${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=$(cat ${FILE_GROUP}) + local FILE_PASSWD="${ROOTFS}/etc/passwd" + local DATA_FILE_PASSWD=$(cat ${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. Разделённых ',' +# # :,:,... +# $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=$(cat ${FILE_PASSWD}) + local FILE_GROUP="${ROOTFS}/etc/group" + local FILE_GSHADOW="${ROOTFS}/etc/gshadow" + local DATA_FILE_GROUP=$(cat ${FILE_GROUP}) + local DATA_FILE_GSHADOW=$(cat ${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=$(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. Разделитель ',' +# # :,:,... +# $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=$(cat ${FILE_PASSWD}) + local FILE_GROUP="${ROOTFS}/etc/group" + local FILE_GSHADOW="${ROOTFS}/etc/gshadow" + local DATA_FILE_GROUP=$(cat ${FILE_GROUP}) + local DATA_FILE_GSHADOW=$(cat ${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}" +} + ##################################################################################### ### ### Функции получения от системы текущих настроек вида параметров от конфигурации ### diff --git a/ublinux/rc.local.d/20-pwgr-check b/ublinux/rc.local.d/20-pwgr-check index 5dda413..0ab31d5 100755 --- a/ublinux/rc.local.d/20-pwgr-check +++ b/ublinux/rc.local.d/20-pwgr-check @@ -22,7 +22,7 @@ exec_check_user_group(){ # Вывести только предупреждение, если файл passwd или shadow повреждён # /usr/bin/pwck -r # Вывести предупреждение и исправить, если файл passwd или shadow повреждён - yes | /usr/bin/pwck -q + echo yes | /usr/bin/pwck -q fi fi if [[ ${CHECK_MODE} =~ "group" ]]; then @@ -33,7 +33,7 @@ exec_check_user_group(){ # Вывести предупреждение, если файл group или gshadow повреждён # /usr/bin/grpck -r # Вывести предупреждение и исправить, если файл group или gshadow повреждён - yes | /usr/bin/grpck -q + echo yes | /usr/bin/grpck -q fi fi } diff --git a/ublinux/rc.local.d/41-x11vnc b/ublinux/rc.local.d/41-x11vnc index 19cb381..81d8cb6 100755 --- a/ublinux/rc.local.d/41-x11vnc +++ b/ublinux/rc.local.d/41-x11vnc @@ -24,6 +24,7 @@ debug_mode "$0" "$@" fi [[ -f /root/.vnc/.passwd ]] && OPTION_RFBAUTH_PASSWD="-rfbauth /root/.vnc/.passwd" if systemctl --quiet is-enabled lightdm.service &>/dev/null || systemctl --quiet is-enabled lightdm-plymouth.service &>/dev/null; then + #$(cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done) for ID_DISPLAY in /var/run/lightdm/root/:*; do FILE_X11VNC_SERVICE="/usr/lib/systemd/system/x11vnc-ublinux:${ID_DISPLAY##*:}.service" OPTION_DISPLAY="-display WAIT:${ID_DISPLAY##*:} -auth /var/run/lightdm/root/:${ID_DISPLAY##*:}" diff --git a/ublinux/rc.post.d/10-brand-backgrounds b/ublinux/rc.post.d/10-brand-backgrounds index 91b8930..40afbf0 100755 --- a/ublinux/rc.post.d/10-brand-backgrounds +++ b/ublinux/rc.post.d/10-brand-backgrounds @@ -59,263 +59,280 @@ SOURCE=${SYSCONF}/video; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null #ROOTDIR=${PWD} [[ -n $1 ]] && [[ -n $2 ]] && BUILD_MANUAL=yes [[ -z ${BUILD_MANUAL} && ${DISPLAYMANAGER} == "none" ]] && exit - [[ -z ${BUILD_MANUAL} && ${BACKGROUND_DE} == @(none|no|disable) && ${BACKGROUND_DM} == @(none|no|disable) ]] && exit + [[ -z ${BUILD_MANUAL} && ${BACKGROUND_DE} == @(none|no|disable) && ${BACKGROUND_DM} == @(none|no|disable) ]] && exit 0 - source_img_dir=${ROOTDIR}/usr/share/ublinux/backgrounds/source #Каталог с исходниками изображений - wallpapers_tmp=${ROOTDIR}/tmp/ublinux_bg #Каталог скомпиллированных изображений - wallpapers_dst=${ROOTDIR}/usr/share/backgrounds/ublinux #Каталог скомпиллированных изображений - default_de_img=${wallpapers_dst%/*}/background.jpg - default_dm_img=${wallpapers_dst%/*}/dm.jpg - bg_desktop_basic=bg_db.png # Фон для Desktop Basic - bg_desktop_enterprise=bg_de.png # Фон для Desktop Enterprise - bg_education=bg_edu.png # Фон для Education - bg_expert=bg_exp.png # Фон для Expert - bg_server=bg_srv.png # Фон для Server - bg_liveoffice=bg_lo.png # Фон для LiveOfice - shadow_img=shadow.png # Затенение - hex_img=hex.png # Сетка из шестигранников - transparent=transparent.png # Изображение прозрачный пиксель - logo_img=logo.png # Логотип исходный - logo_desktop_basic=logo_db.png # Изображение редакции дистрибутива - logo_desktop_enterprise=logo_de.png # Изображение редакции дистрибутива - logo_education=logo_edu.png # Изображение редакции дистрибутива - logo_expert=logo_exp.png # *Deprecated* Изображение редакции дистрибутива - logo_server=logo_srv.png # Изображение редакции дистрибутива - logo_light=logo_light.png # Изображение свечения логотипа - logo_adara=logo_adara.png # Изображение редакции дистрибутива Adara - logo_sibsutis=logo_sibsutis.png # Изображение редакции дистрибутива SibSUTIS - logo_liveoffice=logo_liveoffice.png # Изображение редакции дистрибутива LiveOffice - logo_clue_img=logo_clue.png # Имя склееного логотипа с редакцией дистрибутива + source_img_dir="${ROOTDIR}/usr/share/ublinux/backgrounds/source" #Каталог с исходниками изображений + wallpapers_tmp="${ROOTDIR}/tmp/ublinux_bg" #Каталог скомпиллированных изображений + wallpapers_dst="${ROOTDIR}/usr/share/backgrounds/ublinux" #Каталог скомпиллированных изображений + default_de_img="${wallpapers_dst%/*}/background.jpg" + default_dm_img="${wallpapers_dst%/*}/dm.jpg" + bg_desktop_basic="bg_db.png" # Фон для Desktop Basic + bg_desktop_enterprise="bg_de.png" # Фон для Desktop Enterprise + bg_education="bg_edu.png" # Фон для Education + bg_expert="bg_exp.png" # Фон для Expert + bg_server="bg_srv.png" # Фон для Server + bg_liveoffice="bg_lo.png" # Фон для LiveOfice + shadow_img="shadow.png" # Затенение + hex_img="hex.png" # Сетка из шестигранников + transparent="transparent.png" # Изображение прозрачный пиксель + logo_img="logo.png" # Логотип исходный + logo_desktop_basic="logo_db.png" # Изображение редакции дистрибутива + logo_desktop_enterprise="logo_de.png" # Изображение редакции дистрибутива + logo_education="logo_edu.png" # Изображение редакции дистрибутива + logo_expert="logo_exp.png" # *Deprecated* Изображение редакции дистрибутива + logo_server="logo_srv.png" # Изображение редакции дистрибутива + logo_light="logo_light.png" # Изображение свечения логотипа + logo_adara="logo_adara.png" # Изображение редакции дистрибутива Adara + logo_sibsutis="logo_sibsutis.png" # Изображение редакции дистрибутива SibSUTIS + logo_liveoffice="logo_liveoffice.png" # Изображение редакции дистрибутива LiveOffice + logo_clue_img="logo_clue.png" # Имя склееного логотипа с редакцией дистрибутива - img_state_bg_de=bg_icon_state_de.png # Фон для иконки режима сохранения (рабочий стол) - img_state_bg_dm=bg_icon_state_dm.png # Фон для иконки режима сохранения (гритер) - img_nosave=icon_state_ro.png # Иконка для режима "без сохранения" - img_fullsave=icon_state_rw.png # Иконка для режима "полное сохранение" - img_homesave=icon_state_uw.png # Иконка для режима "сохранение home" - img_modulesave=icon_state_mw.png # Иконка для режима "сохранение в модуль" + img_state_bg_de="bg_icon_state_de.png" # Фон для иконки режима сохранения (рабочий стол) + img_state_bg_dm="bg_icon_state_dm.png" # Фон для иконки режима сохранения (гритер) + img_nosave="icon_state_ro.png" # Иконка для режима "без сохранения" + img_fullsave="icon_state_rw.png" # Иконка для режима "полное сохранение" + img_homesave="icon_state_uw.png" # Иконка для режима "сохранение home" + img_modulesave="icon_state_mw.png" # Иконка для режима "сохранение в модуль" - passwd_block_img=passwd_text.png # Изображение с текстом для FirstSart - wp_de_filename=tmp_wp_de.jpg # Имя файла обоев - wp_dm_filename=tmp_wp_dm.jpg # Имя файла фона гритера - shadow_level=175 # Степень затенения обоев рабочего стола в %, где 100 - исходная яркость, <100 - светлее, >100 - темнее - declare -A monitors + passwd_block_img="passwd_text.png" # Изображение с текстом для FirstSart + wp_de_filename="tmp_wp_de.jpg" # Имя файла обоев + wp_dm_filename="tmp_wp_dm.jpg" # Имя файла фона гритера + shadow_level="175" # Степень затенения обоев рабочего стола в %, где 100 - исходная яркость, <100 - светлее, >100 - темнее + declare -A MONITORS RESOLUTION= # Функция получения всех видеовыходов с максимальными разрешениями # В теле основном: -# declare -A monitors +# declare -A MONITORS # Входной параметр: имя переменной массива -# get_max_resolution "monitors" +# get_max_resolution "MONITORS" # Выходной параметр: заполненный массив, вида # card0-HDMI-A-1:1920x2000 # card0-DP-1:1920x1080 # card0-VGA-1:1280x720 # RESOLUTION:1920x2000 -get_max_resolution() { - local max_mode # Максимальное разрешение из всех мониторов +get_max_resolution(){ # Метод определения разрешения №1, подходит для свободных драйверов KMS # Без драйверов по VGA не находит разрешение - if ls /sys/class/drm/*/status &>/dev/null; then - for video_output in /sys/class/drm/*/status; do - if [[ $(cat ${video_output}) == "connected" ]]; then + local max_mode= # Максимальное разрешение из всех мониторов + local video_output= video_name= video_modes= max_mode= line_mode= pixel_line_mode= pixel_max_mode= pixel_max_mode_all= + while IFS= read -u3 -r -d $'\0' video_output; do + if [[ $(cat ${video_output}) =~ ^"connected"$ ]]; then video_name="${video_output%/*}"; video_name="${video_name##*/}" video_modes="${video_output%/*}/modes" - [[ -f ${video_modes} ]] || break + [[ -f ${video_modes} ]] || continue max_mode="0" - while read line_mode; do + while IFS= read -u4 -r line_mode; do pixel_line_mode=$(echo ${line_mode} | tr -d "i" | tr x "*" | bc) [[ "${line_mode}" == "1440x900" ]] && pixel_line_mode=$( echo ${pixel_line_mode} + 14721 | bc) # fix 1440x900 > 1280x1024 pixel_max_mode=$(echo ${max_mode} | tr -d "i" | tr x "*" | bc) [[ ${pixel_line_mode} -gt ${pixel_max_mode} ]] && max_mode=$(echo ${line_mode} | tr -d "i") pixel_max_mode_all=$(echo ${RESOLUTION} | tr -d "i" | tr x "*" | bc) [[ ${pixel_line_mode} -gt ${pixel_max_mode_all} ]] && RESOLUTION=$(echo ${line_mode} | tr -d "i") - done < ${video_modes} - monitors[${video_name}]=${max_mode} + done 4< ${video_modes} + MONITORS[${video_name}]=${max_mode} fi - done - fi + done 3< <(find /sys/class/drm/*/ -type f -name status -print0 2>/dev/null) # Метод определения разрешения №2 # из конфига /etc/ublinux/video по статическим заданным разрешениям [[ -n "${XORG_MONITOR[@]}" ]] && declare -n MONITOR=XORG_MONITOR [[ -n "${XRANDR_MONITOR[@]}" ]] && declare -n MONITOR=XRANDR_MONITOR - if [[ -n "${MONITOR[@]}" ]]; then - for VIDEO_PORT in "${!MONITOR[@]}"; do - while read VIDEO_PORT_PARAM; do - if grep -Eiq "^[0-9]*x[0-9]*$|^[0-9]*x[0-9]*x[0-9]*$" <<< "${VIDEO_PORT_PARAM}"; then - RESOLUTION="$(sed 's/\([0-9]*\*[0-9]*\) .*/\1/' <<< ${VIDEO_PORT_PARAM//x/*})" - # fix 1440x900 > 1280x1024 - [[ "${RESOLUTION}" == "1440*900" ]] && pixel_line_mode=$(bc <<< "${RESOLUTION}+14721") || pixel_line_mode=$(bc <<< ${RESOLUTION}) - [[ ${pixel_line_mode} -gt ${pixel_max_mode} ]] && pixel_max_mode=${pixel_line_mode} && RESOLUTION_MAX=${RESOLUTION} - fi - done < <(tr ',' '\n' <<< "${MONITOR[${VIDEO_PORT}]}") - done - RESOLUTION=${RESOLUTION_MAX//\*/x} - fi + if [[ ${#MONITOR[@]} -ne 0 ]]; then + local VIDEO_PORT= VIDEO_PORT_PARAM= pixel_line_mode= pixel_max_mode= RESOLUTION_MAX= + for VIDEO_PORT in "${!MONITOR[@]}"; do + while IFS= read -u3 -r VIDEO_PORT_PARAM; do + if grep -Eiq "^[0-9]*x[0-9]*$|^[0-9]*x[0-9]*x[0-9]*$" <<< "${VIDEO_PORT_PARAM}"; then + RESOLUTION="$(sed 's/\([0-9]*\*[0-9]*\) .*/\1/' <<< ${VIDEO_PORT_PARAM//x/*})" + # fix 1440x900 > 1280x1024 + #[[ "${RESOLUTION}" == "1440*900" ]] && pixel_line_mode=$(bc <<< "${RESOLUTION}+14721") || pixel_line_mode=$(bc <<< ${RESOLUTION}) + [[ "${RESOLUTION}" == "1440*900" ]] && pixel_line_mode=$((${RESOLUTION}+14721)) || pixel_line_mode=$((${RESOLUTION})) + [[ ${pixel_line_mode} -gt ${pixel_max_mode} ]] && pixel_max_mode=${pixel_line_mode} && RESOLUTION_MAX=${RESOLUTION} + fi + done 3< <(tr ',' '\n' <<< "${MONITOR[${VIDEO_PORT}]}") + done + [[ -n ${RESOLUTION_MAX} ]] && RESOLUTION=${RESOLUTION_MAX//\*/x} + fi # Метод определения разрешения №99, при условии запущенного lightdm local PATH_XAUTHORITY="/var/lib/lightdm/.Xauthority" - [[ -z ${RESOLUTION} && -f ${PATH_XAUTHORITY} && -n $(ls /tmp/.X11-unix/X* 2>/dev/null) ]] && \ - RESOLUTION=$(XAUTHORITY=${PATH_XAUTHORITY} xrandr -d $(ls /tmp/.X11-unix | tr 'X' ':' | head -n 1) 2>/dev/null | grep "*" | xargs | cut -d" " -f1) + [[ -z ${RESOLUTION} && -f ${PATH_XAUTHORITY} && -n $(ls /tmp/.X11-unix/X* 2>/dev/null) ]] \ + && RESOLUTION=$(XAUTHORITY=${PATH_XAUTHORITY} xrandr -d $(ls /tmp/.X11-unix 2>/dev/null | tr 'X' ':' | head -n 1) 2>/dev/null | grep "*" | xargs | cut -d" " -f1) # $(xrandr -d :0 --current | sed -n 's/.* connected \([0-9]*\)x\([0-9]*\)+.*/\1x\2/p') - # Если не обнаружено ни одно разрешение, то статическое из /usr/lib/ublinux/default - [[ -z ${RESOLUTION} ]] && RESOLUTION=${BACKGROUND_RES} - [[ -z ${RESOLUTION} ]] && RESOLUTION="1920x1080" } build_logo_ublinux_all(){ # Склейка логотипа UBLinux со свечением - [[ -n ${logo_light} ]] && convert ${source_img_dir}/$logo_light ${source_img_dir}/$logo_img -gravity center -background none +smush -710 ${wallpapers_tmp}/tmp_$logo_clue_img \ - || cp ${source_img_dir}/$logo_img ${wallpapers_tmp}/tmp_$logo_clue_img + [[ -n ${logo_light} ]] && convert "${source_img_dir}/${logo_light}" "${source_img_dir}/${logo_img}" -gravity center -background none +smush -710 "${wallpapers_tmp}/tmp_${logo_clue_img}" \ + || cp "${source_img_dir}/${logo_img}" "${wallpapers_tmp}/tmp_${logo_clue_img}" # Конвеер вставки логотипа редакции ОС - [[ -n ${edition_img} ]] && composite -geometry $geometry_edition_wp -gravity east ${source_img_dir}/$edition_img ${wallpapers_tmp}/tmp_$logo_clue_img ${wallpapers_tmp}/tmp_$logo_clue_img + [[ -n ${edition_img} ]] && composite -geometry ${geometry_edition_wp} -gravity east "${source_img_dir}/${edition_img}" "${wallpapers_tmp}/tmp_${logo_clue_img}" "${wallpapers_tmp}/tmp_${logo_clue_img}" # Конвеер вставки логотипа суббренда - if [ ${geometry_adara_wp} ]; then - img_logo_width=$(identify ${wallpapers_tmp}/tmp_$logo_clue_img | cut -d" " -f3 | cut -d"x" -f1) - img_adara_width=$(identify ${source_img_dir}/$logo_adara | cut -d" " -f3 | cut -d"x" -f1) - let img_logo_width=($img_logo_width+$img_adara_width) - convert ${wallpapers_tmp}/tmp_$logo_clue_img -gravity west -background none -extent $img_logo_width'x' ${wallpapers_tmp}/tmp_$logo_clue_img - composite -geometry $geometry_adara_wp -gravity east ${source_img_dir}/$logo_adara ${wallpapers_tmp}/tmp_$logo_clue_img ${wallpapers_tmp}/tmp_$logo_clue_img - elif [ ${geometry_sibsutis_wp} ]; then - img_logo_width=$(identify ${wallpapers_tmp}/tmp_$logo_clue_img | cut -d" " -f3 | cut -d"x" -f1) - convert ${wallpapers_tmp}/tmp_$logo_clue_img -gravity west -background none -extent $img_logo_width'x' ${wallpapers_tmp}/tmp_$logo_clue_img - composite -geometry $geometry_sibsutis_wp -gravity north ${source_img_dir}/$logo_sibsutis ${wallpapers_tmp}/tmp_$logo_clue_img ${wallpapers_tmp}/tmp_$logo_clue_img + if [[ -n ${geometry_adara_wp} ]]; then + img_logo_width="$(identify "${wallpapers_tmp}/tmp_${logo_clue_img}" | cut -d" " -f3 | cut -d"x" -f1)" + img_adara_width="$(identify "${source_img_dir}/${logo_adara}" | cut -d" " -f3 | cut -d"x" -f1)" + img_logo_width=$((${img_logo_width}+${img_adara_width})) + convert "${wallpapers_tmp}/tmp_${logo_clue_img}" -gravity west -background none -extent "${img_logo_width}x" "${wallpapers_tmp}/tmp_${logo_clue_img}" + composite -geometry "${geometry_adara_wp}" -gravity east "${source_img_dir}/${logo_adara}" "${wallpapers_tmp}/tmp_${logo_clue_img}" "${wallpapers_tmp}/tmp_${logo_clue_img}" + elif [[ -n ${geometry_sibsutis_wp} ]]; then + img_logo_width=$(identify "${wallpapers_tmp}/tmp_${logo_clue_img}" | cut -d" " -f3 | cut -d"x" -f1) + convert "${wallpapers_tmp}/tmp_${logo_clue_img}" -gravity west -background none -extent "${img_logo_width}x" "${wallpapers_tmp}/tmp_${logo_clue_img}" + composite -geometry "${geometry_sibsutis_wp}" -gravity north "${source_img_dir}/${logo_sibsutis}" "${wallpapers_tmp}/tmp_${logo_clue_img}" "${wallpapers_tmp}/tmp_${logo_clue_img}" fi } build_background_all(){ # Наложение градиентного затемнения DE - convert -composite $background ${source_img_dir}/$shadow_img ${wallpapers_tmp}/${wp_de_filename} + convert -composite "${background}" "${source_img_dir}/${shadow_img}" "${wallpapers_tmp}/${wp_de_filename}" # Наложение градиентного затемнения DM - cp ${wallpapers_tmp}/${wp_de_filename} ${wallpapers_tmp}/${wp_dm_filename} + cp "${wallpapers_tmp}/${wp_de_filename}" "${wallpapers_tmp}/${wp_dm_filename}" } build_background_de(){ # Наложение сетки шестигранников DE - convert -composite ${wallpapers_tmp}/${wp_de_filename} ${source_img_dir}/$hex_img ${wallpapers_tmp}/${wp_de_filename} + convert -composite "${wallpapers_tmp}/${wp_de_filename}" "${source_img_dir}/${hex_img}" "${wallpapers_tmp}/${wp_de_filename}" # Конвеер вставки объединенного логотипа на фон DE - composite -geometry $geometry_logo_wp -gravity west ${wallpapers_tmp}/tmp_$logo_clue_img ${wallpapers_tmp}/${wp_de_filename} ${wallpapers_tmp}/${wp_de_filename} + composite -geometry "$geometry_logo_wp" -gravity west "${wallpapers_tmp}/tmp_${logo_clue_img}" "${wallpapers_tmp}/${wp_de_filename}" "${wallpapers_tmp}/${wp_de_filename}" # Затенения обоев рабочего стола - convert ${wallpapers_tmp}/${wp_de_filename} -level 0,$shadow_level% ${wallpapers_tmp}/${wp_de_filename} + convert "${wallpapers_tmp}/${wp_de_filename}" -level 0,${shadow_level}% "${wallpapers_tmp}/${wp_de_filename}" } build_background_dm(){ # Вычисление коэффициента скейлинга - img_hight=$(identify $background | cut -d" " -f3 | cut -d"x" -f2) - ratio_scale=$(echo "scale=2;$img_hight/${hight}" | bc) + img_hight=$(identify ${background} | cut -d" " -f3 | cut -d"x" -f2) + ratio_scale=$(echo "scale=2;${img_hight}/${hight}" | bc) # echo RS=${ratio_scale} - tmp_logo_clue_hight=$(identify ${wallpapers_tmp}/tmp_$logo_clue_img | cut -d" " -f3 | cut -d"x" -f2) + tmp_logo_clue_hight=$(identify "${wallpapers_tmp}/tmp_${logo_clue_img}" | cut -d" " -f3 | cut -d"x" -f2) nsize_logo_clue_hight=$(echo "scale=0;$tmp_logo_clue_hight/${ratio_scale}" | bc) # echo RSCF Logo=$nsize_logo_clue_hight - convert ${wallpapers_tmp}/tmp_$logo_clue_img -resize x$nsize_logo_clue_hight ${wallpapers_tmp}/tmp_dm_$logo_clue_img - convert ${wallpapers_tmp}/tmp_dm_$logo_clue_img -resize 35% ${wallpapers_tmp}/tmp_dm_$logo_clue_img + convert "${wallpapers_tmp}/tmp_${logo_clue_img}" -resize "x${nsize_logo_clue_hight}" "${wallpapers_tmp}/tmp_dm_${logo_clue_img}" + convert "${wallpapers_tmp}/tmp_dm_${logo_clue_img}" -resize 35% "${wallpapers_tmp}/tmp_dm_${logo_clue_img}" x_shift=$(echo "scale=0;150/${ratio_scale}" | bc) y_shift=$(echo "scale=0;170/${ratio_scale}" | bc) -# echo "LOGO $x_shift on $y_shift px" +# echo "LOGO ${x_shift} on ${y_shift px}" # Конвеер вставки объединенного уменьшенного логотипа на фон DM - composite -geometry +$x_shift+$y_shift ${wallpapers_tmp}/tmp_dm_$logo_clue_img ${wallpapers_tmp}/${wp_dm_filename} ${wallpapers_tmp}/${wp_dm_filename} + composite -geometry +${x_shift}+${y_shift} "${wallpapers_tmp}/tmp_dm_${logo_clue_img}" "${wallpapers_tmp}/${wp_dm_filename}" "${wallpapers_tmp}/${wp_dm_filename}" } insert_background_dm_txtpass(){ # Вычисление коэффициента скейлинга - img_hight=$(identify $background | cut -d" " -f3 | cut -d"x" -f2) - ratio_scale=$(echo "scale=2;$img_hight/${hight}" | bc) - tmp_passwd_text_hight=$(identify ${source_img_dir}/$passwd_block_img | cut -d" " -f3 | cut -d"x" -f2) - nsize_passwd_text_hight=$(echo "scale=0;$tmp_passwd_text_hight/${ratio_scale}" | bc) + img_hight=$(identify ${background} | cut -d" " -f3 | cut -d"x" -f2) + ratio_scale=$(echo "scale=2;${img_hight}/${hight}" | bc) + tmp_passwd_text_hight=$(identify "${source_img_dir}/$passwd_block_img" | cut -d" " -f3 | cut -d"x" -f2) + nsize_passwd_text_hight=$(echo "scale=0;${tmp_passwd_text_hight}/${ratio_scale}" | bc) x_shift_text=$(echo "scale=0;0/${ratio_scale}" | bc) y_shift_text=$(echo "scale=0;370/${ratio_scale}" | bc) -# echo "TXT $x_shift_text on $y_shift_text px" -# echo RSCF first=$nsize_passwd_text_hight - convert ${source_img_dir}/$passwd_block_img -resize x$nsize_passwd_text_hight -colorspace RGB ${wallpapers_tmp}/tmp_$passwd_block_img - composite -geometry +$x_shift_text+$y_shift_text -gravity NorthEast ${wallpapers_tmp}/tmp_$passwd_block_img $default_dm_img $default_dm_img +# echo "TXT ${x_shift_text} on ${y_shift_text} px" +# echo RSCF first=${nsize_passwd_text_hight} + convert "${source_img_dir}/${passwd_block_img}" -resize "x${nsize_passwd_text_hight}" -colorspace RGB "${wallpapers_tmp}/tmp_${passwd_block_img}" + composite -geometry +${x_shift_text}+${y_shift_text} -gravity NorthEast "${wallpapers_tmp}/tmp_${passwd_block_img}" "${default_dm_img}" "${default_dm_img}" } # $1 Файл иконки для вставки insert_background_icon(){ # Вычисление коэффициента скейлинга - img_hight=$(identify $background | cut -d" " -f3 | cut -d"x" -f2) - ratio_scale=$(echo "scale=2;$img_hight/${hight}" | bc) + img_hight=$(identify ${background} | cut -d" " -f3 | cut -d"x" -f2) + ratio_scale=$(echo "scale=2;${img_hight}/${hight}" | bc) # DM # bg icon - tmp_state_icon_bg_hight=$(identify ${source_img_dir}/$img_state_bg_dm | cut -d" " -f3 | cut -d"x" -f2) - nsize_state_icon_bg_hight=$(echo "scale=0;$tmp_state_icon_bg_hight/${ratio_scale}" | bc) + tmp_state_icon_bg_hight=$(identify ${source_img_dir}/${img_state_bg_dm} | cut -d" " -f3 | cut -d"x" -f2) + nsize_state_icon_bg_hight=$(echo "scale=0;${tmp_state_icon_bg_hight}/${ratio_scale}" | bc) x_shift_img_bg=$(echo "scale=0;-160/${ratio_scale}" | bc) y_shift_img_bg=$(echo "scale=0;170/${ratio_scale}" | bc) - convert ${source_img_dir}/$img_state_bg_dm -resize x$nsize_state_icon_bg_hight -colorspace RGB ${wallpapers_tmp}/tmp_$img_state_bg_dm - composite -geometry +$x_shift_img_bg+$y_shift_img_bg -gravity NorthEast ${wallpapers_tmp}/tmp_$img_state_bg_dm $default_dm_img $default_dm_img + convert "${source_img_dir}/${img_state_bg_dm}" -resize x${nsize_state_icon_bg_hight} -colorspace RGB "${wallpapers_tmp}/tmp_${img_state_bg_dm}" + composite -geometry +${x_shift_img_bg}+${y_shift_img_bg} -gravity NorthEast "${wallpapers_tmp}/tmp_${img_state_bg_dm}" "${default_dm_img}" "${default_dm_img}" # icon tmp_state_icon_hight=$(identify ${source_img_dir}/$1 | cut -d" " -f3 | cut -d"x" -f2) - nsize_state_icon_hight=$(echo "scale=0;$tmp_state_icon_hight/(${ratio_scale}*1.5)" | bc) + nsize_state_icon_hight=$(echo "scale=0;${tmp_state_icon_hight}/(${ratio_scale}*1.5)" | bc) #" x_shift_img=$(echo "scale=0;120/${ratio_scale}" | bc) y_shift_img=$(echo "scale=0;168/${ratio_scale}" | bc) - convert ${source_img_dir}/$1 -resize x$nsize_state_icon_hight -colorspace sRGB ${wallpapers_tmp}/tmp_state.png - composite -geometry +$x_shift_img+$y_shift_img -gravity NorthEast ${wallpapers_tmp}/tmp_state.png $default_dm_img $default_dm_img + convert "${source_img_dir}/$1" -resize x${nsize_state_icon_hight} -colorspace sRGB "${wallpapers_tmp}/tmp_state.png" + composite -geometry +${x_shift_img}+${y_shift_img} -gravity NorthEast "${wallpapers_tmp}/tmp_state.png" "${default_dm_img}" "${default_dm_img}" # DE # bg icon - tmp_state_icon_bg_hight=$(identify ${source_img_dir}/$img_state_bg_de | cut -d" " -f3 | cut -d"x" -f2) - nsize_state_icon_bg_hight=$(echo "scale=0;$tmp_state_icon_bg_hight/${ratio_scale}" | bc) + tmp_state_icon_bg_hight=$(identify ${source_img_dir}/${img_state_bg_de} | cut -d" " -f3 | cut -d"x" -f2) + nsize_state_icon_bg_hight=$(echo "scale=0;${tmp_state_icon_bg_hight}/${ratio_scale}" | bc) x_shift_img_bg=$(echo "scale=0;1785/${ratio_scale}" | bc) y_shift_img_bg=$(echo "scale=0;0/${ratio_scale}" | bc) - convert ${source_img_dir}/$img_state_bg_de -resize x$nsize_state_icon_bg_hight -colorspace RGB ${wallpapers_tmp}/tmp_$img_state_bg_de - composite -geometry +$x_shift_img_bg+$y_shift_img_bg -gravity NorthWest ${wallpapers_tmp}/tmp_$img_state_bg_de $default_de_img $default_de_img + convert "${source_img_dir}/${img_state_bg_de}" -resize x${nsize_state_icon_bg_hight} -colorspace RGB "${wallpapers_tmp}/tmp_${img_state_bg_de}" + composite -geometry +${x_shift_img_bg}+${y_shift_img_bg} -gravity NorthWest "${wallpapers_tmp}/tmp_${img_state_bg_de}" "${default_de_img}" "${default_de_img}" # icon - tmp_state_icon_hight=$(identify ${source_img_dir}/$1 | cut -d" " -f3 | cut -d"x" -f2) - nsize_state_icon_hight=$(echo "scale=0;$tmp_state_icon_hight/(${ratio_scale}*1.5)" | bc) + tmp_state_icon_hight=$(identify "${source_img_dir}/$1" | cut -d" " -f3 | cut -d"x" -f2) + nsize_state_icon_hight=$(echo "scale=0;${tmp_state_icon_hight}/(${ratio_scale}*1.5)" | bc) #" x_shift_img=$(echo "scale=0;1940/${ratio_scale}" | bc) y_shift_img=$(echo "scale=0;50/${ratio_scale}" | bc) - convert ${source_img_dir}/$1 -resize x$nsize_state_icon_hight -colorspace sRGB ${wallpapers_tmp}/tmp_state.png - composite -geometry +$x_shift_img+$y_shift_img -gravity NorthWest ${wallpapers_tmp}/tmp_state.png $default_de_img $default_de_img + convert "${source_img_dir}/$1" -resize x${nsize_state_icon_hight} -colorspace sRGB "${wallpapers_tmp}/tmp_state.png" + composite -geometry +${x_shift_img}+${y_shift_img} -gravity NorthWest "${wallpapers_tmp}/tmp_state.png" "${default_de_img}" "${default_de_img}" } # Test get resolution || Проверить массив мониторов с разрешениями # get_max_resolution "array_monitor_modes" -# for key in "${!monitors[@]}"; do -# echo "${key}:${monitors[${key}]}" +# for key in "${!MONITORS[@]}"; do +# echo "${key}:${MONITORS[${key}]}" # done # echo "${RESOLUTION}" - mkdir -p ${wallpapers_tmp} + mkdir -p "${wallpapers_tmp}" # [[ -L ${wallpapers_dst} ]] || mkdir -p ${wallpapers_dst} - if [[ ! -e ${wallpapers_dst} ]]; then - mkdir -p $(readlink ${wallpapers_dst}) || mkdir -p ${wallpapers_dst} + if [[ ! -d ${wallpapers_dst} ]]; then + mkdir -p $(readlink ${wallpapers_dst}) || mkdir -p "${wallpapers_dst}" fi - - grep -q xres= /proc/cmdline && RESOLUTION=$(cat /proc/cmdline | awk -F xres= '{print $2}' | awk '{print $1}') -# xres=$(cmdline_value desktop) && [[ ! -z ${xres} ]] && RESOLUTION=${xres} + + #grep -q "xres=" /proc/cmdline 2>/dev/null && RESOLUTION=$(cat /proc/cmdline | awk -F xres= '{print $2}' | awk '{print $1}') + #xres=$(cmdline_value desktop) && [[ ! -z ${xres} ]] && RESOLUTION=${xres} + xres=$(cmdline_value xres) && [[ -n ${xres} ]] && RESOLUTION=${xres} + # Определение разрешения экрана - [[ -z $1 ]] || RESOLUTION=$1 - [[ -z "${RESOLUTION}" ]] && get_max_resolution - [[ -z "${RESOLUTION}" ]] && echo "ERROR: resolution not detect" && exit 1 + [[ -n $1 ]] && [[ $1 =~ ^([[:digit:]]+'x'[[:digit:]]+)$ ]] && RESOLUTION=${BASH_REMARCH[1]} + [[ ${RESOLUTION} == "" ]] && get_max_resolution + # Если не обнаружено ни одно разрешение, то статическое из /usr/lib/ublinux/default + [[ ${RESOLUTION} == "" ]] && RESOLUTION=${BACKGROUND_RES} + [[ ${RESOLUTION} == "" ]] && RESOLUTION="1920x1080" + [[ ${RESOLUTION} == "" ]] && echo "ERROR: resolution not detect" && exit 1 # Определение редакции ОС [[ -z $2 ]] && edition_os=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d"=" -f2 2>/dev/null) || edition_os=$2 - width=${RESOLUTION%x*}; width=${width:-1920} - hight=${RESOLUTION#*x}; hight=${hight:-1080} -#echo "${width} on ${hight}" + width= + hight= + width="${RESOLUTION%x*}" + hight="${RESOLUTION#*x}" + +#echo "------ ${width} on ${hight} ------- ${edition_os}" # Вычисление соотношения сторон экрана - ratio=$(bc <<< "scale=2;${width}/${hight}") - if [[ "$(bc -l <<< "${ratio}==1.33")" == 1 ]]; then +# ratio=$(echo "scale=2;${width}/${hight}" | bc) + ratio=$(echo "$((${width}*100/${hight}))" | sed -E "s/([0-9]{2}$)/.\1/") #" +# if [[ "$(echo "${ratio}==1.33" | bc -l)" == 1 ]]; then + if [[ "${ratio}" == "1.33" ]]; then fname_ratio="4:3" - elif [[ "$(bc -l <<< "${ratio}==1.25")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==1.25" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "1.25" ]]; then fname_ratio="5:4" - elif [[ "$(bc -l <<< "${ratio}==1.77")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==1.77" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "1.77" ]]; then fname_ratio="16:9" - elif [[ "$(bc -l <<< "${ratio}==1.6")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==1.60" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "1.60" ]]; then fname_ratio="16:10" - elif [[ "$(bc -l <<< "${ratio}==2.38")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==2.38" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "2.38" ]]; then fname_ratio="21:9" - elif [[ "$(bc -l <<< "${ratio}==2.37")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==2.37" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "2.37" ]]; then fname_ratio="21:9" - elif [[ "$(bc -l <<< "${ratio}==2.40")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==2.40" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "2.40" ]]; then fname_ratio="12:5" - elif [[ "$(bc -l <<< "${ratio}==1.89")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==1.89" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "1.89" ]]; then fname_ratio="256:135" - elif [[ "$(bc -l <<< "${ratio}==2.89")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==2.89" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "2.89" ]]; then fname_ratio="1024:429" - elif [[ "$(bc -l <<< "${ratio}==1.85")" == 1 ]]; then +# elif [[ "$(echo "${ratio}==1.85" | bc -l)" == 1 ]]; then + elif [[ "${ratio}" == "1.85" ]]; then fname_ratio="999:540" else fname_ratio="unknown" @@ -324,79 +341,79 @@ insert_background_icon(){ #echo "==> ${width}x${hight} :: ${ratio} :: ${fname_ratio}" && exit 1 # Установка значений переменных для графических ресурсов, исходя из типа редакции ОС - geometry_logo_wp=+69-52 + geometry_logo_wp="+69-52" case "${edition_os}" in ublinux_db) - background=${source_img_dir}/$bg_desktop_basic + background="${source_img_dir}/${bg_desktop_basic}" edition_img=${logo_desktop_basic} - geometry_edition_wp=+86+256 + geometry_edition_wp="+86+256" ;; ublinux_de) - background=${source_img_dir}/$bg_desktop_enterprise + background="${source_img_dir}/${bg_desktop_enterprise}" edition_img=${logo_desktop_enterprise} - geometry_edition_wp=+86+256 + geometry_edition_wp="+86+256" ;; ublinux_edu) - background=${source_img_dir}/$bg_education + background="${source_img_dir}/${bg_education}" edition_img=${logo_education} - geometry_edition_wp=+70+256 + geometry_edition_wp="+70+256" ;; ublinux_srv) - background=${source_img_dir}/${bg_server} + background="${source_img_dir}/${bg_server}" edition_img=${logo_server} - geometry_edition_wp=+86+256 + geometry_edition_wp="+86+256" ;; ublinux_exp) - background=${source_img_dir}/$bg_exp + background="${source_img_dir}/${bg_exp}" edition_img=${logo_expert} - geometry_edition_wp=+72+256 + geometry_edition_wp="+72+256" ;; ublinux_de_adara) - background=${source_img_dir}/$bg_desktop_enterprise + background="${source_img_dir}/${bg_desktop_enterprise}" edition_img=${logo_desktop_enterprise} - geometry_edition_wp=+86+256 - geometry_adara_wp=+130+42 + geometry_edition_wp="+86+256" + geometry_adara_wp="+130+42" ;; ublinux_srv_adara) - background=${source_img_dir}/${bg_server} + background="${source_img_dir}/${bg_server}" edition_img=${logo_server} - geometry_edition_wp=+86+256 - geometry_adara_wp=+130+42 + geometry_edition_wp="+86+256" + geometry_adara_wp="+130+42" ;; ublinux_de_sibsutis) - background=${source_img_dir}/$bg_desktop_enterprise + background="${source_img_dir}/${bg_desktop_enterprise}" edition_img=${logo_desktop_enterprise} - geometry_edition_wp=+86+256 - geometry_sibsutis_wp=+470+166 + geometry_edition_wp="+86+256" + geometry_sibsutis_wp="+470+166" ;; ublinux_edu_sibsutis) - background=${source_img_dir}/$bg_education + background="${source_img_dir}/${bg_education}" edition_img=${logo_education} - geometry_edition_wp=+70+256 - geometry_sibsutis_wp=+470+166 + geometry_edition_wp="+70+256" + geometry_sibsutis_wp="+470+166" ;; ublinux_srv_sibsutis) background=${source_img_dir}/${bg_server} edition_img=${logo_server} - geometry_edition_wp=+86+256 - geometry_sibsutis_wp=+470+166 + geometry_edition_wp="+86+256" + geometry_sibsutis_wp="+470+166" ;; ublinux_liveoffice) - background=${source_img_dir}/$bg_liveoffice + background="${source_img_dir}/${bg_liveoffice}" logo_img=${logo_liveoffice} - geometry_logo_wp=+260-130 + geometry_logo_wp="+260-130" unset logo_light ;; ublinux_unknown | *) - background=${source_img_dir}/$bg_desktop_basic + background="${source_img_dir}/${bg_desktop_basic}" edition_img=${logo_desktop_basic} - geometry_edition_wp=+86+256 + geometry_edition_wp="+86+256" ;; esac CHECK_BOOT_FILE=$(find ${wallpapers_dst}/ -name "${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg" | wc -l) CHECK_BACKGROUND_FILE=$(find ${wallpapers_dst}/ -name "${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg" | wc -l) if [[ ${CHECK_BOOT_FILE} -eq 0 ]] || [[ ${CHECK_BACKGROUND_FILE} -eq 0 ]]; then - [[ ! -x /usr/bin/composite ]] && [[ ! -x /usr/bin/convert ]] && echo "Error: not fount /usr/bin/composite or /usr/bin/convert" && exit 0 + [[ -x /usr/bin/composite && -x /usr/bin/convert ]] || { echo "Error: not fount /usr/bin/composite or /usr/bin/convert" && exit 1; } build_logo_ublinux_all build_background_all build_background_de @@ -404,36 +421,36 @@ insert_background_icon(){ case ${fname_ratio} in "4:3" | "5:4" | "16:10" ) # Изменить размер по высоте (hight) for filename in ${wp_de_filename} ${wp_dm_filename}; do - convert -resize x${hight} ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} - convert -crop ${width}\x+0+0 ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} + convert -resize x${hight} "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" + convert -crop ${width}\x+0+0 "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" done ;; "21:9") # Изменить размер по ширине (width) for filename in ${wp_de_filename} ${wp_dm_filename}; do - convert -resize ${width} ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} - out_img_hight=$(identify ${wallpapers_tmp}/${filename} | cut -d" " -f3 | cut -d"x" -f2) + convert -resize ${width} "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" + out_img_hight=$(identify "${wallpapers_tmp}/${filename}" | cut -d" " -f3 | cut -d"x" -f2) let crop_top=($out_img_hight-${hight})/2 - convert -crop x${hight}+0+$crop_top ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} + convert -crop x${hight}+0+$crop_top "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" done ;; "16:9") # Изменить размер пропорционально for filename in ${wp_de_filename} ${wp_dm_filename}; do - convert -resize x${hight} ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} + convert -resize x${hight} "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" done ;; *) # Изменить размер пропорционально for filename in ${wp_de_filename} ${wp_dm_filename}; do - convert -resize x${hight} ${wallpapers_tmp}/${filename} ${wallpapers_tmp}/${filename} + convert -resize x${hight} "${wallpapers_tmp}/${filename}" "${wallpapers_tmp}/${filename}" done ;; esac build_background_dm - [[ -z ${BUILD_MANUAL} ]] && mv ${wallpapers_tmp}/${wp_de_filename} ${wallpapers_dst}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg || mv ${wallpapers_tmp}/${wp_de_filename} ${wallpapers_tmp}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg + [[ -z ${BUILD_MANUAL} ]] && mv "${wallpapers_tmp}/${wp_de_filename}" "${wallpapers_dst}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg" || mv "${wallpapers_tmp}/${wp_de_filename}" "${wallpapers_tmp}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg" [[ ${BUILD_MANUAL} ]] && mogrify -format png -write ${wallpapers_tmp}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.png ${wallpapers_tmp}/${wp_dm_filename} - [[ -z ${BUILD_MANUAL} ]] && mv ${wallpapers_tmp}/${wp_dm_filename} ${wallpapers_dst}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg || mv ${wallpapers_tmp}/${wp_dm_filename} ${wallpapers_tmp}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg + [[ -z ${BUILD_MANUAL} ]] && mv "${wallpapers_tmp}/${wp_dm_filename}" "${wallpapers_dst}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg" || mv "${wallpapers_tmp}/${wp_dm_filename}" "${wallpapers_tmp}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg" fi - [[ -z ${BUILD_MANUAL} ]] && cp -pf ${wallpapers_dst}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg $default_de_img - [[ -z ${BUILD_MANUAL} ]] && cp -pf ${wallpapers_dst}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg $default_dm_img + [[ -z ${BUILD_MANUAL} ]] && cp -pf "${wallpapers_dst}/${edition_os}_background_${fname_ratio}_${RESOLUTION}.jpg" "${default_de_img}" + [[ -z ${BUILD_MANUAL} ]] && cp -pf "${wallpapers_dst}/${edition_os}_boot_${fname_ratio}_${RESOLUTION}.jpg" "${default_dm_img}" # Если пароли по умолчанию ublinux, то вывести подсказку пароля [[ -z ${BUILD_MANUAL} && -n ${FIRSTSTART} ]] && insert_background_dm_txtpass @@ -448,7 +465,7 @@ insert_background_icon(){ elif [[ ${state_mode} =~ ^("toxzm"|"machines")$ ]]; then insert_background_icon ${img_modulesave} # Песочница с сохранением профиля пользователя ub.mode= ; ub.home=/ublinux-data/homes - elif [[ $state_home =~ ^"/" ]]; then + elif [[ ${state_home} =~ ^"/" ]]; then insert_background_icon ${img_homesave} # Полная песочница RAM ub.mode= (clean); ub.home= # Полная песочница HDD ub.mode=clear; ub.home= diff --git a/ublinux/rc.post.d/30-network b/ublinux/rc.post.d/30-network index d17bf7e..7959770 100755 --- a/ublinux/rc.post.d/30-network +++ b/ublinux/rc.post.d/30-network @@ -13,8 +13,8 @@ debug_mode "$0" "$@" #[ "$DNS_RENEW" = "yes" -a -f /mnt/live/etc/resolv.conf ] && cat /mnt/live/etc/resolv.conf >> /etc/resolvconf/resolv.conf.d/head - NETDEV=$(grep "e.*:[[:space:]]*[1-9]" /proc/net/dev | awk -F: '{print $1}' | head -1 | tr -d ' ') - [[ -z ${NETDEV} ]] && NETDEV=$(ls /sys/class/net/e*/address | awk -F/ '{print $5}' | head -1) + NETDEV=$(grep "e.*:[[:space:]]*[1-9]" /proc/net/dev 2>/dev/null | awk -F: '{print $1}' | head -1 | tr -d ' ') + [[ -z ${NETDEV} ]] && NETDEV=$(ls /sys/class/net/e*/address 2>/dev/null | awk -F/ '{print $5}' | head -1) #[ -z "$NETDEV" ] || sed -i s/DEVICE=.*/DEVICE=$NETDEV/ /etc/ublinux/network-scripts/ifcfg-eth0 # if grep -Eq " nfs |httpfs|ftpfs|sshfs| cifs " /proc/mounts ;then diff --git a/ublinux/rc.preinit.d/53-language b/ublinux/rc.preinit.d/53-language index f20fb78..c11ec1c 100755 --- a/ublinux/rc.preinit.d/53-language +++ b/ublinux/rc.preinit.d/53-language @@ -28,18 +28,18 @@ for I_LOCALE in ${LOCALE//,/ }; do sed -i "s/^#${I_LOCALE} /${I_LOCALE} /g" ${ROOTFS}/etc/locale.gen done -${CMD_CHROOT} env LANG=${LANG} locale > ${ROOTFS}/etc/locale.conf +${CMD_CHROOT} env LANG=${LANG} locale > ${ROOTFS}/etc/locale.conf 2>/dev/null [[ -n ${FORCE_LOCARCHIVE} ]] && FORCEGEN=1 [[ ! -f ${ROOTFS}/usr/lib/locale/locale-archive ]] && FORCEGEN=1 LOCALE_CONF=${LOCALE//-/}; LOCALE_CONF=${LOCALE_CONF,,}; LOCALE_CONF=${LOCALE_CONF//,/$'\n'}; LOCALE_CONF=$(sort -fu <<< ${LOCALE_CONF}) LOCALE_SYSTEM=$(${CMD_CHROOT} localedef --list-archive | sort -fu); LOCALE_SYSTEM=${LOCALE_SYSTEM,,} -[[ ${LOCALE_CONF} == ${LOCALE_SYSTEM} ]] || FORCEGEN=1 -[[ -n ${FORCEGEN} ]] && chroot . locale-gen &>/dev/null +[[ "${LOCALE_CONF}" == "${LOCALE_SYSTEM}" ]] || FORCEGEN=1 +[[ -n ${FORCEGEN} ]] && ${CMD_CHROOT} locale-gen &>/dev/null #; unset LANG; source /etc/profile.d/locale.sh" # Если имеются языкозависимые файлы, то копируем в корень -[[ -d ${ROOTFS}/usr/share/ublinux/langs/${LANG} ]] && cp -pfr ${ROOTFS}/usr/share/ublinux/langs/${LANG}/* ./ +[[ -d ${ROOTFS}/usr/share/ublinux/langs/${LANG} ]] && cp -pfr ${ROOTFS}/usr/share/ublinux/langs/${LANG}/* ${ROOTFS}/ [[ -z ${CONSOLE_FONT} ]] || echo FONT=${CONSOLE_FONT} > ${ROOTFS}/etc/vconsole.conf [[ -z ${CONSOLE_KEYMAP} ]] || echo KEYMAP=${CONSOLE_KEYMAP} >> ${ROOTFS}/etc/vconsole.conf diff --git a/ublinux/rc.preinit.d/54-backgrounds b/ublinux/rc.preinit.d/54-backgrounds index e666938..28a447f 100755 --- a/ublinux/rc.preinit.d/54-backgrounds +++ b/ublinux/rc.preinit.d/54-backgrounds @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Initial script for UBLinux # This script are launching before starting init from initrd script @@ -11,17 +11,21 @@ DEBUGMODE=no PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin -. usr/lib/ublinux/functions -. usr/lib/ublinux/default +[[ -d /usr/lib/ublinux ]] && { unset ROOTFS; unset CMD_CHROOT; } || { ROOTFS='.'; CMD_CHROOT='chroot . '; } +SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0 +SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0 debug_mode "$0" "$@" +SYSCONF="${ROOTFS}${SYSCONF}" +SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null + find /memory/layer-base/*/* -maxdepth 0 -iname "ublinux-data*.sgn" | while read location; do mkdir -p $(dirname ${location})/backgrounds/ublinux done - [ -d usr/share/backgrounds ] || mkdir -p usr/share/backgrounds + [[ -d ${ROOTFS}/usr/share/backgrounds ]] || mkdir -p ${ROOTFS}/usr/share/backgrounds # With masked /memory/* , with parametre kernel "ub.mask" - [[ $(cmdline_parameter ub.mask) || $(cmdline_parameter ub.hide) ]] && find /memory/layer-base/*/backgrounds/* -maxdepth 0 -exec cp -fru {} usr/share/backgrounds/ \; + [[ $(cmdline_parameter ub.mask) || $(cmdline_parameter ub.hide) ]] && find /memory/layer-base/*/backgrounds/* -maxdepth 0 -exec cp -fru {} ${ROOTFS}/usr/share/backgrounds/ \; # With unmasked /memory/* , without parametre kernel "ub.mask" - [[ -z $(cmdline_parameter ub.mask) || -z $(cmdline_parameter ub.hide) ]] && find /memory/layer-base/*/backgrounds/* -maxdepth 0 -exec ln -s {} usr/share/backgrounds/ \; + [[ -z $(cmdline_parameter ub.mask) || -z $(cmdline_parameter ub.hide) ]] && find /memory/layer-base/*/backgrounds/* -maxdepth 0 -exec ln -fs {} ${ROOTFS}/usr/share/backgrounds/ \; diff --git a/ublinux/rc.preinit.d/60-lightdm-settings b/ublinux/rc.preinit.d/60-lightdm-settings index 144d88f..abe2f1d 100755 --- a/ublinux/rc.preinit.d/60-lightdm-settings +++ b/ublinux/rc.preinit.d/60-lightdm-settings @@ -43,16 +43,20 @@ exec_lightdm_xdmcp(){ fi FILE_LIGHTDM_CONF="${ROOTFS}/etc/lightdm/lightdm.conf" FILE_LIGHTDM_XDMCP_CONF="${ROOTFS}/etc/lightdm/lightdm.conf.d/99-xdmcp-ubconfig.conf" - if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${LIGHTDM_XDMCP} == @("enable"|"yes") && ${#LIGHTDM_XDMCP[@]} -ne 0 ]]; then - [[ -d ${ROOTFS}/etc/lightdm/${FILE_LIGHTDM_XDMCP_CONF%/*} ]] || mkdir -p ${FILE_LIGHTDM_XDMCP_CONF%/*} - cat <<-EOF | sed 's/^\s*\t*//' > "${FILE_LIGHTDM_XDMCP_CONF}" - [XDMCPServer] - enabled=true + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && ${#LIGHTDM_XDMCP[@]} -ne 0 ]]; then + if [[ ${LIGHTDM_XDMCP} == @("enable"|"yes") ]]; then + [[ -d ${ROOTFS}/etc/lightdm/${FILE_LIGHTDM_XDMCP_CONF%/*} ]] || mkdir -p ${FILE_LIGHTDM_XDMCP_CONF%/*} + cat <<-EOF | sed 's/^\s*\t*//' > "${FILE_LIGHTDM_XDMCP_CONF}" + [XDMCPServer] + enabled=true EOF - for LIGHTDM_PARAM in "${!LIGHTDM_XDMCP[@]}"; do - [[ ${LIGHTDM_PARAM} == 0 ]] && continue - echo "${LIGHTDM_PARAM}=${LIGHTDM_XDMCP[${LIGHTDM_PARAM}]}" >> "${FILE_LIGHTDM_XDMCP_CONF}" - done + for LIGHTDM_PARAM in "${!LIGHTDM_XDMCP[@]}"; do + [[ ${LIGHTDM_PARAM} == 0 ]] && continue + echo "${LIGHTDM_PARAM}=${LIGHTDM_XDMCP[${LIGHTDM_PARAM}]}" >> "${FILE_LIGHTDM_XDMCP_CONF}" + done + else + rm -f "${FILE_LIGHTDM_XDMCP_CONF}" + fi elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then rm -f "${FILE_LIGHTDM_XDMCP_CONF}" fi diff --git a/ublinux/rc.preinit.d/90-apparmor b/ublinux/rc.preinit.d/90-apparmor index 3b935df..f15af90 100755 --- a/ublinux/rc.preinit.d/90-apparmor +++ b/ublinux/rc.preinit.d/90-apparmor @@ -26,8 +26,8 @@ SERVICEAPPARMOR="apparmor.service" mkdir -p proc mount -o rbind /proc proc if readlink -fq ${ROOTFS}/usr/bin/init | grep -q "lib/systemd/systemd$"; then - ${CMD_CHROOT} /usr/bin/systemctl unmask ${SERVICEAPPARMOR} - ${CMD_CHROOT} /usr/bin/systemctl enable ${SERVICEAPPARMOR} || ${CMD_CHROOT} /usr/bin/chkconfig --add ${SERVICEAPPARMOR} + ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SERVICEAPPARMOR} + ${CMD_CHROOT} /usr/bin/systemctl --quiet enable ${SERVICEAPPARMOR} || ${CMD_CHROOT} /usr/bin/chkconfig --add ${SERVICEAPPARMOR} else ${CMD_CHROOT} /usr/bin/chkconfig --add ${SERVICEAPPARMOR} fi @@ -44,5 +44,3 @@ StartupNotify=false NoDisplay=true EOF fi - - diff --git a/ublinux/rc.preinit/01-inifile b/ublinux/rc.preinit/01-inifile index 57b17c9..77c9e17 100755 --- a/ublinux/rc.preinit/01-inifile +++ b/ublinux/rc.preinit/01-inifile @@ -53,7 +53,7 @@ SYSCONF="${ROOTFS}${SYSCONF}" NAME_VAR=${LINE%%=*} [[ ${LINE} != ${NAME_VAR} ]] || continue [[ -f ${FILE_CONFIG} && $(cat -n ${FILE_CONFIG}) =~ ($'\n'|^)+[[:blank:]]*([[:digit:]]+)[[:blank:]]*"${NAME_VAR}="[^$'\n']*($'\n'|$)+ ]] && sed "${BASH_REMATCH[2]}d" -i "${FILE_CONFIG}" - if [[ ${FILE_CONFIG##*/} == "users" && ${NAME_VAR} =~ ^("DEFAULTPASSWD"|"DEFAULTROOTPASSWD"|"NEEDEDUSERS"|"USERADD"|"GROUPADD") ]]; then + if [[ ${FILE_CONFIG##*/} == "users" && ${NAME_VAR} =~ ^("DEFAULTPASSWD"|"DEFAULTROOTPASSWD"|"NEEDEDUSERS"|"USERADD["|"GROUPADD[") ]]; then echo "${LINE}" >> ${FILE_ROOT_USERS} if [[ ${NAME_VAR} == @("DEFAULTPASSWD"|"DEFAULTROOTPASSWD"|"NEEDEDUSERS") ]]; then true diff --git a/ublinux/rc.preinit/10-accounts b/ublinux/rc.preinit/10-accounts index 068175d..1320ad1 100755 --- a/ublinux/rc.preinit/10-accounts +++ b/ublinux/rc.preinit/10-accounts @@ -21,41 +21,46 @@ SYSCONF="${ROOTFS}${SYSCONF}" SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/users; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null SOURCE=${SYSCONF}/system; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null +SOURCE=${SYSCONF}/locale; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null FILE_ROOT_USERS="${SYSCONF}/.users_credential" SOURCE=${FILE_ROOT_USERS}; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null +shopt -s extglob + FILE_PASSWD="${ROOTFS}/etc/passwd" FILE_SHADOW="${ROOTFS}/etc/shadow" FILE_GROUP="${ROOTFS}/etc/group" FILE_GSHADOW="${ROOTFS}/etc/gshadow" - PATH_HOME="/home" + FILE_DEFAULT_USERADD="${ROOTFS}/etc/default/useradd" + DATA_FILE_DEFAULT_USERADD=$(cat ${FILE_DEFAULT_USERADD}) + DEFAULT_HOME_USER="/home" NAME_REGEX="^[a-z_][-a-z0-9_]*\$" # Задать пароль пользователю # $1 # Имя пользователя # $2 # Зашифрованный пароля, если не указан, то пароль '!*' запрет авторизации -set_passwd(){ - USER_NAME="${1}" - USER_PASS="${2}" - [[ ${USER_NAME} != "" ]] || return 1 - [[ ${USER_PASS} != "" ]] || USER_PASS='!*' - if [[ -x ${ROOTFS}/usr/bin/chpasswd ]]; then - echo "${USER_NAME}:${USER_PASS}" | ${CMD_CHROOT} /usr/bin/chpasswd --encrypted - else - ESC_USER_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${USER_PASS}") - EPOCH_DAY=$(( $(date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day - USER_FROM_SHADOW=$(grep "^${USER_NAME}:" "${FILE_SHADOW}") - if [[ -z ${USER_FROM_SHADOW} ]]; then - echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" - elif [[ ! ${USER_FROM_SHADOW} =~ ^"${USER_NAME}:${USER_PASS}:" ]]; then - sed -E "s/^${USER_NAME}:[^:]+:[0-9]+:/${USER_NAME}:${ESC_USER_PASS}:${EPOCH_DAY}:/" -i "${FILE_SHADOW}" - sed -E "s/${USER_NAME}:[!]*:/${USER_NAME}:\!\*:/" -i "${FILE_SHADOW}" - #sed /^${USER_NAME}:/d -i "${FILE_SHADOW}" - #echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" - fi - fi -} +#set_passwd(){ +# USER_NAME="${1}" +# USER_PASS="${2}" +# [[ ${USER_NAME} != "" ]] || return 1 +# [[ ${USER_PASS} != "" ]] || USER_PASS='!*' +# if [[ -x ${ROOTFS}/usr/bin/chpasswd ]]; then +# echo "${USER_NAME}:${USER_PASS}" | ${CMD_CHROOT} /usr/bin/chpasswd --encrypted +# else +# ESC_USER_PASS=$(sed 's/[^a-zA-Z0-9,_@%-]/\\&/g' <<< "${USER_PASS}") +# EPOCH_DAY=$(( $(${CMD_CHROOT} date +%s)/(60*60*24) )) # (60*60*24)=18400 second on day +# USER_FROM_SHADOW=$(grep "^${USER_NAME}:" "${FILE_SHADOW}") +# if [[ -z ${USER_FROM_SHADOW} ]]; then +# echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" +# elif [[ ! ${USER_FROM_SHADOW} =~ ^"${USER_NAME}:${USER_PASS}:" ]]; then +# sed -E "s/^${USER_NAME}:[^:]+:[0-9]+:/${USER_NAME}:${ESC_USER_PASS}:${EPOCH_DAY}:/" -i "${FILE_SHADOW}" +# sed -E "s/${USER_NAME}:[!]*:/${USER_NAME}:\!\*:/" -i "${FILE_SHADOW}" +# #sed /^${USER_NAME}:/d -i "${FILE_SHADOW}" +# #echo "${USER_NAME}:${USER_PASS}:${EPOCH_DAY}:0:99999:7:::" >> "${FILE_SHADOW}" +# fi +# fi +#} # Задать пароль группе # $1 # Имя группы @@ -89,128 +94,231 @@ create_home(){ local ARG_RECURSIVE= [[ ${SELECT_GROUP} == "" || ${SELECT_GROUP} == "-" ]] && SELECT_GROUP=${SELECT_USERNAME} [[ ${SELECT_USERNAME} != "" ]] || return 1 - if [[ -d "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" ]]; then - ${CMD_CHROOT} /usr/bin/chmod -f u+rw,g-rwx,o-rwx "${PATH_HOME}/${SELECT_USERNAME}" - [[ -z ${SELECT_FORCESKEL} ]] || cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" + if [[ -d "${ROOTFS}${DEFAULT_HOME_USER}/${SELECT_USERNAME}" ]]; then + ${CMD_CHROOT} /usr/bin/chmod -f u+rw,g-rwx,o-rwx "${DEFAULT_HOME_USER}/${SELECT_USERNAME}" + [[ -z ${SELECT_FORCESKEL} ]] || cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${DEFAULT_HOME_USER}/${SELECT_USERNAME}" else - install -dm700 "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" - cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" + install -dm700 "${ROOTFS}${DEFAULT_HOME_USER}/${SELECT_USERNAME}" + cp -Taf ${ROOTFS}/etc/skel "${ROOTFS}${DEFAULT_HOME_USER}/${SELECT_USERNAME}" fi - #rsync -rlpt --ignore-existing etc/skel/ "${ROOTFS}${PATH_HOME}/${SELECT_USERNAME}" + #rsync -rlpt --ignore-existing etc/skel/ "${ROOTFS}${DEFAULT_HOME_USER}/${SELECT_USERNAME}" [[ -n ${ROOTFS} ]] && ARG_RECURSIVE="-R" || ARG_RECURSIVE= - ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} "${SELECT_USERNAME}" ${PATH_HOME}/"${SELECT_USERNAME}" - ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} :"${SELECT_GROUP}" "${PATH_HOME}/${SELECT_USERNAME}" + ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} "${SELECT_USERNAME}" ${DEFAULT_HOME_USER}/"${SELECT_USERNAME}" + ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} :"${SELECT_GROUP}" "${DEFAULT_HOME_USER}/${SELECT_USERNAME}" } # Задаём пароль root пользователю -exec_00_defaultrootpasswd(){ -#echo "exec_00_defaultrootpasswd" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_01_defaultrootpasswd(){ +#echo "exec_01_defaultrootpasswd" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" local PARAM="$@" if [[ -n ${PARAM} ]]; then [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${DEFAULTROOTPASSWD} && ! ${DEFAULTROOTPASSWD,,} == @(no|none|disable) ]]; then # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр DEFAULTROOTPASSWD из '/etc/ublinux/users - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - if [[ -f ${FILE_ROOT_USERS} ]]; then - sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}" - echo "DEFAULTROOTPASSWD='${DEFAULTROOTPASSWD}'" >> ${FILE_ROOT_USERS} - fi - [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users" + if [[ -f ${FILE_ROOT_USERS} ]]; then + sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}" + echo "DEFAULTROOTPASSWD='${DEFAULTROOTPASSWD}'" >> ${FILE_ROOT_USERS} fi - [[ -n ${DEFAULTROOTPASSWD} ]] && DEFAULTROOTPASSWD=$(return_hash_password hash ${HASHPASSWD} ${DEFAULTROOTPASSWD}) - set_passwd root "${DEFAULTROOTPASSWD}" + [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users" + DEFAULTROOTPASSWD=$(return_hash_password hash ${HASHPASSWD} ${DEFAULTROOTPASSWD}) + #set_passwd root "${DEFAULTROOTPASSWD}" + user_add "root:+:+:+:${DEFAULTROOTPASSWD}:+:+:+:+:+:+:+:+" elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - [[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}" - [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users" - fi - + [[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${FILE_ROOT_USERS}" + [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTROOTPASSWD=/d" -i "${SYSCONF}/users" fi } # Задаём пароль по умолчанию пользователю -exec_00_defaultpasswd(){ -#echo "exec_00_defaultpasswd" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_02_defaultpasswd(){ +#echo "exec_02_defaultpasswd" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" local PARAM="$@" if [[ -n ${PARAM} ]]; then [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${DEFAULTPASSWD} ]]; then # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр DEFAULTROOTPASSWD из '/etc/ublinux/users - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - if [[ -f ${FILE_ROOT_USERS} ]]; then - sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}" - echo "DEFAULTPASSWD='${DEFAULTPASSWD}'" >> ${FILE_ROOT_USERS} - fi - [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users" + if [[ -f ${FILE_ROOT_USERS} ]]; then + sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}" + echo "DEFAULTPASSWD='${DEFAULTPASSWD}'" >> ${FILE_ROOT_USERS} fi + [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users" elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - [[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}" - [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users" - fi - + [[ -f ${FILE_ROOT_USERS} ]] && sed "/DEFAULTPASSWD=/d" -i "${FILE_ROOT_USERS}" + [[ -f "${SYSCONF}/users" ]] && sed "/DEFAULTPASSWD=/d" -i "${SYSCONF}/users" fi } # Создаём группы из ${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS} c ID из /usr/share/ublinux-sysusers/*.sysusers -exec_01_add_groups(){ -#echo "exec_01_add_groups" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_03_add_groups(){ +#echo "exec_03_add_groups" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" local PARAM="$@" - local GROUPADD_GROUPS SELECT_GROUP ARG_FINDGROUP_ID FINDGROUP_ID - DATA_FILE_GROUP=$(cat ${FILE_GROUP}) + local GROUPADD_GROUPS= SELECT_GROUP= SELECT_GID= + local DATA_FILE_GROUP=$(cat ${FILE_GROUP}) # Загрузить файлы которые совпадают в каталогах /usr/lib/sysusers.d/ и /usr/share/ublinux-sysusers/. И загрузить которые уникальные в /usr/lib/sysusers.d/ - DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) + local DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) if [[ -n ${PARAM} ]]; then - GROUPADD_GROUPS=${PARAM} + local GROUPADD_GROUPS=${PARAM} else - GROUPADD_GROUPS="${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS}" + local GROUPADD_GROUPS="${DEFAULTGROUP},${ADMGROUPS},${USERGROUPS}" fi if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${GROUPADD_GROUPS} ]]; then GROUPADD_GROUPS=${GROUPADD_GROUPS//;/,}; GROUPADD_GROUPS="${GROUPADD_GROUPS//,,/,}" [[ ${GROUPADD_GROUPS:0:1} == ',' ]] && GROUPADD_GROUPS=${GROUPADD_GROUPS:1} [[ ${GROUPADD_GROUPS} =~ ','$ ]] && GROUPADD_GROUPS=${GROUPADD_GROUPS%*,} + local SELECT_GROUP= [[ -n ${GROUPADD_GROUPS} ]] && while IFS= read -u3 SELECT_GROUP; do - local ARG_FINDGROUP_ID= - # Найти группу по имени - [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID= - # Найти группу по GID - #[[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]} - if [[ ${FINDGROUP_ID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*:${FINDGROUP_ID}:[^$'\n']*($'\n'|$)+ ]]; then + local SELECT_GID= + # Поиск по имени в шаблонах пользователей/групп systemd, если найдено, то GID из шаблона + [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+('g'|'u')[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && SELECT_GID=${BASH_REMATCH[3]} + # Поиск по GID в шаблонах пользователей/групп systemd, если найдено, то GID=SELECT_GROUP, а SELECT_GROUP из шаблона + [[ ${SELECT_GID} != "" && ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${DATA_SYSUSERS} =~ ($'\n'|^)+('g'|'u')[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] \ + && SELECT_GID=${SELECT_GROUP} && SELECT_GROUP=${BASH_REMATCH[3]} + if [[ ${SELECT_GID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUP}":[^$'\n']*:"${SELECT_GID}":[^$'\n']*($'\n'|$)+ ]]; then # Группа найдена, имя и id совпадают, пропускаем добавление continue - elif [[ ${FINDGROUP_ID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}:[^$'\n']*($'\n'|$)+ ]]; then - # Группа найдена, имя и id не совпадают, удаляем группу - echo "WARNING: the group '${SELECT_GROUP}' has an id different from the template /usr/share/ublinux-sysusers/*.sysusers and the id will be changed to '${SELECT_GROUP}:${FINDGROUP_ID}'" - ${CMD_CHROOT} /usr/bin/groupdel -f ${SELECT_GROUP} - fi - [[ ${FINDGROUP_ID} == @(""|"-") ]] || ARG_FINDGROUP_ID="--gid ${FINDGROUP_ID}" - if [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]]; then - ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_FINDGROUP_ID} ${SELECT_GROUP} + elif [[ ${SELECT_GID} != "" && ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUP}":[^$'\n']*($'\n'|$)+ ]]; then + # Группа найдена, имя совпадает, но id не совпадает, меняем GID у группы, все остальные параметры группы не изменяем + #echo "WARNING: the group '${SELECT_GROUP}' has an id different from the template '/usr/share/ublinux-sysusers/*.sysusers' and the id will be changed to '${SELECT_GROUP}:${SELECT_GID}'" + group_add "${SELECT_GROUP}:${SELECT_GID}:+:+:+" else - >&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name" + # Группа не найдена, добавить новую + [[ ${SELECT_GID} == @(""|"-") ]] && SELECT_GID="+" + if [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]]; then + group_add "${SELECT_GROUP}:${SELECT_GID}:+:+:+" + else + >&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name" + fi fi done 3<<< "${GROUPADD_GROUPS//,/$'\n'}" fi } +# Функция добавление/удаление групп в систему. Если группа существует, то изменить под параметры +# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove +# $2 Для команды set=|set+=|set++= параметр со значением, пример: GROUPADD[g_department_1]=ob.ivanov,rv.smirnov +# Для команды set-=|set--=|remove параметр только с именем, пример: GROUPADD[g_department_1] +# null Если отсутствует $@, то применяем из системной конфигурации GROUPADD[*] + +## GROUPADD[group_name]='group_users:gid:optional:password|x' +## group_name # Имя группы +## group_users # Пользователи группы, перечисление через запятую. Может быть пусто. +## gid # GID группы +## null|x # Если пусто или 'x', то автоматически рассчитывать +## s|system # Назначить системный свободный GID +## optional # Дополнительные параметры, например: '--system --non-unique' +## -o|--non-unique # Разрешить создание групп с повторяющимися (не уникальными) GID +## -r|--system # Cоздавать системную группу +## administrators # Администраторы группы которые могут менять пароль группы и добавлять членов +## password|x # Хеш пароля группа, если выбрано 'x' или пусто, то группа без пароля +## + # Значение "+" в любом блоке означает, что данные поля будут взяты с существующей группы +## GROUPADD[g_department_1]=ob.ivanov,rv.smirnov +## GROUPADD[g_department_2]='ob.ivanov,rv.smirnov:1001:x:superadmin:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60' +exec_04_groupadd(){ +#echo "exec_04_groupadd" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" + local PARAM="$@" + [[ $(declare -p GROUPADD 2>/dev/null) =~ ^"declare -A" ]] || declare -gA GROUPADD + local SELECT_GROUP SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL + local ARG_SELECT_USERS ARG_SELECT_GID SELECT_OPTIONAL ARG_SELECT_PASSWORD ARG_NON_UNIQUE + local DATA_FILE_PASSWD REAL_SELECT_USERS REAL_SELECT_ADMINISTRATORS + local FILE_GROUP="${ROOTFS}/etc/group" + local DATA_FILE_GROUP=$(cat ${FILE_GROUP}) + local DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) + if [[ -n ${PARAM} ]]; then + local GROUPADD= + declare -A GROUPADD + [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" + fi + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#GROUPADD[@]} != 0 ]]; then + groupadd_local(){ + get_free_gid(){ + local PARAM="$@" + local GID_MIN= GID_MAX= GID_NEW= + # Свободный номер списка групп, кроме системного списка + 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} + printf "%d" "${GID_NEW}" + } + local SELECT_GROUP=$1 + # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр GROUPADD[.*] из '/etc/ublinux/users + IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}" + [[ ${SELECT_USERS} == "x" ]] && SELECT_USERS= + # Поиск по имени в шаблонах пользователей/групп systemd, если найдено, то GID из шаблона + [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+('g'|'u')[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] \ + && SELECT_GID=${BASH_REMATCH[3]} + # Поиск по GID в шаблонах пользователей/групп systemd, если найдено, то GID=SELECT_GROUP, а SELECT_GROUP из шаблона + [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${DATA_SYSUSERS} =~ ($'\n'|^)+('g'|'u')[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] \ + && SELECT_GID=${SELECT_GROUP} && SELECT_GROUP=${BASH_REMATCH[3]} + [[ ${SELECT_GID,,} == 'x' ]] && SELECT_GID=$(get_free_gid) + [[ ${SELECT_GID} =~ ^([[:digit:]]+|'s'|'system')$ ]] || SELECT_GID=$(get_free_gid) + [[ ${SELECT_OPTIONAL} == 'x' ]] && SELECT_OPTIONAL= + [[ ${SELECT_OPTIONAL} =~ ('-r'|'--system') ]] && SELECT_GID="system" + #[[ ! ${SELECT_OPTIONAL} =~ ('-o'|'--non-unique') && ${DATA_FILE_GROUP} =~ ($'\n'|^)+[^:]*:[^:]*:"${SELECT_GID}": ]] && { >&2 echo "ERROR: '${SELECT_GROUP}' non unique a group ID (GID)"; return 1; } + [[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD= + [[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD}) +#echo "==> exec_04_groupadd: ${SELECT_GROUP}:${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}" + group_add "${SELECT_GROUP}:${SELECT_GID}:${SELECT_USERS}:${SELECT_PASSWORD}:${SELECT_ADMINISTRATORS}" + if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then + if [[ -f ${FILE_ROOT_USERS} ]]; then + sed "/GROUPADD\[${SELECT_GROUP}\]=/d" -i "${FILE_ROOT_USERS}" + echo "GROUPADD[${SELECT_GROUP}]='${GROUPADD[${SELECT_GROUP}]}'" >> ${FILE_ROOT_USERS} + fi + [[ -f "${SYSCONF}/users" ]] && sed -E "s/(GROUPADD\[${SELECT_GROUP}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users" + fi + } + local SELECT_GROUP= LIST_GROUPADD_GID= LIST_GROUPADD_NOGID= + while IFS= read -ru3 SELECT_GROUP; do + [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]] || { >&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name"; continue; } + IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}" + if [[ ${SELECT_GID} =~ ^[0-9]+$ ]] ; then + LIST_GROUPADD_GID+="groupadd_local ${SELECT_GROUP}; " + else + LIST_GROUPADD_NOGID+="groupadd_local ${SELECT_GROUP}; " + fi + done 3< <(printf "%s\n" "${!GROUPADD[@]}") + [[ -n ${LIST_GROUPADD_GID} ]] && eval "${LIST_GROUPADD_GID}" + [[ -n ${LIST_GROUPADD_NOGID} ]] && eval "${LIST_GROUPADD_NOGID}" + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then + if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then + SELECT_GROUP=${BASH_REMATCH[1]} + if [[ ${SELECT_GROUP} == @("*"|"**"|"/"|"//") ]]; then + while IFS= read -ru3 SELECT_GROUP; do + group_del ${SELECT_GROUP} + [[ -f ${FILE_ROOT_USERS} ]] && sed "/GROUPADD\[${SELECT_GROUP}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null + done 3< <(printf "%s\n" "${!GROUPADD[@]}") + else + group_del ${SELECT_GROUP} + [[ -f ${FILE_ROOT_USERS} ]] && sed "/GROUPADD\[${SELECT_GROUP}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null + fi + fi + fi +} + # Создаем пользователей из ${NEEDEDUSERS} и добавляем в группы # $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove # $2 Для команды set=|set+=|set++= параметр со значением, пример: # Для команды set-=|set--=|remove параметр только с именем, пример: # null Если отсутствует $@, то применяем из системной конфигурации -exec_02_neededusers(){ -#echo "exec_02_neededusers" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_05_neededusers(){ +#echo "exec_05_neededusers" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" local PARAM="$@" local SELECT_USERNAME SELECT_UID SELECT_PASSWORD SELECT_GECOS NULL ADDGROUPS local ARG_DEFAULTGROUP ARG_SELECT_UID ARG_SELECT_GECOS @@ -219,7 +327,7 @@ exec_02_neededusers(){ fi # Если по умолчанию нет ни одного пользователя, то создаём администратора #[[ -z ${NEEDEDUSERS} ]] && NEEDEDUSERS="${DEFAULTUSER}:${ADMUID}:${DEFAULTPASSWD}:Administrator" - [[ -z $(cmdline_value users) ]] || NEEDEDUSERS=$(cmdline_value users) + [[ -n ${ROOTFS} ]] && { [[ -z $(cmdline_value users) ]] || NEEDEDUSERS=$(cmdline_value users); } [[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes if [[ -n ${NEEDEDUSERS} ]]; then while IFS= read -ru3 SELECT_USER; do @@ -250,12 +358,12 @@ exec_02_neededusers(){ if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-c '${SELECT_GECOS}'" || ARG_SELECT_GECOS= [[ -n ${DEFAULTGROUP} ]] && ARG_DEFAULTGROUP="-G ${DEFAULTGROUP}" || ARG_DEFAULTGROUP= - eval ${CMD_CHROOT} /usr/bin/useradd -M ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME} #>/dev/null 2>&1 + eval "${CMD_CHROOT} /usr/bin/useradd -M ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME}" #>/dev/null 2>&1 elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then # busybox adduser [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g '${SELECT_GECOS}'" || ARG_SELECT_GECOS= [[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}" - eval ${CMD_CHROOT} /usr/bin/busybox adduser -D -H ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME} #>/dev/null 2>&1 + eval "${CMD_CHROOT} /usr/bin/busybox adduser -D -H ${ARG_DEFAULTGROUP} ${ARG_SELECT_UID} ${ARG_SELECT_GECOS} ${SELECT_USERNAME}" #>/dev/null 2>&1 fi # Добавляем пользователя в группу USER_GROUPS="${ADDGROUPS//;/,}" @@ -263,10 +371,11 @@ exec_02_neededusers(){ # Задаём пароль пользователю #[[ -n ${SELECT_PASSWORD} ]] && return_hash_password "${SELECT_PASSWORD}" && [[ -n ${HASH_PASSWORD_NEW} ]] && SELECT_PASSWORD="${HASH_PASSWORD_NEW}" [[ -n ${SELECT_PASSWORD} ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD}) - set_passwd "${SELECT_USERNAME}" "${SELECT_PASSWORD}" + #set_passwd "${SELECT_USERNAME}" "${SELECT_PASSWORD}" + user_add "${SELECT_USERNAME}:+:+:+:${SELECT_PASSWORD}:+:+:+:+:+:+:+:+" fi # Создаём домашний каталог принудительно и копируем /etc/skel - if [[ ! -d ${ROOTFS}${PATH_HOME}/"${SELECT_USERNAME}" \ + if [[ ! -d ${ROOTFS}${DEFAULT_HOME_USER}/"${SELECT_USERNAME}" \ || ${UPDATEHOME[${SELECT_USERNAME}],,} == @(yes|y|enable) \ || ${UPDATEHOME,,} == @(yes|y|enable) ]]; then create_home "${SELECT_USERNAME}" - force @@ -311,16 +420,17 @@ exec_02_neededusers(){ ## user_name # Имя пользователя, необязательное поле. Если не указано, то применяется для всех пользователей ## boot # При загрузке системы принудительно применить глобальную конфигурацию на пользователя ## shutdown # При завершении работы системы синхронизировать указанных пользователей в системе с глобальной конфигурацией -exec_03_useradd(){ -#echo "exec_03_useradd" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_06_useradd(){ +#echo "exec_06_useradd" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" [[ ${USERADD} != @(none|no|disable) ]] || return 0 - [[ -n ${USERADD_SYNC} ]] || declare -gA USERADD_SYNC - [[ -n ${UPDATEHOME} ]] || declare -gA UPDATEHOME - [[ -n ${USERADD} ]] || declare -gA USERADD - declare -gA USERSHADOW + [[ $(declare -p USERADD_SYNC 2>/dev/null) =~ ^"declare -A" ]] || declare -gA USERADD_SYNC + [[ $(declare -p UPDATEHOME 2>/dev/null) =~ ^"declare -A" ]] || declare -gA UPDATEHOME + [[ $(declare -p USERADD 2>/dev/null) =~ ^"declare -A" ]] || declare -gA USERADD + [[ $(declare -p USERSHADOW 2>/dev/null) =~ ^"declare -A" ]] || declare -gA USERSHADOW + local SELECT_USERNAME SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_OPTIONAL SELECT_PASSWORD NULL local ARG_SELECT_UID ARG_SELECT_GROUP ARG_SELECT_GECOS ARG_SELECT_PASSWORD ARG_SELECT_OPTIONAL local ARG_GROUPADD_GID ARG_GROUPADD_GROUPNAME @@ -332,200 +442,130 @@ exec_03_useradd(){ [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi # Если в GRUB указан параметр useradd, то создать пользователя - while IFS=':' read -u3 SELECT_USERNAME SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_PASSWORD NULL; do + [[ -n ${ROOTFS} ]] && while IFS=':' read -u3 SELECT_USERNAME SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_PASSWORD NULL; do [[ ${SELECT_USERNAME} != "" ]] && USERADD[${SELECT_USERNAME}]=":${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUP}:x:${SELECT_PASSWORD}" done 3< <(tr ';' '\n' <<< $(cmdline_value useradd)) - if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then - [[ ${#USERADD[@]} == 0 ]] && USERADD[${DEFAULTUSER}]="Administrator:${ADMUID}:x:x:x:${DEFAULTPASSWD}" + if [[ ${#USERADD[@]} == 0 ]]; then + local DEFAULTUSER_GECOS="Administrator" + [[ ${LANG} =~ "ru_RU" ]] && DEFAULTUSER_GECOS="Администратор" + USERADD[${DEFAULTUSER}]="${DEFAULTUSER_GECOS}:${ADMUID}:x:x:x:${DEFAULTPASSWD}" + fi + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERADD[@]} -ne 0 ]]; then [[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes + local DATA_FILE_PASSWD=$(cat ${FILE_PASSWD}) + local DATA_FILE_GROUP=$(cat ${FILE_GROUP}) useradd_local(){ - DATA_FILE_PASSWD=$(cat ${FILE_PASSWD}) - DATA_FILE_GROUP=$(cat ${FILE_GROUP}) local SELECT_USERNAME=$1 - # Вызов как исполнителя после ubconfig - # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить хеш пароля параметра USERADD[.*] в /etc/ublinux/users - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - if [[ -f ${FILE_ROOT_USERS} ]]; then - sed "/USERADD\[${SELECT_USERNAME}\]=/d" -i "${FILE_ROOT_USERS}" - echo "USERADD[${SELECT_USERNAME}]='${USERADD[${SELECT_USERNAME}]}'" >> ${FILE_ROOT_USERS} - fi - [[ -f "${SYSCONF}/users" ]] && sed -E "s/(USERADD\[${SELECT_USERNAME}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users" - fi # Проверяем существует ли пользователь в системе [[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+"${SELECT_USERNAME}": ]] && IS_USERNAME_PASSWD=yes || IS_USERNAME_PASSWD= # Проверяем отсутствие пользователя в системе или параметр принудительного обновления if [[ ${IS_USERNAME_PASSWD} == "" || ${USERADD_SYNC} =~ 'boot' || ${USERADD_SYNC[${SELECT_USERNAME}]} =~ 'boot' ]]; then IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}" -#echo -e "\n===> exec_03_useradd: ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}" + [[ ${NULL} == "" ]] || { >&2 echo "WARNING: Unnecessary processing of the ':' character. USERADD[${SELECT_USERNAME}]"; } +#echo -e "\n===> exec_06_useradd: ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}" [[ ${SELECT_GECOS,,} == "x" ]] && SELECT_GECOS= - [[ ${SELECT_OPTIONAL,,} == "x" ]] && SELECT_OPTIONAL= - [[ ${SELECT_OPTIONAL} =~ ("--home-dir "|"-d ")([^' ']*)(' '|$) ]] && HOME_DIR_SELECT_USERNAME="${BASH_REMATCH[2]}" || HOME_DIR_SELECT_USERNAME="${PATH_HOME}/${SELECT_USERNAME}" + # ----------- [[ ${SELECT_UID,,} == "x" || ${SELECT_UID} =~ ^[^0-9]+$ ]] && SELECT_UID= # Если существует домашний каталог пользователя, то UID берём от каталога - if [[ -z ${SELECT_UID} && -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]]; then - SELECT_UID=$(stat -c %u "${ROOTFS}${HOME_DIR_SELECT_USERNAME}") + if [[ -z ${SELECT_UID} && -d "${ROOTFS}${SELECT_HOME}" ]]; then + SELECT_UID=$(stat -c %u "${ROOTFS}${SELECT_HOME}") [[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+[^:]*:[^:]*:"${SELECT_UID}": ]] && SELECT_UID= fi + # ----------- [[ ${SELECT_GROUP,,} == "x" ]] && SELECT_GROUP= # Если существует домашний каталог пользователя, то GID берём от каталога - if [[ -z ${SELECT_GROUP} && -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]]; then - SELECT_GROUP=$(stat -c %g "${ROOTFS}${HOME_DIR_SELECT_USERNAME}") + if [[ -z ${SELECT_GROUP} && -d "${ROOTFS}${SELECT_HOME}" ]]; then + SELECT_GROUP=$(stat -c %g "${ROOTFS}${SELECT_HOME}") [[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+[^:]*:[^:]*:[^:]*:"${SELECT_GROUP}": ]] && SELECT_GROUP= fi - [[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD="${DEFAULTPASSWD}" - [[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD="$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})" - [[ ${SELECT_EXTRAGROUPS,,} == "x" ]] && SELECT_EXTRAGROUPS= - # Если в дополнительных группа присутствует группа по имени пользователя, то удалить её из списка - SELECT_EXTRAGROUPS=${SELECT_EXTRAGROUPS//${SELECT_USERNAME}/} - # Создадать группы из параметра SELECT_EXTRAGROUPS - local SELECT_EXTRAGROUPS_TO_EXEC_01= - local SELECT_EXTRAGROUPS_TO_EXEC_05= - [[ -n ${SELECT_EXTRAGROUPS} ]] && while IFS= read -u4 ITEM_SELECT_EXTRAGROUP; do - [[ ${ITEM_SELECT_EXTRAGROUP} != "" ]] || continue - if [[ -n ${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]} ]]; then - #exec_05_groupadd "GROUPADD[${ITEM_SELECT_EXTRAGROUP}]=${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]}" - SELECT_EXTRAGROUPS_TO_EXEC_05+="exec_05_groupadd GROUPADD[${ITEM_SELECT_EXTRAGROUP}]=${GROUPADD[${ITEM_SELECT_EXTRAGROUP}]}; " - else - SELECT_EXTRAGROUPS_TO_EXEC_01+="${ITEM_SELECT_EXTRAGROUP}," - fi - done 4<<< "${SELECT_EXTRAGROUPS//,/$'\n'}" -#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && echo "exec_01_add_groups ${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}" -# [[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && exec_01_add_groups "${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}" -#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && echo "eval ${SELECT_EXTRAGROUPS_TO_EXEC_05}" -# [[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && eval "${SELECT_EXTRAGROUPS_TO_EXEC_05}" - SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS},${USERGROUPS}" - [[ ${SELECT_UID} == ${ADMUID} && ${ADDADM} == "yes" ]] && SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS},${ADMGROUPS}" - SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//;/,}"; SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//,,/,}" - [[ ${SELECT_EXTRAGROUPS:0:1} == "," ]] && SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS:1}" -#echo "===> ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}:${SELECT_PASSWORD}" -#echo "===> ${SELECT_USERNAME}=${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUPS}:${SELECT_OPTIONAL}" - - ARG_SELECT_UID=; ARG_SELECT_GROUP=; ARG_SELECT_GECOS=; ARG_SELECT_PASSWORD=; ARG_SELECT_OPTIONAL=; STATUS=; IS_USERNAME_PASSWD= - [[ -n ${SELECT_UID} && ${SELECT_UID} != 0 ]] && ARG_SELECT_UID="--uid ${SELECT_UID}" || ARG_SELECT_UID= - # Если указана основная группа, но она не создана, то создать - local ARG_GROUPADD_GID= ARG_GROUPADD_GROUPNAME= - if [[ -n ${SELECT_GROUP} && -n ${GROUPADD[${SELECT_GROUP}]} ]]; then - # Если группа указана и присутствует в списке групп GROUPADD[.] -#echo 0:${SELECT_GROUP} -#echo "exec_05_groupadd GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}" - exec_05_groupadd "GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}" - elif [[ -n ${SELECT_GROUP} && ! ${DATA_FILE_GROUP} =~ ($'\n'|^)+(${SELECT_GROUP}:|[^$'\n']*:${SELECT_GROUP}:) ]]; then - # Если группа указана и не найдена в файле shadow + if [[ -n ${SELECT_GROUP} && ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUP}":[^$'\n']+:([[:digit:]]+):.*($'\n'|$) ]]; then + # Если группа имеет буквенное имя и присутствует в списке, то берём её GUID + SELECT_GROUP=${BASH_REMATCH[2]} + elif [[ -n ${SELECT_GROUP} && ${DATA_FILE_GROUP} =~ ($'\n'|^)+[^$'\n']+:[^$'\n']+:"${SELECT_GROUP}":.*($'\n'|$) ]]; then + # Если группа имеет цифровое имя и присутствует в списке, то берём её GUID + SELECT_GROUP=${SELECT_GROUP} + elif [[ ${SELECT_OPTIONAL} =~ ("--no-user-group"|"-N") && ${DATA_FILE_GROUP} =~ ($'\n'|^)+"users":[^$'\n']+:([[:digit:]]+):.*($'\n'|$) ]]; then + # Если указан параметр не создавать группу по имени пользователя, то задаём GIT группы users + SELECT_GROUP=${BASH_REMATCH[2]} + elif [[ ${SELECT_OPTIONAL} =~ ("--system"|"-r") ]]; then + # Если указан параметр создавать системную группу + SELECT_GROUP="system" + else + if [[ -n ${SELECT_GROUP} && -n ${GROUPADD[${SELECT_GROUP}]} ]]; then + # Если группа указана и присутствует в списке групп GROUPADD[.] + exec_04_groupadd "GROUPADD[${SELECT_GROUP}]=${GROUPADD[${SELECT_GROUP}]}" + DATA_FILE_GROUP=$(cat ${FILE_GROUP}) + [[ ${DATA_FILE_GROUP} =~ ($'\n'|^)+"${SELECT_GROUP}":[^$'\n']+:([[:digit:]]+):.*($'\n'|$) ]] \ + && SELECT_GROUP=${BASH_REMATCH[2]} + elif [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} == ${SELECT_UID} ]]; then # Группа имет цифровой GID и номер GID=UID - if [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} == ${SELECT_UID} ]]; then -#echo 1:${SELECT_GROUP} - ARG_GROUPADD_GID="${SELECT_GROUP}" - ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME} + IFS=: read -r NULL SELECT_GROUP NULL NULL NULL NULL <<< $(group_add --verbose "${SELECT_USERNAME}:${SELECT_GROUP}:+:+:+") elif [[ ${SELECT_GROUP} =~ ^[[:digit:]]+$ && ${SELECT_GROUP} != ${SELECT_UID} ]]; then -#echo 2:${SELECT_GROUP} # Группа имет цифровой GID и номер GID!=UID - ARG_GROUPADD_GID="${SELECT_GROUP}" - ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME} + IFS=: read -r NULL SELECT_GROUP NULL NULL NULL NULL <<< $(group_add --verbose "${SELECT_USERNAME}:${SELECT_GROUP}:+:+:+") elif [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]]; then -#echo 3:${SELECT_GROUP} # Группа имет буквенный GID - ARG_GROUPADD_GROUPNAME=${SELECT_USERNAME} + IFS=: read -r NULL SELECT_GROUP NULL NULL NULL NULL <<< $(group_add --verbose "${SELECT_GROUP}:+:+:+:+") else -#echo 4:${SELECT_GROUP} - # Если группа не имеет цифры и буквы + # Если группа не имеет цифры или не имеет букв или не по шаблону разрешённых SELECT_GROUP= fi - if [[ -n ${ARG_GROUPADD_GROUPNAME} ]]; then - [[ ${ARG_GROUPADD_GROUPNAME} =~ ${NAME_REGEX} ]] || ARG_GROUPADD_GROUPNAME="_${ARG_GROUPADD_GROUPNAME}" -#echo "exec_05_groupadd GROUPADD[${ARG_GROUPADD_GROUPNAME}]=x:${ARG_GROUPADD_GID}" - exec_05_groupadd "GROUPADD[${ARG_GROUPADD_GROUPNAME}]=x:${ARG_GROUPADD_GID}" - fi fi - if [[ ${IS_USERNAME_PASSWD} == "" ]]; then - # Создаём пользователя - if [[ -x ${ROOTFS}/usr/bin/useradd ]]; then - [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="--comment '${SELECT_GECOS}'" || ARG_SELECT_GECOS= - [[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="--gid ${SELECT_GROUP}" || ARG_SELECT_GROUP= - [[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD= - ARG_SELECT_OPTIONAL="${SELECT_OPTIONAL}" - [[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_UID} ]] || { ARG_SELECT_OPTIONAL=${ARG_SELECT_OPTIONAL//-o/}; ARG_SELECT_OPTIONAL=${ARG_SELECT_OPTIONAL//--non-unique/}; } - [[ ${SELECT_OPTIONAL} =~ ("-M"|"--no-create-home") ]] || { [[ -d "${ROOTFS}${HOME_DIR_SELECT_USERNAME}" ]] || ARG_SELECT_OPTIONAL+=" --create-home"; } - [[ ${SELECT_OPTIONAL} =~ ("-N"|"--no-user-group") ]] || { [[ -z ${SELECT_GROUP} ]] && ARG_SELECT_OPTIONAL+=" --user-group"; } - eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$? - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME}' failed, try attempt 2"; \ - eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 2 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${SELECT_USERNAME}' failed, try attempt 3"; \ - eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 3 to use 'useradd ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${SELECT_USERNAME}' failed, try attempt 4"; \ - eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_UID} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 4 to use 'useradd ${ARG_SELECT_UID} ${SELECT_USERNAME}' failed, try attempt 5"; \ - eval ${CMD_CHROOT} /usr/bin/useradd ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 5 to use 'useradd ${SELECT_USERNAME}' failed, try attempt 6"; \ - eval ${CMD_CHROOT} /usr/bin/useradd ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { >&2 echo "ERROR: Attempt 6 to use 'useradd ${SELECT_USERNAME}' failed, exit"; return 1; } - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - # busybox adduser - [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="-g '${SELECT_GECOS}'" || ARG_SELECT_GECOS= - [[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="-G ${SELECT_GROUP}" || ARG_SELECT_GROUP="-G ${SELECT_USERNAME}" - [[ ${SELECT_OPTIONAL} =~ ("-M"|"--no-create-home") ]] && ARG_SELECT_OPTIONAL+=" -H" - eval ${CMD_CHROOT} /usr/bin/busybox adduser -D ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME} #>/dev/null 2>&1 - # Задаём пароль пользователю - set_passwd "${SELECT_USERNAME}" "${SELECT_PASSWORD}" - fi - else - # Изменяем пользователя - if [[ -x ${ROOTFS}/usr/bin/usermod ]]; then - [[ -n ${SELECT_GECOS} ]] && ARG_SELECT_GECOS="--comment '${SELECT_GECOS}'" || ARG_SELECT_GECOS= - [[ -n ${SELECT_GROUP} ]] && ARG_SELECT_GROUP="--gid ${SELECT_GROUP}" || ARG_SELECT_GROUP= - [[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD= - ARG_SELECT_OPTIONAL= - [[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_UID} ]] && ARG_SELECT_OPTIONAL+=" --non-unique" - [[ ${SELECT_OPTIONAL} =~ ("--shell "|"-s ")([^' ']*)(' '|$) ]] && ARG_SELECT_OPTIONAL+=" --shell ${BASH_REMATCH[2]}" - [[ ${SELECT_OPTIONAL} =~ ("--home-dir "|"-d ")([^' ']*)(' '|$) ]] && ARG_SELECT_OPTIONAL+=" --home ${BASH_REMATCH[2]} --move-home" - eval ${CMD_CHROOT} /usr/bin/usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$? - [[ ${STATUS} -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_OPTIONAL} ${SELECT_USERNAME}' failed, try attempt 2"; \ - eval ${CMD_CHROOT} /usr/bin/usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}; STATUS=$?; } - [[ ${STATUS} -eq 0 ]] || { >&2 echo "ERROR: Attempt 2 to use 'usermod ${ARG_SELECT_UID} ${ARG_SELECT_GROUP} ${ARG_SELECT_GECOS} ${ARG_SELECT_PASSWORD} ${SELECT_USERNAME}' failed, exit"; return 1; } - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - true - fi - fi - # Создаём дополнитеьные группы -#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && echo "exec_01_add_groups ${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}" - [[ ${SELECT_EXTRAGROUPS_TO_EXEC_01} != "" ]] && exec_01_add_groups "${SELECT_EXTRAGROUPS_TO_EXEC_01%*,}" -#[[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && echo "eval ${SELECT_EXTRAGROUPS_TO_EXEC_05}" - [[ ${SELECT_EXTRAGROUPS_TO_EXEC_05} != "" ]] && eval "${SELECT_EXTRAGROUPS_TO_EXEC_05}" - # Добавляем пользователя в основную группу - if [[ -x ${ROOTFS}/usr/bin/usermod ]]; then - # Добавляем пользователя в дополнительные группы - ${CMD_CHROOT} /usr/bin/usermod -a -G ${SELECT_EXTRAGROUPS%*,} ${SELECT_USERNAME} #>/dev/null 2>&1 - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - true - fi - # Задаём параметры пароля пользователю /etc/shadow из USERSHADOW[user]. Только если запущено отдельно с параметром - [[ -n ${PARAM} && -n ${USERSHADOW[${SELECT_USERNAME}]} ]] && exec_04_usershadow "USERSHADOW[${SELECT_USERNAME}]=${USERSHADOW[${SELECT_USERNAME}]}" - # Проверим права на домашний каталог пользователя совпадают с указанным польователем, если нет, то переназначим - if [[ -d ${ROOTFS}${HOME_DIR_SELECT_USERNAME} ]]; then - GET_UID_GID_HOME=$(${CMD_CHROOT} /usr/bin/stat -c "%U:%G" ${HOME_DIR_SELECT_USERNAME}) + # ----------- + [[ ${SELECT_OPTIONAL,,} == "x" ]] && SELECT_OPTIONAL= + [[ ${SELECT_OPTIONAL} =~ ("--home-dir "|"-d ")([^' ']*)(' '|$) ]] && SELECT_HOME="${BASH_REMATCH[2]}" || SELECT_HOME="${DEFAULT_HOME_USER}/${SELECT_USERNAME}" + [[ ${SELECT_OPTIONAL} =~ ("--shell "|"-s ")([^' ']*)(' '|$) ]] && SELECT_SHELL="${BASH_REMATCH[2]}" || SELECT_SHELL="+" + [[ ${SELECT_OPTIONAL} =~ ("--no-create-home"|"-M") ]] && SELECT_MKHOME= || SELECT_MKHOME="yes" + # ----------- + [[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD="${DEFAULTPASSWD}" + [[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'!!'|'*') ]] && SELECT_PASSWORD="$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD})" + # ----------- + # Создаём/Изменяем пользователя + user_add "${SELECT_USERNAME}:${SELECT_GECOS}:${SELECT_UID}:${SELECT_GROUP}:${SELECT_PASSWORD}:${SELECT_HOME}:${SELECT_SHELL}:+:+:+:+:+:+" + # ----------- + # Проверим права на домашнем каталоге пользователя, если не совпадают с указанным польователем, то переназначим + if [[ -d ${ROOTFS}${SELECT_HOME} ]]; then + GET_UID_GID_HOME=$(${CMD_CHROOT} /usr/bin/stat -c "%U:%G" ${SELECT_HOME}) GET_UID_GID_SELECT="$(${CMD_CHROOT} /usr/bin/id -u ${SELECT_USERNAME} 2>/dev/null):$(${CMD_CHROOT} /usr/bin/id -g ${SELECT_GROUP:-${SELECT_USERNAME}} 2>/dev/null)" if [[ ${GET_UID_GID_HOME} != ${GET_UID_GID_SELECT} ]]; then eval ${CMD_CHROOT} /usr/bin/chown -f -h "${SELECT_USERNAME}:" \ - $(${CMD_CHROOT} find ${HOME_DIR_SELECT_USERNAME} -maxdepth 1 -printf '"%p"\n') \ - $(cat ${ROOTFS}/etc/xdg/user-dirs.defaults 2>/dev/null | grep -v "^\s*#" | sed -E "s|.*=(.*)|${HOME_DIR_SELECT_USERNAME}/\1|") \ - $(cat ${ROOTFS}${HOME_DIR_SELECT_USERNAME}/.config/user-dirs.dirs 2>/dev/null | grep -v "^\s*#"| sed -E "s|.*HOME/(.*)|${HOME_DIR_SELECT_USERNAME}/\"\1|") + $(${CMD_CHROOT} find ${SELECT_HOME} -maxdepth 1 -printf '"%p"\n') \ + $(cat ${ROOTFS}/etc/xdg/user-dirs.defaults 2>/dev/null | grep -v "^\s*#" | sed -E "s|.*=(.*)|${SELECT_HOME}/\1|") \ + $(cat ${ROOTFS}${SELECT_HOME}/.config/user-dirs.dirs 2>/dev/null | grep -v "^\s*#"| sed -E "s|.*HOME/(.*)|${SELECT_HOME}/\"\1|") ARG_RECURSIVE="-hRP" eval ${CMD_CHROOT} /usr/bin/chown -f ${ARG_RECURSIVE} "${SELECT_USERNAME}:" \ - $(${CMD_CHROOT} find ${HOME_DIR_SELECT_USERNAME} -maxdepth 1 -name ".*" -printf '"%p"\n') + $(${CMD_CHROOT} find ${SELECT_HOME} -maxdepth 1 -name ".*" -printf '"%p"\n') fi fi + # ----------- + # Вызов как исполнителя после ubconfig + if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then +# # Добавим пользователя в дополнительные группы +# exec_08_user_members "USERADD[${SELECT_USERNAME}]=${USERADD[${SELECT_USERNAME}]}" +# # Задаём параметры пароля пользователю /etc/shadow из USERSHADOW[user] +# [[ -n ${USERSHADOW[${SELECT_USERNAME}]} ]] && exec_07_usershadow "USERSHADOW[${SELECT_USERNAME}]=${USERSHADOW[${SELECT_USERNAME}]}" + # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить хеш пароля параметра USERADD[.*] в /etc/ublinux/users + if [[ -f ${FILE_ROOT_USERS} ]]; then + sed "/USERADD\[${SELECT_USERNAME}\]=/d" -i "${FILE_ROOT_USERS}" + echo "USERADD[${SELECT_USERNAME}]='${USERADD[${SELECT_USERNAME}]}'" >> ${FILE_ROOT_USERS} + fi + [[ -f "${SYSCONF}/users" ]] && sed -E "s/(USERADD\[${SELECT_USERNAME}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users" + fi else - echo "INFO: The user '${SELECT_USERNAME}' exists in the system, the settings are not applied. To force the settings, enable the '[users] USERADD_SYNC[${SELECT_USERNAME}]=boot' option" + [[ -n ${ROOTFS} ]] || echo "INFO: The user '${SELECT_USERNAME}' exists in the system, the settings are not applied. To force the settings, enable the '[users] USERADD_SYNC[${SELECT_USERNAME}]=boot' option" fi # Создаём домашний каталог принудительно и копируем /etc/skel - if [[ ${UPDATEHOME,,} == @(yes|y|enable) \ - || ${UPDATEHOME[${SELECT_USERNAME}],,} == @(yes|y|enable) ]]; then + [[ ! -d ${ROOTFS}${DEFAULT_HOME_USER}/"${SELECT_USERNAME}" && SELECT_MKHOME == "yes" ]] && UPDATEHOME[${SELECT_USERNAME}]=yes + if [[ ${UPDATEHOME,,} == @(yes|y|enable) || ${UPDATEHOME[${SELECT_USERNAME}],,} == @(yes|y|enable) ]]; then create_home "${SELECT_USERNAME}" "${SELECT_GROUP}" force fi + } - # Обработать всех пользователей у которых указан UID + # Обработать всех пользователей у которых указан UID в первую очередь local LIST_USERADD_UID= LIST_USERADD_NOUID= while IFS= read -ru3 SELECT_USERNAME; do + local SELECT_GECOS= SELECT_UID= SELECT_GROUP= SELECT_EXTRAGROUPS= SELECT_OPTIONAL= SELECT_PASSWORD= NULL= IFS=: read -r SELECT_GECOS SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS SELECT_OPTIONAL SELECT_PASSWORD NULL <<< "${USERADD[${SELECT_USERNAME}]}" if [[ ${SELECT_UID} =~ ^[0-9]+$ ]] ; then LIST_USERADD_UID+="useradd_local ${SELECT_USERNAME}; " @@ -535,28 +575,27 @@ exec_03_useradd(){ done 3< <(printf "%s\n" "${!USERADD[@]}") eval "${LIST_USERADD_UID}" eval "${LIST_USERADD_NOUID}" - elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]] && [[ ${#USERADD[@]} -ne 0 ]]; then if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then - # Удалим пользователей только тех кто содержиться в файле учетных данных ${FILE_ROOT_USERS} - SELECT_USERNAME=${BASH_REMATCH[1]} + # Удалим пользователей + local SELECT_USERNAME=${BASH_REMATCH[1]} delete_select_username(){ local SELECT_USERNAME=$1 - if [[ -n ${SELECT_USERNAME} ]] && ${CMD_CHROOT} /usr/bin/getent passwd ${SELECT_USERNAME} &>/dev/null; then - ${CMD_CHROOT} /usr/bin/userdel --force ${SELECT_USERNAME} - fi - [[ -f ${FILE_ROOT_USERS} ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null - ${CMD_CHROOT} /usr/bin/ubconfig --target system --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]" + user_del "${SELECT_USERNAME}" + exec_07_usershadow remove "USERSHADOW[${SELECT_USERNAME}]" + #${CMD_CHROOT} /usr/bin/ubconfig --target system --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]" + [[ -f ${FILE_ROOT_USERS} ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${FILE_ROOT_USERS}" + [[ -f "${SYSCONF}/users" ]] && sed "/USERADD\[${SELECT_USERNAME}\]/d" -i "${SYSCONF}/users" } if [[ ${SELECT_USERNAME} == @("*"|"**"|"/"|"//") ]]; then - [[ -f ${FILE_ROOT_USERS} ]] && while IFS= read -ru3 LINE_USERADD; do - [[ ${LINE_USERADD} =~ ^.*'['(.*)']' ]] && delete_select_username ${BASH_REMATCH[1]} - done 3< <(grep -E "USERADD\[.*\]" ${FILE_ROOT_USERS} 2>/dev/null) + [[ -f ${SYSCONF}/users ]] && while IFS= read -ru3 LINE_USERADD; do + [[ ${LINE_USERADD} =~ ^.*'['(.*)']' ]] && delete_select_username "${BASH_REMATCH[1]}" + done 3< <(printf "%s\n" "${!USERADD[@]}") else - delete_select_username ${SELECT_USERNAME} + delete_select_username "${SELECT_USERNAME}" fi fi fi -# echo -e "\nEND\n" } # Параметры пользователя системы /etc/shadow. Если пользователь существует, то без изменений @@ -577,227 +616,134 @@ exec_03_useradd(){ ## # Конвертировать кол-во дней от эпохи в понятную дату: date --date=@$(( DDDDD*(60*60*24) )); date --date=@EPOCH ## USERSHADOW[superadmin]=2023-01-01:0:99999:7::2025-01-01 ## USERSHADOW[superadmin]=18009:0:120:7:14: -exec_04_usershadow(){ -#echo "exec_04_usershadow" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" - local SELECT_USERNAME SELECT_LASTCHANGED SELECT_MINDAY SELECT_MAXDAY SELECT_WARN SELECT_INACTIVE SELECT_EXPIRE NULL - local ARG_SELECT_LASTCHANGED ARG_SELECT_MINDAY ARG_SELECT_MAXDAY ARG_SELECT_WARN ARG_SELECT_INACTIVE ARG_SELECT_EXPIRE +exec_07_usershadow(){ +#echo "exec_07_usershadow" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" + [[ $(declare -p USERSHADOW 2>/dev/null) =~ ^"declare -A" ]] || declare -gA USERSHADOW + local SELECT_USERNAME= SELECT_LASTCHANGED= SELECT_MINDAY= SELECT_MAXDAY= SELECT_WARN= SELECT_INACTIVE= SELECT_EXPIRE= NULL= local PARAM="$@" + local DATA_FILE_SHADOW=$(cat ${FILE_SHADOW}) if [[ -n ${PARAM} ]]; then local USERSHADOW declare -A USERSHADOW [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi - if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERSHADOW[@]} != 0 ]]; then + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERSHADOW[@]} -ne 0 ]]; then while IFS= read -ru3 SELECT_USERNAME; do + [[ -n ${SELECT_USERNAME} ]] || continue # Если пользователь не существует, то пропустить - if [[ -n ${SELECT_USERNAME} ]]; then - if ! ${CMD_CHROOT} /usr/bin/getent shadow ${SELECT_USERNAME} &>/dev/null; then - ${CMD_CHROOT} /usr/bin/ubconfig --quiet --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]" - continue - fi - else + if [[ ! ${DATA_FILE_SHADOW} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]]; then + #${CMD_CHROOT} /usr/bin/ubconfig --quiet --noexecute remove [users] "USERSHADOW[${SELECT_USERNAME}]" continue fi IFS=: read -r SELECT_LASTCHANGED SELECT_MINDAY SELECT_MAXDAY SELECT_WARN SELECT_INACTIVE SELECT_EXPIRE NULL <<< "${USERSHADOW[${SELECT_USERNAME}]}" - # Получить из секунд от эпохи текущую дату: date -d @1705841503 - # Получить от эпохи количество дней: $(( $(date +%s)/(60*60*24) )). В дне 86400 секунд (60*60*24) - #[[ ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(date --date=${SELECT_LASTCHANGED} +"%s") - #[[ -z ${SELECT_LASTCHANGED_EPOH} && -x /bin/busybox && ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(busybox date --date="${SELECT_LASTCHANGED//./}0000" +"%s") - #[[ -z ${SELECT_LASTCHANGED_EPOH} && -x ${ROOTFS}/usr/bin//date && ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED_EPOH=$(${ROOTFS}/usr/bin/date --date="${SELECT_LASTCHANGED//./} 0000" +"%s") - #[[ -n ${SELECT_LASTCHANGED_EPOH} ]] && SELECT_LASTCHANGED=$(( ${SELECT_LASTCHANGED_EPOH}/(60*60*24) )) - #[[ ${SELECT_LASTCHANGED,,} == @(""|"x") || ${SELECT_LASTCHANGED} =~ ^[^0-9]*$ || ! ${SELECT_LASTCHANGED} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_LASTCHANGED= [[ ${SELECT_LASTCHANGED} =~ (^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || SELECT_LASTCHANGED= [[ ${SELECT_MINDAY} =~ ^[0-9]*$ ]] || SELECT_MINDAY= [[ ${SELECT_MAXDAY} =~ ^[0-9]*$ ]] || SELECT_MAXDAY= [[ ${SELECT_WARN} =~ ^[0-9]*$ ]] || SELECT_WARN= [[ ${SELECT_INACTIVE} =~ (-1|^[0-9]*$) ]] || SELECT_INACTIVE= - #[[ ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(date --date=${SELECT_EXPIRE} +"%s") - #[[ -z ${SELECT_EXPIRE_EPOH} && -x /bin/busybox && ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(busybox date --date="${SELECT_EXPIRE//./}0000" +"%s") - #[[ -z ${SELECT_EXPIRE_EPOH} && -x ${ROOTFS}/usr/bin/date && ${SELECT_EXPIRE} =~ ^[0-9]{4,4}'.'[0-9]{1,2}'.'[0-9]{1,2}$ ]] && SELECT_EXPIRE_EPOH=$(${ROOTFS}/usr/bin/date --date="${SELECT_EXPIRE//./} 0000" +"%s") - #[[ -n ${SELECT_EXPIRE_EPOH} ]] && SELECT_EXPIRE=$(( ${SELECT_EXPIRE_EPOH}/(60*60*24) )) - [[ ${SELECT_EXPIRE} =~ (-1|^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || SELECT_EXPIRE= - if [[ -z ${SELECT_LASTCHANGED} && -z ${SELECT_MINDAY} && -z ${SELECT_MAXDAY} && -z ${SELECT_WARN} && -z ${SELECT_INACTIVE} && -z ${SELECT_EXPIRE} ]]; then - SELECT_LASTCHANGED= - SELECT_MINDAY="0" - SELECT_MAXDAY="99999" - SELECT_WARN="7" - SELECT_INACTIVE="-1" - SELECT_EXPIRE="-1" - fi - [[ -n ${SELECT_LASTCHANGED} ]] && ARG_SELECT_LASTCHANGED="--lastday ${SELECT_LASTCHANGED}" || ARG_SELECT_LASTCHANGED= - [[ -n ${SELECT_MINDAY} ]] && ARG_SELECT_MINDAY="--mindays ${SELECT_MINDAY}" || ARG_SELECT_MINDAY= - [[ -n ${SELECT_MAXDAY} ]] && ARG_SELECT_MAXDAY="--maxdays ${SELECT_MAXDAY}" || ARG_SELECT_MAXDAY= - [[ -n ${SELECT_WARN} ]] && ARG_SELECT_WARN="--warndays ${SELECT_WARN}" || ARG_SELECT_WARN= - [[ -n ${SELECT_INACTIVE} ]] && ARG_SELECT_INACTIVE="--inactive ${SELECT_INACTIVE}" || ARG_SELECT_INACTIVE= - [[ -n ${SELECT_EXPIRE} ]] && ARG_SELECT_EXPIRE="--expiredate ${SELECT_EXPIRE}" || ARG_SELECT_EXPIRE= - # Задаём параметры пароля пользователя - if [[ -x ${ROOTFS}/usr/bin/chage ]]; then - ${CMD_CHROOT} /usr/bin/chage ${ARG_SELECT_LASTCHANGED} ${ARG_SELECT_MINDAY} ${ARG_SELECT_MAXDAY} ${ARG_SELECT_WARN} ${ARG_SELECT_INACTIVE} ${ARG_SELECT_EXPIRE} "${SELECT_USERNAME}" #>/dev/null 2>&1 - fi + [[ ${SELECT_EXPIRE} =~ (^[0-9]*$|^[0-9]{4,4}'-'[0-9]{1,2}'-'[0-9]{1,2}$) ]] || SELECT_EXPIRE= + user_add "${SELECT_USERNAME}:+:+:+:+:+:+:${SELECT_LASTCHANGED}:${SELECT_MINDAY}:${SELECT_MAXDAY}:${SELECT_WARN}:${SELECT_INACTIVE}:${SELECT_EXPIRE}" done 3< <(printf "%s\n" "${!USERSHADOW[@]}") - elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]] && [[ ${#USERSHADOW[@]} -ne 0 ]]; then if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then - SELECT_USERNAME=${BASH_REMATCH[1]} - if [[ -n ${SELECT_USERNAME} ]] && ${CMD_CHROOT} /usr/bin/getent shadow ${SELECT_USERNAME} &>/dev/null; then - if [[ -x ${ROOTFS}/usr/bin/chage ]]; then - ${CMD_CHROOT} /usr/bin/chage --mindays 0 --maxdays 99999 --warndays 7 --inactive -1 --expiredate -1 ${SELECT_USERNAME} + local SELECT_USERNAME=${BASH_REMATCH[1]} + delete_select_usershadow(){ + local SELECT_USERNAME=$1 + if [[ ${DATA_FILE_SHADOW} =~ ($'\n'|^)+"${SELECT_USERNAME}":([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*):([^$'\n']*)($'\n'|$)+ ]]; then + user_add "${SELECT_USERNAME}:+:+:+:+:+:+::::::" fi + [[ -f "${SYSCONF}/users" ]] && sed "/USERSHADOW\[${SELECT_USERNAME}\]/d" -i "${SYSCONF}/users" + } + if [[ ${SELECT_USERNAME} == @("*"|"**"|"/"|"//") ]]; then + [[ -f ${SYSCONF}/users ]] && while IFS= read -ru3 LINE_USERSHADOW; do + [[ ${LINE_USERSHADOW} =~ ^.*'['(.*)']' ]] && delete_select_usershadow "${BASH_REMATCH[1]}" + done 3< <(printf "%s\n" "${!USERSHADOW[@]}") + else + delete_select_usershadow "${SELECT_USERNAME}" fi + fi fi } -# Функция добавление/удаление групп в систему. Если группа существует, то изменить под параметры -# $1 Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove -# $2 Для команды set=|set+=|set++= параметр со значением, пример: GROUPADD[g_department_1]=ob.ivanov,rv.smirnov -# Для команды set-=|set--=|remove параметр только с именем, пример: GROUPADD[g_department_1] -# null Если отсутствует $@, то применяем из системной конфигурации GROUPADD[*] - -## GROUPADD[group_name]='group_users:gid:optional:password|x' -## group_name # Имя группы -## group_users # Пользователи группы, перечисление через запятую. Может быть пусто. -## gid # GID группы, если необходимо автоматически рассчитывать, то оставить пустым или 'x' -## optional # Дополнительные параметры, например: '--system --non-unique' -## -o, --non-unique # Разрешить создание групп с повторяющимися (не уникальными) GID -## -r, --system # Cоздавать системную группу -## administrators # Администраторы группы которые могут менять пароль группы и добавлять членов -## password|x # Хеш пароля группа, если выбрано 'x' или пусто, то группа без пароля -## GROUPADD[g_department_1]=ob.ivanov,rv.smirnov -## GROUPADD[g_department_2]='ob.ivanov,rv.smirnov:1001:x:superadmin:$6$E7stRhRS8fCKk7UU$Qoqw62AUaUa5uLIc2KC7WV3MUThhrR8kjXtCODmnKCzKe2zHu1/wmsiWBHZEIk/IQnk/aELQYbUK93OUtrwg60' -exec_05_groupadd(){ -#echo "exec_05_groupadd" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" +exec_08_user_members(){ +#echo "exec_08_user_members" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" + [[ $(declare -p USERADD 2>/dev/null) =~ ^"declare -A" ]] || declare -gA USERADD + [[ $(declare -p GROUPADD 2>/dev/null) =~ ^"declare -A" ]] || declare -gA GROUPADD local PARAM="$@" - local SELECT_GROUP SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL - local ARG_SELECT_USERS ARG_SELECT_GID SELECT_OPTIONAL ARG_SELECT_PASSWORD ARG_NON_UNIQUE - local DATA_FILE_PASSWD REAL_SELECT_USERS REAL_SELECT_ADMINISTRATORS - DATA_SYSUSERS=$(cat ${ROOTFS}/usr/lib/sysusers.d/*.conf ${ROOTFS}/usr/share/ublinux-sysusers/*.sysusers) if [[ -n ${PARAM} ]]; then + local USERADD= + declare -A USERADD local GROUPADD= declare -A GROUPADD [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi - if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#GROUPADD[@]} != 0 ]]; then + local SELECT_USERNAME= SELECT_UID= SELECT_GROUP= SELECT_EXTRAGROUP= SELECT_PASSWORD= NULL= + # Если в GRUB указан параметр useradd, то создать пользователя + [[ -n ${ROOTFS} ]] && while IFS=':' read -u3 SELECT_USERNAME SELECT_UID SELECT_GROUP SELECT_EXTRAGROUP SELECT_PASSWORD NULL; do + [[ ${SELECT_USERNAME} != "" ]] && USERADD[${SELECT_USERNAME}]=":${SELECT_UID}:${SELECT_GROUP}:${SELECT_EXTRAGROUP}:x:${SELECT_PASSWORD}" + done 3< <(tr ';' '\n' <<< $(cmdline_value useradd)) + ## USERADD[@] + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#USERADD[@]} -ne 0 ]]; then + [[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] && ADDADM=yes + local FILE_SHADOW="${ROOTFS}/etc/shadow" + useradd_local(){ + local SELECT_USERNAME=$1 + local SELECT_UID= SELECT_GROUP= SELECT_EXTRAGROUPS= NULL= + IFS=: read -r NULL SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS NULL NULL NULL <<< "${USERADD[${SELECT_USERNAME}]}" + SELECT_EXTRAGROUPS+=",${USERGROUPS},${DEFAULTGROUP}" + [[ ${SELECT_UID} == ${ADMUID} && ${ADDADM} == "yes" ]] && SELECT_EXTRAGROUPS+=",${ADMGROUPS}" + SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//;/,}"; SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS//,,/,}" + [[ ${SELECT_EXTRAGROUPS} =~ ','$ ]] && SELECT_EXTRAGROUPS=${SELECT_EXTRAGROUPS%*,} + [[ ${SELECT_EXTRAGROUPS:0:1} == "," ]] && SELECT_EXTRAGROUPS="${SELECT_EXTRAGROUPS:1}" + # Создавать группы из параметра SELECT_EXTRAGROUPS + exec_03_add_groups "${SELECT_EXTRAGROUPS}" + # Добавляем пользователя в дополнительные группы + [[ -n ${SELECT_EXTRAGROUPS} ]] && user_add_group "${SELECT_USERNAME}" "${SELECT_EXTRAGROUPS}" + } + # Удалить пользователей из всех групп + user_remove_group "$(printf "%s," "${!USERADD[@]}")" "%all" + # Добавить пользователей в группы + while IFS= read -ru3 SELECT_USERNAME; do + useradd_local ${SELECT_USERNAME} + done 3< <(printf "%s\n" "${!USERADD[@]}") + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]] && [[ ${#USERADD[@]} -ne 0 ]]; then + if [[ ${PARAM%%=*} =~ ^'USERADD['(.*)']' ]]; then + local SELECT_USERNAME=${BASH_REMATCH[1]} + local SELECT_UID= SELECT_GROUP= SELECT_EXTRAGROUPS= NULL= + IFS=: read -r NULL SELECT_UID SELECT_GROUP SELECT_EXTRAGROUPS NULL NULL NULL <<< "${USERADD[${SELECT_USERNAME}]}" + [[ ${SELECT_EXTRAGROUPS,,} == @(""|"x") ]] && return 0 + # Удалить пользователя из групп + user_remove_group "${SELECT_USERNAME}" "${SELECT_EXTRAGROUPS}" + fi + fi + ## GROUPADD[@] + if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#GROUPADD[@]} -ne 0 ]]; then groupadd_local(){ local SELECT_GROUP=$1 - # Добавить параметр в ${FILE_ROOT_USERS}=.users_credential и удалить параметр GROUPADD[.*] из '/etc/ublinux/users - if [[ -n ${PARAM} && -z ${ROOTFS} ]]; then - if [[ -f ${FILE_ROOT_USERS} ]]; then - sed "/GROUPADD\[${SELECT_GROUP}\]=/d" -i "${FILE_ROOT_USERS}" - echo "GROUPADD[${SELECT_GROUP}]='${GROUPADD[${SELECT_GROUP}]}'" >> ${FILE_ROOT_USERS} - fi - [[ -f "${SYSCONF}/users" ]] && sed -E "s/(GROUPADD\[${SELECT_GROUP}\]=[\'\"]?)([^:]*:[^:]*:[^:]*:[^:]*:)[^\'\"]*([\'\"]?)/\1\2\3/g" -i "${SYSCONF}/users" - fi - IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}" - [[ ${SELECT_USERS} == "x" ]] && SELECT_USERS= - [[ ${SELECT_GID,,} == "x" || ${SELECT_GID} =~ ^[^0-9]*$ ]] && SELECT_GID= -#echo "==> exec_05_groupadd: ${SELECT_GROUP}:${SELECT_USERS}:${SELECT_GID}:${SELECT_OPTIONAL}:${SELECT_ADMINISTRATORS}:${SELECT_PASSWORD}" - [[ ${SELECT_OPTIONAL} == "x" ]] && SELECT_OPTIONAL= - [[ ${SELECT_PASSWORD} == @(""|"x") ]] && SELECT_PASSWORD= - [[ ${SELECT_PASSWORD} != @(""|'!*'|'!'|'*') ]] && SELECT_PASSWORD=$(return_hash_password hash ${HASHPASSWD} ${SELECT_PASSWORD}) - # Поиск по имени в шаблонах пользователей/групп systemd - [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+"${SELECT_GROUP}"[[:blank:]]+([[:digit:]]+)[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_ID=${BASH_REMATCH[2]} || FINDGROUP_ID= - # Поиск по GID в шаблонах пользователей/групп systemd - [[ -z ${FINDGROUP_ID} ]] \ - && [[ ${DATA_SYSUSERS} =~ ($'\n'|^)+'g'[[:blank:]]+([^$'\n']+)[[:blank:]]+"${SELECT_GROUP}"[^$'\n']*($'\n'|$)+ ]] && FINDGROUP_NAME=${BASH_REMATCH[2]} || FINDGROUP_NAME= - [[ -n ${FINDGROUP_ID} ]] && SELECT_GID="${FINDGROUP_ID}" - [[ -n ${FINDGROUP_NAME} ]] && SELECT_GID="${FINDGROUP_NAME}" - DATA_FILE_GROUP=$(cat ${FILE_GROUP}) - # Добавляем аргументы к опциям, при условии что такого GID не существует - [[ -n ${SELECT_GID} ]] && [[ ! ${DATA_FILE_GROUP} =~ :${SELECT_GID}: ]] && ARG_SELECT_GID="--gid ${SELECT_GID}" || ARG_SELECT_GID= - #[[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="--users ${SELECT_USERS}" || ARG_SELECT_USERS= - [[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD= - [[ ${SELECT_OPTIONAL} =~ ("-o"|"--non-unique") ]] && [[ -n ${ARG_SELECT_GID} ]] || { SELECT_OPTIONAL=${SELECT_OPTIONAL//-o/}; SELECT_OPTIONAL=${SELECT_OPTIONAL//--non-unique/}; } - # Создаём группу, если создана то изменяем под установленные параметры - if [[ ! ${DATA_FILE_GROUP} =~ ($'\n'|^)+${SELECT_GROUP}: ]]; then - if [[ -x ${ROOTFS}/usr/bin/groupadd ]]; then - #${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_USERS} ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} -#echo "eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}" - eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} - [[ $? -eq 0 ]] || { echo "WARNING: Attempt 1 to use 'groupadd ${ARG_SELECT_GID} ${SELECT_OPTIONAL} ${SELECT_GROUP}' failed, try attempt 2"; \ - eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_GID} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; } - [[ $? -eq 0 ]] || { echo "WARNING: Attempt 2 to use 'groupadd ${ARG_SELECT_GID} ${SELECT_GROUP}' failed, try attempt 3"; \ - eval ${CMD_CHROOT} /usr/bin/groupadd --force ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} ; } - [[ $? -eq 0 ]] || { echo "WARNING: Attempt 3 to use 'groupadd ${SELECT_GROUP}' failed, try attempt 4"; \ - ${CMD_CHROOT} /usr/bin/groupadd --force ${SELECT_GROUP} ; } - [[ $? -eq 0 ]] || { >&2 echo "ERROR: Attempt 4 to use 'groupadd ${SELECT_GROUP}' failed, exit"; return 1; } - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - true - # Задаём пароль группе - # set_gpasswd "${SELECT_GROUP}" "${SELECT_PASSWORD}" - fi - elif [[ -n ${ARG_SELECT_GID} ]]; then - if [[ -x ${ROOTFS}/usr/bin/groupmod ]]; then - # т.к. groupmod принимет не все возможные аргументы совместимы с groupadd, то фильтруем - [[ ${SELECT_OPTIONAL} =~ ("--non-unique"|"-o") ]] && [[ -n ${ARG_SELECT_GID} ]] && ARG_NON_UNIQUE="--non-unique" || ARG_NON_UNIQUE= - [[ -n ${SELECT_PASSWORD} ]] && ARG_SELECT_PASSWORD="--password '${SELECT_PASSWORD}'" || ARG_SELECT_PASSWORD= - #eval ${CMD_CHROOT} /usr/bin/groupmod --append ${ARG_SELECT_USERS} ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} -#echo "eval ${CMD_CHROOT} /usr/bin/groupmod ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP}" - eval ${CMD_CHROOT} /usr/bin/groupmod ${ARG_SELECT_GID} ${ARG_NON_UNIQUE} ${ARG_SELECT_PASSWORD} ${SELECT_GROUP} - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - true - # Задаём пароль группе - # set_gpasswd "${SELECT_GROUP}" "${SELECT_PASSWORD}" - fi - fi - DATA_FILE_PASSWD=$(cat ${FILE_PASSWD}) - local REAL_SELECT_USERS= REAL_SELECT_ADMINISTRATORS= - # Если пользователь не существуют то убрать из списка SELECT_USERS - while IFS= read -r ITEM_SELECT_USERS; do - [[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${ITEM_SELECT_USERS}: ]] && REAL_SELECT_USERS+=",${ITEM_SELECT_USERS}" - done <<< ${SELECT_USERS//,/$'\n'} - [[ ${REAL_SELECT_USERS:0:1} == "," ]] && REAL_SELECT_USERS=${REAL_SELECT_USERS:1} - [[ ${REAL_SELECT_USERS} != "" ]] && SELECT_USERS=${REAL_SELECT_USERS} || SELECT_USERS= - # Если пользователь не существуют то убрать из списка REAL_SELECT_ADMINISTRATORS - while IFS= read -r ITEM_SELECT_ADMINISTRATORS; do - [[ ${DATA_FILE_PASSWD} =~ ($'\n'|^)+${ITEM_SELECT_ADMINISTRATORS}: ]] && REAL_SELECT_ADMINISTRATORS+=",${ITEM_SELECT_ADMINISTRATORS}" - done <<< ${SELECT_ADMINISTRATORS//,/$'\n'} - [[ ${REAL_SELECT_ADMINISTRATORS:0:1} == "," ]] && REAL_SELECT_ADMINISTRATORS=${REAL_SELECT_ADMINISTRATORS:1} - [[ ${REAL_SELECT_ADMINISTRATORS} != "" ]] && SELECT_ADMINISTRATORS=${REAL_SELECT_ADMINISTRATORS} || SELECT_ADMINISTRATORS= - # Добавляем пользователей в группу, т.к. groupadd не добавил пользователей в /etc/gshadow - if [[ -n ${SELECT_USERS} || -n ${SELECT_ADMINISTRATORS} ]]; then - if [[ -x ${ROOTFS}/usr/bin/gpasswd ]]; then - [[ -n ${SELECT_USERS} ]] && ARG_SELECT_USERS="-M ${SELECT_USERS}" || ARG_SELECT_USERS= - [[ -n ${SELECT_ADMINISTRATORS} ]] && ARG_SELECT_ADMINISTRATORS="-A ${SELECT_ADMINISTRATORS}" || ARG_SELECT_ADMINISTRATORS= -#echo "${CMD_CHROOT} /usr/bin/gpasswd ${ARG_SELECT_ADMINISTRATORS} ${ARG_SELECT_USERS} ${SELECT_GROUP}" - ${CMD_CHROOT} /usr/bin/gpasswd ${ARG_SELECT_ADMINISTRATORS} ${ARG_SELECT_USERS} ${SELECT_GROUP} #>/dev/null 2>&1 - elif [[ -x ${ROOTFS}/usr/bin/busybox ]]; then - true - fi - fi + local SELECT_USERS= SELECT_GID= NULL= + IFS=: read -r SELECT_USERS SELECT_GID NULL NULL NULL NULL <<< "${GROUPADD[${SELECT_GROUP}]}" + [[ ${SELECT_USERS} == @(""|"x") ]] && return 0 + # Создавать группы из параметра SELECT_GROUP + exec_03_add_groups "${SELECT_GROUPS}" + # Добавляем пользователя в дополнительные группы + user_add_group "${SELECT_USERS}" "${SELECT_GROUP}" } - local LIST_GROUPADD_GID= LIST_GROUPADD_NOGID= while IFS= read -ru3 SELECT_GROUP; do - [[ ${SELECT_GROUP} =~ ${NAME_REGEX} ]] || { >&2 echo "ERROR: '${SELECT_GROUP}' cannot be a group name"; continue; } - IFS=: read -r SELECT_USERS SELECT_GID SELECT_OPTIONAL SELECT_ADMINISTRATORS SELECT_PASSWORD NULL <<< "${GROUPADD[${SELECT_GROUP}]}" - if [[ ${SELECT_GID} =~ ^[0-9]+$ ]] ; then - LIST_GROUPADD_GID+="groupadd_local ${SELECT_GROUP}; " - else - LIST_GROUPADD_NOGID+="groupadd_local ${SELECT_GROUP}; " - fi + groupadd_local "${SELECT_GROUP}" done 3< <(printf "%s\n" "${!GROUPADD[@]}") - [[ -n ${LIST_GROUPADD_GID} ]] && eval "${LIST_GROUPADD_GID}" - [[ -n ${LIST_GROUPADD_NOGID} ]] && eval "${LIST_GROUPADD_NOGID}" - elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then - if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then - SELECT_GROUP=${BASH_REMATCH[1]} - delete_select_group(){ - local SELECT_GROUP=$1 - if [[ -n ${SELECT_GROUP} ]] && ${CMD_CHROOT} /usr/bin/getent group ${SELECT_GROUP} &>/dev/null; then - ${CMD_CHROOT} /usr/bin/groupdel --force ${SELECT_GROUP} - fi - [[ -f ${FILE_ROOT_USERS} ]] && sed "/GROUPADD\[${SELECT_GROUP}\]/d" -i "${FILE_ROOT_USERS}" 2>/dev/null - } - if [[ ${SELECT_GROUP} == @("*"|"**"|"/"|"//") ]]; then - [[ -f ${FILE_ROOT_USERS} ]] && while IFS= read -ru3 LINE_GROUPADD; do - [[ ${LINE_GROUPADD} =~ ^.*'['(.*)']' ]] && delete_select_group ${BASH_REMATCH[1]} - done 3< <(grep -E "GROUPADD\[.*\]" ${FILE_ROOT_USERS} 2>/dev/null) - else - delete_select_group ${SELECT_GROUP} - fi + elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]] && [[ ${#GROUPADD[@]} -ne 0 ]]; then + if [[ ${PARAM%%=*} =~ ^'GROUPADD['(.*)']' ]]; then + local SELECT_GROUP=${BASH_REMATCH[1]} + local SELECT_USERS= SELECT_GID= NULL= + IFS=: read -r SELECT_USERS SELECT_GID NULL NULL NULL NULL <<< "${GROUPADD[${SELECT_GROUP}]}" + [[ ${SELECT_USERS} == @(""|"x") ]] && return 0 + # Удалить пользователя из группы + user_remove_group "${SELECT_USERS}" "${SELECT_GROUP}" fi fi } @@ -806,17 +752,17 @@ exec_05_groupadd(){ # Если пароли по умолчанию, то firststart exec_99_firststart(){ #echo "exec_99_firststart" - [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift - [[ -n ${COMMAND} ]] || COMMAND="set=" + [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift + [[ -n ${COMMAND} ]] || local COMMAND="set=" local PARAM="$@" if [[ -n ${PARAM} ]]; then local FIRSTSTART= [[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}" fi if [[ -n ${ROOTFS} ]]; then - if [[ ${NOSECUREROOTPASSWD} == ${DEFAULTROOTPASSWD} ]] \ - && grep -q "^$(grep ".*:x:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):${NOSECUREROOTPASSWD}:" ${ROOTFS}/etc/shadow; then - [[ $(cat ${SYSCONF}/config 2>/dev/null) =~ ($'\n'|^)+'FIRSTSTART=' ]] || echo "FIRSTSTART=yes" >> ${SYSCONF}/config + if grep -q "^root:${DEFAULTROOTPASSWD}:" ${ROOTFS}/etc/shadow \ + && grep -q "^$(grep ".*:x:${ADMUID}:" ${ROOTFS}/etc/passwd | cut -d: -f1):${DEFAULTPASSWD}:" ${ROOTFS}/etc/shadow; then + grep -q "^FIRSTSTART$" ${SYSCONF}/config 2>/dev/null || echo "FIRSTSTART=yes" >> ${SYSCONF}/config fi elif [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${FIRSTSTART} ]]; then [[ $(cat ${SYSCONF}/config 2>/dev/null) =~ ($'\n'|^)+'FIRSTSTART=' ]] || echo "FIRSTSTART=yes" >> ${SYSCONF}/config @@ -834,14 +780,14 @@ exec_99_firststart(){ return 0 2>/dev/null && return 0 #rm -f "${FILE_ROOT_USERS}" if [[ -z $@ ]]; then - while read -ru3 FUNCTION; do + while read -r FUNCTION; do $"${FUNCTION##* }" - done 3< <(declare -F | grep "declare -f exec_") + done < <(declare -F | grep "declare -f exec_") else FUNCTION= while [[ $# -gt 0 ]]; do [[ -z ${1} ]] || { declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"; } - shift + shift done eval ${FUNCTION#*; } fi diff --git a/ublinux/rc.xorg/02-xrandr b/ublinux/rc.xorg/02-xrandr index 7f832f8..a764ad7 100755 --- a/ublinux/rc.xorg/02-xrandr +++ b/ublinux/rc.xorg/02-xrandr @@ -17,7 +17,8 @@ SOURCE=${SYSCONF}/desktop; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null ## Parametrs: ## cvt , gtf , reduced|r , auto , preferred , off , primary , mode:1920x1080 ## lo|LeftOf:{name} , ro|RightOf:{name} , ab|Above:{name} , be|Below:{name} , rotate:normal|left|right|invert - [[ -z "${XRANDR_MONITOR[@]}" ]] || for VIDEO_PORT in "${!XRANDR_MONITOR[@]}"; do + [[ $(declare -p XRANDR_MONITOR 2>/dev/null) =~ ^"declare -A" ]] || declare -gA XRANDR_MONITOR + [[ ${#XRANDR_MONITOR[@]} -ne 0 ]] && for VIDEO_PORT in "${!XRANDR_MONITOR[@]}"; do SOFT_MODELINE="gtf" SOFT_MODELINE_R= while read VIDEO_PORT_PARAM; do