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.

147 lines
4.9 KiB

  1. # -*- mode: shell-script -*-
  2. make_build_script() {
  3. local users_def="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" | md5_compat)"
  4. if [ -e "$cache_file" ]; then
  5. #debug "$FUNCNAME: STATIC cache hit"
  6. cat "$cache_file" &&
  7. touch "$cache_file" || return 1
  8. return 0
  9. fi
  10. ## remaining arguments are the group_label:gid list that should be
  11. ## avoided for creation (because already existent ?)
  12. shift
  13. local code fixed_groups_code groups_code \
  14. created_groups first_group gids
  15. if [ -z "$users_def" ]; then
  16. return 0
  17. fi
  18. e "set -eux"$'\n'
  19. code=""
  20. fixed_groups_code=""
  21. groups_code=""
  22. gids=()
  23. declare -A created_groups
  24. for group in "$@"; do
  25. if [[ "$group" != *":"* ]]; then
  26. err "Invalid group specification given from script"
  27. return 1
  28. fi
  29. gid=${group##*:}
  30. gids+=("$gid")
  31. group_label=${group%%:*}
  32. created_groups[$group_label]="$gid"
  33. done
  34. while read-0 user user_def; do
  35. code+="mkdir -p \"/home/$user\""$'\n'
  36. ##
  37. ## Group management
  38. ##
  39. first_group=
  40. first=1
  41. while read-0 group; do
  42. gid="unspecified"
  43. if [[ "$group" == *":"* ]]; then
  44. gid=${group##*:}
  45. if ! [[ "$gid" =~ ^[0-9]+$ ]]; then
  46. err "gid part (after ':') should be numerical not '$gid'."
  47. return 1
  48. fi
  49. group_label=${group%%:*}
  50. else
  51. group_label="$group"
  52. fi
  53. if [ "${created_groups[$group_label]}" ]; then ## already met this group
  54. ## double-check we did not give conflicting gid information
  55. if [[ "${created_groups[$group_label]}" != "$gid" ]]; then
  56. err "Conflicting setup: using existing group '$group_label' for user '$user'" \
  57. "with different GIDs specification" \
  58. "(previous was ${created_groups[$group_label]}, current one is $gid)."
  59. return 1
  60. fi
  61. else
  62. if [[ "$gid" != unspecified ]]; then
  63. ## check not already used
  64. if [[ " ${gids[*]} " == *" $gid "* ]]; then
  65. err "gid $gid is alreay used and is not available."
  66. return 1
  67. fi
  68. fixed_groups_code+="addgroup -g \"$gid\" \"$group_label\""$'\n'
  69. else
  70. groups_code+="addgroup \"$group\""$'\n'
  71. fi
  72. created_groups[$group_label]="$gid"
  73. fi
  74. echo "First: $first" >&2
  75. echo "First: $group_label" >&2
  76. if [ "$first" ]; then
  77. echo "FG1: $first_group" >&2
  78. first_group="$group_label"
  79. first=
  80. else
  81. remaining_groups+=("$group_label")
  82. fi
  83. done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null)
  84. ##
  85. ## User create commands
  86. ##
  87. uid=$(echo "$user_def" | shyaml get-value uid 2>/dev/null)
  88. useradd_options=(
  89. "-D" ## don't assign a password
  90. "-s" "/bin/false" ## default shell
  91. )
  92. if [ "$uid" ]; then
  93. useradd_options+=("-u" "$uid") ## force uid
  94. fi
  95. if [ "$first_group" ]; then
  96. useradd_options+=("-G" "$first_group") ## force main group
  97. fi
  98. code+="adduser ${useradd_options[*]} \"$user\""$'\n'
  99. if [ "$allow_writeable_chroot" ]; then
  100. code+="chown $user \"/home/$user\""$'\n' ## sanitize
  101. else
  102. code+="chown root:root \"/home/$user\""$'\n' ## sanitize
  103. fi
  104. code+="chmod 755 \"/home/$user\""$'\n' ## sanitize
  105. password=$(echo "$user_def" | shyaml get-value password 2>/dev/null) ||
  106. password=$(gen_password 14)
  107. code+="echo '$user:$password' | chpasswd"$'\n'
  108. for group in "${remaining_groups[@]}"; do
  109. code+="adduser \"$user\" \"$group\""$'\n'
  110. done
  111. ##
  112. ## Key managements
  113. ##
  114. while read-0 key; do
  115. keys+="$key"$'\n'
  116. done < <(echo "$user_def" | shyaml get-values-0 -q keys)
  117. if [ "$keys" ]; then
  118. code+="mkdir -p \"/home/$user/.ssh\""$'\n'
  119. code+="cat <<EOF > /home/$user/.ssh/authorized_keys"$'\n'
  120. code+="$keys"
  121. code+="EOF"$'\n'
  122. # code+="chown $user /home/$user/.ssh/authorized_keys"$'\n'
  123. code+="chmod 644 /home/$user/.ssh/authorized_keys"$'\n'
  124. code+="chmod 755 /home/$user/.ssh"$'\n'
  125. fi
  126. done < <(echo "$users_def" | shyaml key-values-0)
  127. {
  128. echo -n "$fixed_groups_code"
  129. echo -n "$groups_code"
  130. echo -n "$code"
  131. } | tee "$cache_file"
  132. }