the acl check could not fail, because sudo drops DATA_PATH
Review of 76cd7c2. The ACL finding is right and the fix is correct — verified here that `setfacl -R -P -b`
removes the default entries as well as the access ones, which the man page splits between -b and -k and
does not settle. `acl` is already a core package in setup.sh, so the new hard dependency is real.
But the checker it added cannot fail in the way it is documented to be run.
`assert-uid-free.sh` is invoked as `sudo ./assert-uid-free.sh --check ...`, and sudo's env_reset DROPS
DATA_PATH, so the script falls back to the hardcoded `/home/pastilhas/officerdev/data` — which is not this
machine's data directory and does not exist. Every check in the file is "look for X, report ok when nothing
is found", so a missing root reports clean without looking. Demonstrated: a tree carrying both
`user:65534:rwx` and `default:user:65534:rwx` was reported as `ok no ACL entries naming uid 65534`.
The ACL check is the one that fails silently and completely, because it is the only one scoped to DATA_PATH
alone — the uid and subuid scans still walk /home and would catch something. So the check just added to
catch the hazard ownership cannot see is the check a wrong DATA_PATH disables.
Fixed by refusing rather than passing:
require_roots every search root must exist, or exit 2 naming it and showing the sudo invocation
that preserves DATA_PATH
numeric guard uid/start/count must be numbers. deprovisionOsAccount logs '<no-subuid-range>' in
that position for an account with no /etc/subuid entry, and pasting that log line in
— which is exactly how it is meant to be used — made sub_end empty and turned the
range scan into a no-op.
The handler's audit line now prints DATA_PATH inside the command it tells the operator to copy, and says
so explicitly when there is no subuid range rather than emitting a command that cannot work.
Verified: bogus root exits 2, non-numeric range exits 2, and the ACL check FAILS on a specimen tree
carrying the entries — the "make it fail before trusting it to pass" step from the spec's own subuid
section, now done for the ACL half too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import type { UserRole } from 'officerdb';
|
||||
import * as errors from '@@/custom-errors';
|
||||
import { OS_USERS_ENABLED } from '@@/os-user';
|
||||
import { deprovisionOsAccount } from '@@/os-user-deprovision';
|
||||
import { DATA_PATH } from '@@/data-path';
|
||||
|
||||
// Owner-only management of the other accounts. Everything here is gated by ownerGate in
|
||||
// users-router.ts; these handlers assume the caller is the Super Admin.
|
||||
@@ -139,10 +140,19 @@ export const deleteUserHandler: Handler = async function (ctx) {
|
||||
if (deprovisioned.freed) {
|
||||
// The audit line. `scripts/assert-uid-free.sh --check` takes exactly these arguments, and after
|
||||
// `userdel` this log is the only place the freed subuid range still exists.
|
||||
//
|
||||
// DATA_PATH is spelled out rather than left to the operator, because this line exists to be COPIED
|
||||
// and sudo's env_reset drops it — the version without it fell back to a hardcoded default and made
|
||||
// the checker report CLEAN without reading a single member tree.
|
||||
const { osUser, uid, subUid } = deprovisioned.freed;
|
||||
const range = subUid ? `${subUid.start} ${subUid.count}` : null;
|
||||
console.info(
|
||||
`[users] deprovisioned ${osUser} — verify with: sudo ./scripts/assert-uid-free.sh --check ` +
|
||||
`${osUser} ${uid} ${subUid?.start ?? '<no-subuid-range>'} ${subUid?.count ?? ''}`,
|
||||
range
|
||||
? `[users] deprovisioned ${osUser} — verify with: sudo DATA_PATH=${DATA_PATH} ` +
|
||||
`./scripts/assert-uid-free.sh --check ${osUser} ${uid} ${range}`
|
||||
: `[users] deprovisioned ${osUser} (uid ${uid}) — it had no /etc/subuid range, so only the uid ` +
|
||||
`half is verifiable: sudo DATA_PATH=${DATA_PATH} ./scripts/assert-uid-free.sh --check ` +
|
||||
`${osUser} ${uid} <start> <count> will refuse without real numbers`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user