feat(shares): R-7b Parts 1-2 — shares payload builder + tier-2 shares job (Model B')
Sibling shares source for the local cross-drive tier. Reuses the tier2Mirror seam, selectTier2TargetFrom (narrow source-drive seam extracted from selectTier2Target), tier2ReconcileRoots (pure extraction), tier2SafeRemove, the marker-LAST discipline and the recordTier2* helpers. Per-app paths are untouched. - shares_payload.go: deterministic _shares-manifest.json + best-effort passdb capture - tier2_shares.go: per-source-drive legs -> cross-drive target, payload, marker LAST - infra.SambaContainerName/SambaPassdbVolume/Mount: single source of truth for the container identity (renderer, stacks execs, backup execs, monitor all read it) - RESERVED-NAME finding: ValidateSMBShareName did NOT exclude a leading underscore, so "_shares" was an accepted share name. Now refused; RunAllTier2 additionally skips a "_shares" stack loudly as defense in depth. - fix: shareSourceDrive returned a slash-normalised path, which made the target selector's source-drive equality check miss (a group could target its own drive)
This commit is contained in:
@@ -30,6 +30,21 @@ type SambaData struct {
|
||||
// SambaHouseholdUser is the single household SMB account name (matches the entrypoint's unix user).
|
||||
const SambaHouseholdUser = "felhom"
|
||||
|
||||
// SambaContainerName is the fixed container name the compose render pins. It is THE single source of
|
||||
// truth for it: the renderer below interpolates this constant, stacks.sambaContainer aliases it for
|
||||
// the exec paths, monitor's effective-protected set watches it (R-7b liveness), and the backup
|
||||
// package execs it for the passdb capture/restore. Anything that needs "which container is samba"
|
||||
// reads this — never a second string literal.
|
||||
const SambaContainerName = "felhom-samba"
|
||||
|
||||
// SambaPassdbVolume / SambaPassdbMount name the docker volume that holds the household SMB credential
|
||||
// (the passdb tdb set) and where the container mounts it. R-7b's payload capture/restore targets this
|
||||
// mount point, so it is pinned here beside the render that creates it rather than duplicated there.
|
||||
const (
|
||||
SambaPassdbVolume = "samba-passdb"
|
||||
SambaPassdbMount = "/var/lib/samba"
|
||||
)
|
||||
|
||||
// RenderSambaConfig renders smb.conf: the hardened global block (bind interfaces only = lo eth0,
|
||||
// SMB2+ floor, NetBIOS on for flat-name resolution) plus one [section] per share. Deterministic:
|
||||
// shares are emitted in the given order (the caller preserves registry order). force user/group pin
|
||||
@@ -95,21 +110,21 @@ func RenderSambaCompose(d SambaData) string {
|
||||
# receive the LAN multicast that WSD/mDNS discovery needs.
|
||||
|
||||
services:
|
||||
felhom-samba:
|
||||
image: %s
|
||||
container_name: felhom-samba
|
||||
%[1]s:
|
||||
image: %[2]s
|
||||
container_name: %[1]s
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
environment:
|
||||
- FELHOM_SERVER_NAME=%s
|
||||
- FELHOM_SERVER_NAME=%[3]s
|
||||
- FELHOM_IFACE=eth0
|
||||
- FELHOM_UID=%d
|
||||
- FELHOM_GID=%d
|
||||
- FELHOM_UID=%[4]d
|
||||
- FELHOM_GID=%[4]d
|
||||
volumes:
|
||||
- ./smb.conf:/etc/samba/smb.conf:ro
|
||||
- samba-passdb:/var/lib/samba
|
||||
%s
|
||||
- %[5]s:%[6]s
|
||||
%[7]s
|
||||
volumes:
|
||||
samba-passdb:
|
||||
`, SambaImage, d.ServerName, d.UID, d.UID, binds.String())
|
||||
%[5]s:
|
||||
`, SambaContainerName, SambaImage, d.ServerName, d.UID, SambaPassdbVolume, SambaPassdbMount, binds.String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user