feat(users): add user management module
Implement user account creation and sudo configuration: - Interactive root password setup in chroot - Standard user creation with configurable groups - Automatic sudo configuration for wheel group - Password validation via visudo Decision: Set passwords interactively for security. Hash-based passwords rejected for initial implementation (complexity vs security trade-off). User groups: wheel (sudo), audio, video, storage, network. Provides hardware access without additional configuration. Alternative considered: Passwordless sudo rejected (security risk). Creating user without sudo rejected (user would be unable to administer system). Trade-off: Interactive password input requires TTY and manual entry. More secure than storing hashes but less convenient for automated installations. Future config file support can add hash option. Sudoers validation: Use visudo -c to validate syntax before committing changes. Rollback to backup if validation fails. This prevents lockout from broken sudoers file.
This commit is contained in:
parent
56c8234d35
commit
4ac64e6659
120
src/users.sh
Normal file
120
src/users.sh
Normal file
@ -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."
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user