# Samba / LAN File Sharing Setup

## Decision Framework

When user needs to access a project folder from another machine (e.g. Android Studio on desktop workstation, server project on laptop):

| Method | Setup effort | Gradle/IDE perf | Use case |
|--------|-------------|-----------------|----------|
| **Samba** | Medium (install + config + password) | Good (oplocks, strict locking off) | Daily development, Android Studio, Gradle builds |
| **SSHFS** | Low (install client, mount) | Poor (latent, lots of tiny reads) | Occasional file editing, browsing |
| **Remote Dev (JetBrains Gateway)** | High (install IDE backend + SDKs on server) | Excellent (compilation on server) | Heavy IDE usage, limited workstation |

**Recommendation:** Samba for daily Android Studio/Gradle work. SSHFS for one-off browsing.

---

## Server Setup (Debian)

### Install

```bash
sudo apt install -y samba samba-common
```

### smb.conf — Gradle-Performance Tuned

Place at `/etc/samba/smb.conf`:

```ini
[global]
   workgroup = WORKGROUP
   server role = standalone server
   netbios name = DEBIAN-AI
   server string = <description>

   # Bind to LAN only
   interfaces = 127.0.0.1 192.168.1.0/24
   bind interfaces only = yes

   # Logging
   log file = /var/log/samba/log.%m
   max log size = 1000
   logging = file
   panic action = /usr/share/samba/panic-action %d

   # Auth
   obey pam restrictions = yes
   unix password sync = yes
   passwd program = /usr/bin/passwd %u
   pam password change = yes
   map to guest = bad user
   usershare allow guests = no

   # Performance — critical for Gradle/Android Studio
   socket options = TCP_NODELAY IPTOS_LOWDELAY
   read raw = yes
   write raw = yes
   strict locking = no
   oplocks = yes
   level2 oplocks = yes
   kernel oplocks = yes

[<share-name>]
   comment = <description>
   path = /path/to/project
   browseable = yes
   read only = no
   writable = yes
   create mask = 0644
   directory mask = 0755
   valid users = <user>
   force user = <user>
   force group = <user>
```

**Key perf opts:** `strict locking = no` avoids SMB2 locking round-trips on every read/write. `oplocks = yes` + `kernel oplocks = yes` enables client-side caching. `socket options = TCP_NODELAY IPTOS_LOWDELAY` reduces latency for small reads.

### Firewall (UFW)

```bash
sudo ufw allow from 192.168.1.0/24 to any port 139,445 proto tcp comment 'Samba'
sudo ufw allow from 192.168.1.0/24 to any port 137,138 proto udp comment 'Samba NetBIOS'
```

### Start Services

```bash
# Disable AD DC if it conflicts on port 135
sudo systemctl disable --now samba-ad-dc 2>/dev/null

sudo systemctl enable --now smbd nmbd
```

### Set Samba Password

```bash
# Interactive
sudo smbpasswd <user>

# Non-interactive (pipe from stdin)
printf "%s\n%s\n" "$PASSWORD" "$PASSWORD" | sudo smbpasswd -a -s <user>
```

Or generate a random password:
```bash
PASS=$(openssl rand -base64 12)
printf "%s\n%s\n" "$PASS" "$PASS" | sudo smbpasswd -a -s rurouni
echo "Password: $PASS"
```

### Verify

```bash
sudo testparm -s         # config syntax
sudo smbcontrol smbd ping  # PONG = running
```

---

## Client Setup (CachyOS / Arch)

### KDE Dolphin (Quick Access)

Navigate to `smb://192.168.1.50/<share-name>`, bookmark it.

### cifs-utils Mount (Android Studio)

```bash
sudo pacman -S smbclient cifs-utils
sudo mkdir -p /mnt/<share-name>
sudo mount -t cifs //192.168.1.50/<share-name> /mnt/<share-name> \
  -o username=<user>,password=<password>,uid=$(id -u),gid=$(id -g),iocharset=utf8,noatime,noserverino
```

Then Android Studio → **Open** → `/mnt/<share-name>/`

### fstab Auto-Mount

```fstab
//192.168.1.50/<share-name>  /mnt/<share-name>  cifs  username=<user>,password=<password>,uid=1000,gid=1000,noatime,noserverino,iocharset=utf8,x-systemd.automount  0  0
```

Apply: `sudo mount -a`

---

## Pitfalls

- **samba-ad-dc auto-starts** on Debian and conflicts with smbd on port 135. Disable it immediately after install.
- **smbcontrol smbd ping** confirms the daemon is alive. `smbstatus` requires root.
- **User-mismatch shares:** If the file owner on the server differs from the Samba user, use `force user = <owner>` in the share config to avoid permission errors on write.
- **UFW blocks Samba by default** — Samba's ports (139, 445) are not in the default allow list. Add rules explicitly.
- **`noserverino` mount flag** avoids inode number caching issues when files change on the server (Gradle's file-watching).
- **Multi-machine Android projects:** After mounting, also fix `gradle.properties` Java home and `local.properties` SDK path to point at the **client** machine's JDK/SDK (not the server's). See `android-project-build` → `references/samba-multi-machine-dev.md`.
