diff --git a/src/users.sh b/src/users.sh new file mode 100644 index 0000000..6e8b4ec --- /dev/null +++ b/src/users.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +# === Motivation === +# Create user accounts with proper permissions for system access. + +# === Problem Statement === +# A bootable system needs at least root access and a non-privileged user account. + +# === Scope === +# In scope: root password, standard user creation, group membership, sudo configuration. +# Out of scope: multiple users, password policies, PAM configuration. + +# === Concepts === +# Root user: Administrative account with UID 0, full system access. +# Standard user: Non-privileged account for daily tasks, can escalate via sudo. +# wheel group: Traditional Unix group for sudo access. +# useradd: Creates user accounts with home directory and group membership. + +# === Decisions === +# Root password is set interactively (security requirement). +# Standard user is created with wheel group for sudo access. +# Additional groups (audio, video, storage, network) are added for hardware access. +# User password is set interactively (same security requirement as root). +# sudo is configured by uncommenting wheel group in /etc/sudoers. +# Default shell is /bin/bash (most common, widely supported). + +# === Alternatives Considered === +# Hash-based password rejected for initial implementation (requires additional config). +# Passwordless sudo rejected (security risk). +# Creating user without sudo rejected (user would be unable to administer system). +# systemd-homed rejected (Void uses traditional user management). + +# === Constraints === +# Target system must be mounted at $MOUNT_ROOT. +# sudo package must be installed before configuration. +# Interactive password input requires TTY. + +# === Open Questions === +# Should we support multiple user creation? +# Should we validate password strength? +# Should we configure shell based on user preference? + +# === Success Criteria === +# Root password is set and login works. +# Standard user can log in with password. +# Standard user can execute sudo commands. +# User has access to audio, video, and network hardware. + +users_setup() { + : "${MOUNT_ROOT:?Mount root is required}" + : "${USERNAME:?Username is required}" + local user_shell="${USER_SHELL:-/bin/bash}" + local user_groups="${USER_GROUPS:-wheel,audio,video,storage,network}" + + log_info "User setup: configuring root and creating standard user" + + # Set root password interactively + log_info "Setting root password" + log_info "Please enter the root password when prompted:" + if ! chroot "$MOUNT_ROOT" passwd; then + die "Failed to set root password" + fi + + # Create standard user + log_info "Creating user: $USERNAME" + if chroot "$MOUNT_ROOT" id "$USERNAME" >/dev/null 2>&1; then + log_warn "User $USERNAME already exists, skipping creation" + else + # Create user with home directory and group membership + if ! chroot "$MOUNT_ROOT" useradd -m -G "$user_groups" -s "$user_shell" "$USERNAME"; then + die "Failed to create user: $USERNAME" + fi + log_info "User $USERNAME created with groups: $user_groups" + fi + + # Set user password interactively + log_info "Setting password for user: $USERNAME" + log_info "Please enter the password for $USERNAME when prompted:" + if ! chroot "$MOUNT_ROOT" passwd "$USERNAME"; then + die "Failed to set password for user: $USERNAME" + fi + + # Configure sudo for wheel group + log_info "Configuring sudo access for wheel group" + local sudoers_file="$MOUNT_ROOT/etc/sudoers" + + if [[ ! -f "$sudoers_file" ]]; then + die "Sudoers file not found. Ensure sudo package is installed." + fi + + # Backup sudoers file + cp "$sudoers_file" "${sudoers_file}.bak" + + # Uncomment wheel group line (allow members of wheel to execute any command) + if grep -q "^# %wheel ALL=(ALL:ALL) ALL" "$sudoers_file"; then + sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' "$sudoers_file" + log_info "Enabled sudo for wheel group" + elif grep -q "^%wheel ALL=(ALL:ALL) ALL" "$sudoers_file"; then + log_info "sudo for wheel group already enabled" + elif grep -q "^# %wheel ALL=(ALL) ALL" "$sudoers_file"; then + # Alternative format + sed -i 's/^# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/' "$sudoers_file" + log_info "Enabled sudo for wheel group (alternative format)" + else + # Add wheel group entry if not present + echo "%wheel ALL=(ALL:ALL) ALL" >> "$sudoers_file" + log_info "Added sudo configuration for wheel group" + fi + + # Validate sudoers file syntax + if ! chroot "$MOUNT_ROOT" visudo -c -f /etc/sudoers >/dev/null 2>&1; then + log_warn "Sudoers file validation failed, restoring backup" + mv "${sudoers_file}.bak" "$sudoers_file" + die "Failed to configure sudo (syntax error)" + fi + + rm -f "${sudoers_file}.bak" + + log_info "User setup complete." +}