Commit eeff6a9e authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add config-nsswitch which sets up basic name lookup

parent 5e5891e1
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,4 +8,5 @@ FROM scratch
ENV PATH=/scripts:/bin
COPY --from=collect /stage /
COPY collect-binaries.bash /scripts/collect-binaries
COPY config-nsswitch.bash /scripts/config-nsswitch
ENTRYPOINT ["/bin/bash"]

config-nsswitch.bash

0 → 100755
+114 −0
Original line number Diff line number Diff line
#!/bin/bash
# Copyright (c) 2020 Dom Sekotill <dom.sekotill@kodo.org.uk>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

set -eu -o pipefail
declare -r DEFAULT_STAGE=/stage

USAGE="Usage: $0 [--help] [-s STAGE] [USERNAME[:GROUP[,GROUP...]] ...]

Prepare the necessary libraries and configuration for name lookups with nsswitch

The Name Service Switch system is used by the GNU C library to provide various
types of name lookup including: user names, group names, and host names.  This
script configures an image for those name look-ups.

Hostname lookups are configured to use /etc/hosts (as supplied by Docker) and
DNS.  Users and groups are configured from command line arguments which supply
usernames and optional comma separated group names.  Only *additional* groups
need be specified, not the user's default group which has the same name as the
user.  The root user is always created if not specified.

Options:
  -h|--help         Show this message and exit.
  -s|--stage STAGE  Set the output stage directory. If it does not exist it will
                    be created. (default: $DEFAULT_STAGE)

Environment:
  STAGE:  An alternate way of providing --stage
"

add_group() {
	local IFS= users=${GROUP_USERS[$1]-}
	echo "$1:x:$2:${users%,}" >>$STAGE/etc/group
	unset GROUP_USERS[$1]
}

add_user() {
	echo "$1:x:$2:$2::/:/bin/nologin" >>$STAGE/etc/passwd
}

process_userspec()
{
	declare -a USERS=()
	declare -A GROUP_USERS=()
	declare -a groups
	local IFS=, spec user group i

	for spec in "$@"; do
		user=${spec%:*}
		groups=( ${spec#*:} )
		USERS+=( $user )
		GROUP_USERS[$user]+=""
		for group in "${groups[@]}"; do
			[[ $group = $user ]] && continue
			GROUP_USERS[$group]+="$user,"
		done
	done

	add_user root 0
	add_group root 0

	i=0
	for user in "${USERS[@]}"; do
		add_user $user $((++i))
		add_group $user $i
	done

	i=500
	for group in "${!GROUP_USERS[@]}"; do
		add_group $group $((i++))
	done

	cat <<-END_CONF >$STAGE/etc/nsswitch.conf
		passwd: files
		group:  files
		hosts:  files dns
	END_CONF
}

export PATH+=:$(dirname $0)
export STAGE=${STAGE-$DEFAULT_STAGE}

declare -a USERSPEC=()
until [[ $# -eq 0 ]]; do
	case $1 in
		-h|--help) echo "$USAGE"; exit 0 ;;
		-s|--stage) STAGE=$2; shift ;;
		--*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;;
		--) USERSPEC+=( "$@" ); break ;;
		*) USERSPEC+=( "$1" ) ;;
	esac
	shift
done

mkdir -p $STAGE/etc
collect-binaries /lib/*/libnss*
process_userspec "${USERSPEC[@]}"