#!/bin/sh
# Copyright 2022 Simon McVittie
# SPDX-License-Identifier: GPL-2.0-or-later

# create-normal-user [USERNAME]
# Create an ordinary, unprivileged user.

set -eu

usage () {
    echo "Usage: create-normal-user [USERNAME]" >&2
    exit 2
}

create () {
    # shellcheck disable=SC3043
    local user="$1" uid=1000

    case "$user" in
        ('' | [!a-zA-Z_]* | *[!a-zA-Z0-9_.-]*)
            echo "create-normal-user: Invalid username '$user'" >&2
            return 1
            ;;
    esac

    if getent passwd "$user" >/dev/null || getent group "$user" >/dev/null; then
        echo "create-normal-user: User or group '$user' already exists" >&2
        return 1
    fi

    while getent passwd "$uid" >/dev/null || getent group "$uid" >/dev/null; do
        uid=$((uid + 1))
        if [ "$uid" -gt 59999 ]; then
            echo "create-normal-user: No unused UID/GID in range 1000 to 59999" >&2
            return 1
        fi
    done

    # '*' prevents password authentication; no shadow entry is created.
    printf '%s:*:%s:\n' "$user" "$uid" >> /etc/group
    printf '%s:*:%s:%s:Temporary autopkgtest user:/home/%s:/bin/sh\n' \
        "$user" "$uid" "$uid" "$user" >> /etc/passwd
    install -d -m 0755 -o "$uid" -g "$uid" "/home/$user"

    echo "$user" > /run/autopkgtest-normal-user
}

case "${1-}" in
    (--)
        shift
        ;;

    (-*)
        usage
        ;;
esac

if [ "$#" -gt 1 ]; then
    usage
fi

if [ "$#" -eq 1 ]; then
    create "$1"
    exit 0
fi

tries=20

for i in $(seq 0 "$tries"); do
    if [ "$i" = 0 ]; then
        user="test"
    else
        random=$(mktemp /tmp/test-XXXXXX)
        user="$(basename "$random")"
        rm -f "$random"
    fi

    if getent passwd "$user" >/dev/null || getent group "$user" >/dev/null; then
        echo "create-normal-user: '$user' already exists"
    else
        create "$user"
        exit 0
    fi
done

echo "create-normal-user: Unable to generate a new username (tried $tries times)" >&2
exit 1
