fork 0k-charms
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

148 lines
4.9 KiB

# -*- mode: shell-script -*-
make_build_script() {
local users_def="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(declare -f "$FUNCNAME")" | md5_compat)"
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: STATIC cache hit"
cat "$cache_file" &&
touch "$cache_file" || return 1
return 0
fi
## remaining arguments are the group_label:gid list that should be
## avoided for creation (because already existent ?)
shift
local code fixed_groups_code groups_code \
created_groups first_group gids
if [ -z "$users_def" ]; then
return 0
fi
e "set -eux"$'\n'
code=""
fixed_groups_code=""
groups_code=""
gids=()
declare -A created_groups
for group in "$@"; do
if [[ "$group" != *":"* ]]; then
err "Invalid group specification given from script"
return 1
fi
gid=${group##*:}
gids+=("$gid")
group_label=${group%%:*}
created_groups[$group_label]="$gid"
done
while read-0 user user_def; do
code+="mkdir -p \"/home/$user\""$'\n'
##
## Group management
##
first_group=
first=1
while read-0 group; do
gid="unspecified"
if [[ "$group" == *":"* ]]; then
gid=${group##*:}
if ! [[ "$gid" =~ ^[0-9]+$ ]]; then
err "gid part (after ':') should be numerical not '$gid'."
return 1
fi
group_label=${group%%:*}
else
group_label="$group"
fi
if [ "${created_groups[$group_label]}" ]; then ## already met this group
## double-check we did not give conflicting gid information
if [[ "${created_groups[$group_label]}" != "$gid" ]]; then
err "Conflicting setup: using existing group '$group_label' for user '$user'" \
"with different GIDs specification" \
"(previous was ${created_groups[$group_label]}, current one is $gid)."
return 1
fi
else
if [[ "$gid" != unspecified ]]; then
## check not already used
if [[ " ${gids[*]} " == *" $gid "* ]]; then
err "gid $gid is alreay used and is not available."
return 1
fi
fixed_groups_code+="addgroup -g \"$gid\" \"$group_label\""$'\n'
else
groups_code+="addgroup \"$group\""$'\n'
fi
created_groups[$group_label]="$gid"
fi
echo "First: $first" >&2
echo "First: $group_label" >&2
if [ "$first" ]; then
echo "FG1: $first_group" >&2
first_group="$group_label"
first=
else
remaining_groups+=("$group_label")
fi
done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null)
##
## User create commands
##
uid=$(echo "$user_def" | shyaml get-value uid 2>/dev/null)
useradd_options=(
"-D" ## don't assign a password
"-s" "/bin/false" ## default shell
)
if [ "$uid" ]; then
useradd_options+=("-u" "$uid") ## force uid
fi
if [ "$first_group" ]; then
useradd_options+=("-G" "$first_group") ## force main group
fi
code+="adduser ${useradd_options[*]} \"$user\""$'\n'
if [ "$allow_writeable_chroot" ]; then
code+="chown $user \"/home/$user\""$'\n' ## sanitize
else
code+="chown root:root \"/home/$user\""$'\n' ## sanitize
fi
code+="chmod 755 \"/home/$user\""$'\n' ## sanitize
password=$(echo "$user_def" | shyaml get-value password 2>/dev/null) ||
password=$(gen_password 14)
code+="echo '$user:$password' | chpasswd"$'\n'
for group in "${remaining_groups[@]}"; do
code+="adduser \"$user\" \"$group\""$'\n'
done
##
## Key managements
##
while read-0 key; do
keys+="$key"$'\n'
done < <(echo "$user_def" | shyaml get-values-0 -q keys)
if [ "$keys" ]; then
code+="mkdir -p \"/home/$user/.ssh\""$'\n'
code+="cat <<EOF > /home/$user/.ssh/authorized_keys"$'\n'
code+="$keys"
code+="EOF"$'\n'
# code+="chown $user /home/$user/.ssh/authorized_keys"$'\n'
code+="chmod 644 /home/$user/.ssh/authorized_keys"$'\n'
code+="chmod 755 /home/$user/.ssh"$'\n'
fi
done < <(echo "$users_def" | shyaml key-values-0)
{
echo -n "$fixed_groups_code"
echo -n "$groups_code"
echo -n "$code"
} | tee "$cache_file"
}