+# masu__map_own_all.sh
#!/bin/bash
+set -euo pipefail
+masu="${1:?Usage: $0 <masu> [--suid=subu1,subu2] }"
+suid_list="${2-}" # optional: --suid=a,b,c
-# Check if the correct number of arguments is passed
-if [ $# -ne 1 ]; then
- echo "Usage: $0 <username>"
- exit 1
-fi
+# Build a set for quick membership checks
+want_suid() {
+ [[ -n "$suid_list" ]] || return 1
+ [[ "$suid_list" =~ ^--suid= ]] || return 1
+ IFS=',' read -r -a arr <<< "${suid_list#--suid=}"
+ for n in "${arr[@]}"; do [[ "$n" == "$1" ]] && return 0; done
+ return 1
+}
-user=$1
+subus=$(./masu__subu_dir_list.sh "$masu")
+[[ -n "$subus" ]] || { echo "No sub-users found for $masu"; exit 1; }
-# Get the list of sub-users by calling the user_list_subu_home.sh script
-subu_list=$(./masu__subu_dir_list.sh "$user")
-
-# Check if we received any sub-users
-if [ -z "$subu_list" ]; then
- echo "No sub-users found for $user."
- exit 1
-fi
-
-# Loop through the sub-users and call user_open_subu.sh for each
-for subu in $subu_list; do
- echo "Opening sub-user: $subu"
- ./masu_subu__map_own.sh "$user" "$subu"
-done
+while IFS= read -r s; do
+ [[ -n "$s" ]] || continue
+ echo "Opening sub-user: $s"
+ if want_suid "$s"; then
+ sudo ./masu_subu__map_own.sh "$masu" "$s" --suid
+ else
+ sudo ./masu_subu__map_own.sh "$masu" "$s"
+ fi
+done <<< "$subus"
+# masu_subu__map_own.sh
#!/bin/bash
-# masu_subu__map_own.sh <user> <subu> [--suid]
-#
-# Examples:
-# sudo ./masu_subu__map_own.sh Thomas developer
-# sudo ./masu_subu__map_own.sh Thomas developer --suid
-
+# usage: sudo ./masu_subu__map_own.sh <masu> <subu> [--suid]
set -euo pipefail
-need() { command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
-
-subu_bind() {
- local user="$1"
- local subu="$2"
- local want_suid="${3-}" # optional third arg
-
- need bindfs
- need findmnt
- need mountpoint
-
- # identities
- local master_user_name="$user"
- local master_group="$user"
- local subu_user_name="${user}-${subu}"
- local subu_group="${user}-${subu}"
-
- id "$master_user_name" &>/dev/null || { echo "Error: user '$master_user_name' not found!" >&2; return 1; }
- id "$subu_user_name" &>/dev/null || { echo "Error: sub-user '$subu_user_name' not found!" >&2; return 1; }
-
- # paths
- local subu_data_path="/home/$user/subu_data/$subu"
- local subu_mount_point_path="/home/$user/subu/$subu"
-
- [[ -d "$subu_data_path" ]] || { echo "Error: source dir '$subu_data_path' does not exist!" >&2; return 1; }
- mkdir -p "$subu_mount_point_path"
-
- # desired options
- local base_opts="allow_other,default_permissions,exec"
- local opts="$base_opts,nosuid"
- if [[ "$want_suid" == "--suid" ]]; then
- opts="$base_opts,suid"
+need(){ command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
+
+want_suid=0
+case "${3-}" in
+ --suid) want_suid=1 ;;
+ "" ) ;;
+ * ) echo "unknown option: $3" >&2; exit 2 ;;
+esac
+
+masu="${1:?usage: $0 <masu> <subu> [--suid] }"
+subu="${2:?usage: $0 <masu> <subu> [--suid] }"
+
+need bindfs; need findmnt; need mountpoint; id "$masu" >/dev/null
+id "${masu}-${subu}" >/dev/null
+
+src="/home/$masu/subu_data/$subu"
+tgt="/home/$masu/subu/$subu"
+[[ -d "$src" ]] || { echo "Error: source dir '$src' does not exist" >&2; exit 1; }
+mkdir -p "$tgt"
+
+base_opts="allow_other,default_permissions,exec"
+desired_opts="$base_opts,$([[ $want_suid -eq 1 ]] && echo suid || echo nosuid)"
+map_opt="--map=${masu}-${subu}/${masu}:@${masu}-${subu}/@${masu}"
+
+opts_have() { grep -qw "$1"; }
+
+# Peel off incorrect layers until either:
+# - nothing is mounted on $tgt, or
+# - the top-most layer is a bindfs of $src with desired opts
+while mountpoint -q "$tgt"; do
+ read -r FSTYPE SOURCE OPTIONS < <(findmnt -T "$tgt" -no FSTYPE,SOURCE,OPTIONS)
+ if [[ "$FSTYPE" != fuse*bindfs* && "$FSTYPE" != fuse.bindfs && "$FSTYPE" != fuse3.bindfs ]]; then
+ echo "⚠︎ '$tgt' is a mountpoint but not bindfs (fstype=$FSTYPE); unmounting this layer…"
+ umount "$tgt" || umount -l "$tgt" || true
+ continue
fi
- # map rule
- local map_opt="--map=${subu_user_name}/${master_user_name}:@${subu_group}/@${master_group}"
-
- # check if *this path* is already a mountpoint
- if mountpoint -q "$subu_mount_point_path"; then
- # only care about a few options, avoid brittle whole-string compare
- local current_opts
- current_opts="$(findmnt -no OPTIONS -T "$subu_mount_point_path" 2>/dev/null || true)"
-
- have_exec=$(grep -qw exec <<<"$current_opts" && echo 1 || echo 0)
- have_suid=$(grep -qw suid <<<"$current_opts" && echo 1 || echo 0)
- have_nosuid=$(grep -qw nosuid <<<"$current_opts" && echo 1 || echo 0)
- have_allow=$(grep -qw allow_other <<<"$current_opts" && echo 1 || echo 0)
-
- want_suid_flag=$([[ "$want_suid" == "--suid" ]] && echo 1 || echo 0)
-
- needs_change=0
- [[ $have_exec -eq 1 ]] || needs_change=1
- [[ $have_allow -eq 1 ]] || needs_change=1
- if [[ $want_suid_flag -eq 1 ]]; then
- [[ $have_suid -eq 1 && $have_nosuid -eq 0 ]] || needs_change=1
- else
- [[ $have_nosuid -eq 1 && $have_suid -eq 0 ]] || needs_change=1
- fi
-
- if [[ $needs_change -eq 1 ]]; then
- echo "remounting $subu_mount_point_path with opts: $opts"
- umount "$subu_mount_point_path" || { echo "⚠︎ umount failed; trying lazy"; umount -l "$subu_mount_point_path" || true; }
- bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
- else
- echo "already mounted with compatible options: $current_opts"
- fi
- else
- echo "mounting $subu_data_path -> $subu_mount_point_path with opts: $opts"
- bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
+ # Normalize desired
+ want_suid_kw=$([[ $want_suid -eq 1 ]] && echo suid || echo nosuid)
+ # Check source and essential flags without brittle full-string compare
+ if [[ "$SOURCE" == "$src" ]] \
+ && opts_have <<<"$OPTIONS" allow_other \
+ && opts_have <<<"$OPTIONS" exec \
+ && opts_have <<<"$OPTIONS" "$want_suid_kw" \
+ && ! opts_have <<<"$OPTIONS" "$([[ $want_suid -eq 1 ]] && echo nosuid || echo suid)"; then
+ echo "already mounted OK: $tgt ← $src ($OPTIONS)"
+ exit 0
fi
- # verify
- findmnt "$subu_mount_point_path" -o TARGET,FSTYPE,OPTIONS
- echo "OK: $subu_data_path -> $subu_mount_point_path"
- if [[ "$want_suid" == "--suid" ]]; then
- echo "note: suid is ENABLED; setuid binaries (e.g., the gasket) can take effect on this mount."
- else
- echo "note: nosuid (default) — setuid will NOT take effect on this mount."
- fi
-}
+ echo "unmounting incorrect layer on $tgt (src=$SOURCE opts=$OPTIONS)…"
+ umount "$tgt" || umount -l "$tgt" || true
+done
-# run (sudo not needed if already root)
-subu_bind "${1:-}" "${2:-}" "${3:-}"
+echo "mounting $src -> $tgt (opts: $desired_opts)"
+bindfs -o "$desired_opts" $map_opt "$src" "$tgt"
+findmnt "$tgt" -o TARGET,SOURCE,FSTYPE,OPTIONS
+echo "OK"