|
| 1 | +#!/bin/bash |
| 2 | +# fix-perms.sh — Reset ownership and permissions for multi-user repo access. |
| 3 | +# |
| 4 | +# Run with sudo whenever permission issues arise: |
| 5 | +# sudo scripts/fix-perms.sh |
| 6 | +# |
| 7 | +# This ensures both Linux users in the devshare group can read/write |
| 8 | +# the repo without stepping on each other's permissions. |
| 9 | + |
| 10 | +set -euo pipefail |
| 11 | + |
| 12 | +REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" |
| 13 | +GROUP="${GROUP:-devshare}" |
| 14 | +OWNER="${OWNER:-eg}" |
| 15 | + |
| 16 | +if [[ $EUID -ne 0 ]]; then |
| 17 | + echo "ERROR: This script must be run as root (sudo)." >&2 |
| 18 | + echo " sudo $0" >&2 |
| 19 | + exit 1 |
| 20 | +fi |
| 21 | + |
| 22 | +echo "=== Fixing permissions for $REPO_DIR ===" |
| 23 | +echo " Owner: $OWNER Group: $GROUP" |
| 24 | +echo "" |
| 25 | + |
| 26 | +# ── Fix ownership ──────────────────────────────────────────────── |
| 27 | +# All files belong to $OWNER:$GROUP so both users in the group can |
| 28 | +# access them (group permissions in the next step). |
| 29 | +echo "--- Step 1: Fixing ownership (chown) ---" |
| 30 | +chown -R "$OWNER":"$GROUP" "$REPO_DIR" |
| 31 | + |
| 32 | +# ── Fix directory permissions ──────────────────────────────────── |
| 33 | +# Drwxrws--- (2770) = rwx for owner+group, setgid bit so new files |
| 34 | +# inherit the group. The setgid bit is critical — without it, a |
| 35 | +# file created by user B gets user B's primary group instead of |
| 36 | +# 'devshare'. |
| 37 | +echo "--- Step 2: Fixing directory permissions (chmod 2770) ---" |
| 38 | +find "$REPO_DIR" -type d -exec chmod 2770 {} + |
| 39 | + |
| 40 | +# ── Fix file permissions ───────────────────────────────────────── |
| 41 | +# -rw-rw---- (660) = rw for owner+group, nothing for others. |
| 42 | +# Exclude files that need +x (scripts, binaries). |
| 43 | +echo "--- Step 3: Fixing file permissions (chmod 660 +x) ---" |
| 44 | +find "$REPO_DIR" -type f -exec chmod 660 {} + |
| 45 | + |
| 46 | +# Restore execute bits on files that need them. |
| 47 | +# Match common executable patterns. |
| 48 | +echo "--- Step 4: Restoring execute bits ---" |
| 49 | +find "$REPO_DIR" -type f \( \ |
| 50 | + -name "*.sh" -o \ |
| 51 | + -name "*.py" -o \ |
| 52 | + -name "*.pl" -o \ |
| 53 | + -name "*.rb" -o \ |
| 54 | + -path "*/bin/*" -o \ |
| 55 | + -path "*/.githooks/*" -o \ |
| 56 | + -name "configure" -o \ |
| 57 | + -name "Makefile*" \ |
| 58 | +\) -exec chmod 770 {} + 2>/dev/null || true |
| 59 | + |
| 60 | +# Restore execute on the mxcli binary |
| 61 | +chmod 770 "$REPO_DIR/bin/mxcli" 2>/dev/null || true |
| 62 | + |
| 63 | +# ── Special-case: ensure .git permissions work ─────────────────── |
| 64 | +# Git needs to be able to write to .git/objects, .git/refs, etc. |
| 65 | +if [[ -d "$REPO_DIR/.git" ]]; then |
| 66 | + chmod -R 2770 "$REPO_DIR/.git" |
| 67 | +fi |
| 68 | + |
| 69 | +# ── Verify ──────────────────────────────────────────────────────── |
| 70 | +echo "" |
| 71 | +echo "=== Verification (spot check) ===" |
| 72 | +STAT=$(stat -c "%a %G %U" "$REPO_DIR" 2>/dev/null || stat -f "%Sp %Sg %Su" "$REPO_DIR" 2>/dev/null) |
| 73 | +echo " Repo root: $STAT" |
| 74 | + |
| 75 | +# Quick test: can the group write a temp file? |
| 76 | +TEST_FILE="$REPO_DIR/.perm_test_$$" |
| 77 | +if touch "$TEST_FILE" 2>/dev/null; then |
| 78 | + rm -f "$TEST_FILE" |
| 79 | + echo " Result: OK — group can write to repo" |
| 80 | +else |
| 81 | + echo " WARNING: group still cannot write to repo" |
| 82 | +fi |
| 83 | + |
| 84 | +echo "" |
| 85 | +echo "=== Done ===" |
| 86 | +echo "Run as the other user to verify: ls -la $REPO_DIR" |
0 commit comments