diff --git a/src/servers/os-user.ts b/src/servers/os-user.ts index 7bca5c00..cc7381ae 100644 --- a/src/servers/os-user.ts +++ b/src/servers/os-user.ts @@ -369,7 +369,17 @@ export async function confineUserTree(params: { } } - // ── One directory where container bind mounts can live ── + // ── One directory where container bind mounts can live: DISABLED 2026-08-13, code kept ── + // + // `~/.local/dockers` existed only for rootless Docker, and members no longer get a daemon — see the + // commented-out step in api/users/provision-os.ts. Creating a blessed bind-mount directory for a daemon + // that is not there is a promise about container storage the platform no longer keeps. + // + // `.local` itself STAYS. It is not Docker's: the `claude` installer targets `~/.local/bin`, and the + // paragraph below is the record of that directory being created root-owned and blocking it. + // + // The reasoning is kept in full because turning containers back on means uncommenting the block, not + // rediscovering why 711 and why the ACLs come off. // // The default ACLs above are inherited by everything created in the home afterwards, including // `default:other::---`. A rootless container's INNER uid is neither the service user nor the member — @@ -416,37 +426,39 @@ export async function confineUserTree(params: { ]); if (!madeLocalDir.ok) return { ok: false, error: `could not create ${localDir}: ${madeLocalDir.out}` }; - const composeDir = join(home, '.local', 'dockers'); - const madeComposeDir = await run([ - 'sudo', - '-n', - 'install', - '-d', - '-o', - String(params.uid), - '-g', - String(params.gid), - // 711, not 700, and this is the whole point of the directory. A container's inner uid is `other`, so it - // needs `x` HERE to reach a bind source inside — 700 blocks the path before any ACL matters. `r` stays - // off, so nothing can list it. Safe because the home above is 700: no other account can traverse this - // far in the first place, and the only uids that get here are the member's own containers. - '-m', - '711', - composeDir, - ]); - if (!madeComposeDir.ok) return { ok: false, error: `could not create ${composeDir}: ${madeComposeDir.out}` }; - - // `-b`, not `-k`: remove ACCESS entries as well as defaults, leaving plain POSIX modes. + // const composeDir = join(home, '.local', 'dockers'); + // const madeComposeDir = await run([ + // 'sudo', + // '-n', + // 'install', + // '-d', + // '-o', + // String(params.uid), + // '-g', + // String(params.gid), + // // 711, not 700, and this is the whole point of the directory. A container's inner uid is `other`, so + // // it needs `x` HERE to reach a bind source inside — 700 blocks the path before any ACL matters. `r` + // // stays off, so nothing can list it. Safe because the home above is 700: no other account can + // // traverse this far in the first place, and the only uids that get here are the member's own + // // containers. + // '-m', + // '711', + // composeDir, + // ]); + // if (!madeComposeDir.ok) return { ok: false, error: `could not create ${composeDir}: ${madeComposeDir.out}` }; // - // `-k` alone left `mask::---` behind — inherited named entries with every permission masked off, reading - // as `user:pastilhas:rwx #effective:---`. An ACL that says one thing and means another is worse than no - // ACL, and container storage is the one place in the home that wants ordinary mode bits and nothing else. - // - // AFTER the recursive grant above, or what it just set is re-inherited here. - const stripped = await run(['sudo', '-n', 'setfacl', '-R', '-b', composeDir]); - if (!stripped.ok) { - return { ok: false, error: `could not clear inherited ACLs from ${composeDir}: ${stripped.out}` }; - } + // // `-b`, not `-k`: remove ACCESS entries as well as defaults, leaving plain POSIX modes. + // // + // // `-k` alone left `mask::---` behind — inherited named entries with every permission masked off, + // // reading as `user:pastilhas:rwx #effective:---`. An ACL that says one thing and means another is worse + // // than no ACL, and container storage is the one place in the home that wants ordinary mode bits and + // // nothing else. + // // + // // AFTER the recursive grant above, or what it just set is re-inherited here. + // const stripped = await run(['sudo', '-n', 'setfacl', '-R', '-b', composeDir]); + // if (!stripped.ok) { + // return { ok: false, error: `could not clear inherited ACLs from ${composeDir}: ${stripped.out}` }; + // } return { ok: true }; } catch (ex) {