# -*- mode: shell-script -*- make_build_script() { local users_def="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" | 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 < /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" }