Compare commits

...

2 Commits

2 changed files with 112 additions and 0 deletions

View File

@ -13,3 +13,5 @@ fix-alt(){
}
alias restart-audio="systemctl --user restart pipewire.service"
alias disable-touchscreen="sudo xinput disable 10"
alias enable-touchscreen="sudo xinput enable 10"

View File

@ -0,0 +1,110 @@
#!/bin/bash
set -euo pipefail
shopt -s lastpipe
UID_MAP="/etc/jimlab/uid.map"
SUBID_MAP="/etc/jimlab/subid.map"
DEFAULT_SUBID_SIZE=4096
if [[ ! -f "$UID_MAP" ]]; then
echo "❌ Error: $UID_MAP not found."
exit 1
fi
touch "$SUBID_MAP"
# Return true if two ranges [start1, end1) and [start2, end2) overlap
ranges_overlap() {
local start1=$1
local size1=$2
local start2=$3
local size2=$4
[[ -z "$start1" || -z "$size1" || -z "$start2" || -z "$size2" ]] && return 1
[[ ! "$start1" =~ ^[0-9]+$ || ! "$size1" =~ ^[0-9]+$ || ! "$start2" =~ ^[0-9]+$ || ! "$size2" =~ ^[0-9]+$ ]] && return 1
local end1=$((start1 + size1))
local end2=$((start2 + size2))
[[ $start1 -lt $end2 && $start2 -lt $end1 ]]
}
# Get next available subid base
get_next_subid_base() {
local max=100000
grep -v '^\s*$' "$SUBID_MAP" | while IFS=: read -r _ base size; do
base=$(echo "$base" | xargs)
size=$(echo "$size" | xargs)
[[ "$base" =~ ^[0-9]+$ && "$size" =~ ^[0-9]+$ ]] || continue
local end=$((base + size))
(( end > max )) && max=$end
done
echo "$max"
}
# Warn if overlapping any prior block
check_overlap() {
local new_start=$1
local new_size=$2
grep -v '^\s*$' "$SUBID_MAP" | while IFS=: read -r user base size; do
if ranges_overlap "$new_start" "$new_size" "$base" "$size"; then
echo "⚠️ Warning: new block $new_start:$new_size overlaps with $user:$base:$size" >&2
fi
done
}
grep -v '^\s*$' "$UID_MAP" | while IFS=: read -r service uid; do
service=$(echo "$service" | xargs)
uid=$(echo "$uid" | xargs)
home="/var/lib/$service"
[[ -z "$service" || -z "$uid" || "$service" == \#* ]] && continue
echo "▶️ Processing $service (UID=$uid, HOME=$home)"
# Create group if missing
if ! getent group "$service" > /dev/null; then
echo " Creating group $service with GID $uid"
groupadd --system --gid "$uid" "$service"
fi
# Create or fix user
if ! id "$service" &>/dev/null; then
echo " Creating user $service with UID $uid and home $home"
useradd --system --uid "$uid" --gid "$uid" --home-dir "$home" --create-home --shell /sbin/nologin "$service"
else
current_home=$(getent passwd "$service" | cut -d: -f6)
if [[ "$current_home" != "$home" ]]; then
echo " 🛠 Updating home dir for $service$home"
usermod -d "$home" "$service"
mkdir -p "$home"
chown "$service:$service" "$home"
fi
fi
# Enable lingering
if ! loginctl show-user "$uid" &>/dev/null || ! loginctl show-user "$uid" | grep -q "Linger=yes"; then
echo " 🔄 Enabling lingering for $service"
loginctl enable-linger "$service"
fi
# Subuid/subgid mapping
if ! grep -q "^$service:" "$SUBID_MAP"; then
next_base=$(get_next_subid_base)
check_overlap "$next_base" "$DEFAULT_SUBID_SIZE"
echo " 📦 Assigning subid range: $service:$next_base:$DEFAULT_SUBID_SIZE"
echo "$service:$next_base:$DEFAULT_SUBID_SIZE" >> "$SUBID_MAP"
fi
# Sync to /etc/subuid and /etc/subgid
map_line=$(grep "^$service:" "$SUBID_MAP" | head -n1)
for file in /etc/subuid /etc/subgid; do
if ! grep -q "^$service:" "$file"; then
echo "$map_line" | sudo tee -a "$file" >/dev/null
elif ! grep -q "^$map_line\$" "$file"; then
echo "⚠️ Mismatch in $file for $service. Check manually!" >&2
fi
done
done