modified: masu_subu__map_own.sh
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 25 Sep 2025 11:36:56 +0000 (11:36 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 25 Sep 2025 11:36:56 +0000 (11:36 +0000)
developer/source/mount/masu_subu__map_own.sh

index 6d9cadd..d6820e5 100755 (executable)
@@ -2,20 +2,21 @@
 # masu_subu__map_own.sh <user> <subu> [--suid]
 #
 # Examples:
-#   subu_bind Thomas developer           # default (nosuid)
-#   subu_bind Thomas developer --suid    # enable setuid on this mount
+#   sudo ./masu_subu__map_own.sh Thomas developer
+#   sudo ./masu_subu__map_own.sh Thomas developer --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
 
-  if ! command -v bindfs &>/dev/null; then
-    echo "Error: bindfs is not installed!" >&2
-    return 1
-  fi
+  need bindfs
+  need findmnt
+  need mountpoint
 
   # identities
   local master_user_name="$user"
@@ -33,43 +34,59 @@ subu_bind() {
   [[ -d "$subu_data_path" ]] || { echo "Error: source dir '$subu_data_path' does not exist!" >&2; return 1; }
   mkdir -p "$subu_mount_point_path"
 
-  # mount options
-  # - allow_other/default_permissions: kernel does POSIX perms
-  # - exec: allow execution on the mount
-  # - suid: only when explicitly requested (and only works when mounted as root)
+  # desired options
   local base_opts="allow_other,default_permissions,exec"
   local opts="$base_opts,nosuid"
   if [[ "$want_suid" == "--suid" ]]; then
     opts="$base_opts,suid"
   fi
 
-  # The UID/GID mapping you already use
+  # map rule
   local map_opt="--map=${subu_user_name}/${master_user_name}:@${subu_group}/@${master_group}"
 
-  # If already mounted, decide whether to keep or remount
-  if findmnt -n -T "$subu_mount_point_path" >/dev/null 2>&1; then
-    current_opts="$(findmnt -no OPTIONS -T "$subu_mount_point_path" || true)"
-    if [[ ",$current_opts," != *",$opts,"* ]]; then
+  # 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"
-      # clean remount: unmount then mount with new opts
-      sudo umount "$subu_mount_point_path"
-      sudo bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
+      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"
-    sudo bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
+    bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
   fi
 
-  # Verify outcome
+  # 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."
+    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
 }
 
+# run (sudo not needed if already root)
 subu_bind "${1:-}" "${2:-}" "${3:-}"