10 (amended): the teardown is done, and terminate-user does not reap everything
Amending 10 in place rather than adding 12: it is my own file, nobody has read it or acted on it, and it carried a PREDICTION about deleting green that is now a measurement. The prediction is left standing and the outcome appended below it, so the diff shows one against the other. The record of what was believed lives in git either way, which is the same argument used when ten dated files were deleted. Item 1 of 01 is now observed. After the owner deleted green through the UI and before anything was cleaned up: the users row was gone, and the Linux account, a working login shell, a healthy postgres container, 454M of home and Docker storage, lingering, the runtime directory and the subuid ranges were all still there. Nothing broke, which is what makes it dangerous. The correction worth having: loginctl terminate-user did NOT reap everything. A /bin/zsh -i owned by green survived it by three hours, after the session was terminated and the runtime directory removed. userdel fails against a live process owned by the account, so any deprovisionOsAccount trusting terminate-user as a barrier works on a quiet account and fails on a member who left a shell open — the normal case. An explicit pkill -u with a -9 fallback and a zero-process check belongs between terminate and userdel. Box verified clean: no accounts >=1000 but the owner, no files owned by 1001 or 1002 anywhere under DATA_PATH or /home, subuid/subgid reduced to the owner, linger empty, the owner's eight containers untouched. officer_jg is gone as well, so the shared-home artefact that started this thread is off the machine. Taking ownership of the spec and the verification for deprovisionOsAccount, not the implementation — four of five defects tonight were in code whose author had already convinced himself it was right, and what caught them was that author and verifier were different people. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,63 @@ and still the most dangerous item in `01`, and tonight it stops being theoretica
|
||||
|
||||
---
|
||||
|
||||
## APPENDED AFTER THE FACT — it has now been done, and item 1 is no longer a prediction
|
||||
|
||||
Everything above this line was written before the teardown. It is left standing rather than rewritten,
|
||||
because what follows is the measurement of it.
|
||||
|
||||
**The owner deleted green through the UI. Before I touched anything:**
|
||||
|
||||
| | after `deleteUserHandler` |
|
||||
|---|---|
|
||||
| `users` row | gone |
|
||||
| Linux account | **alive**, uid 1002 |
|
||||
| Login shell | **`id -u` → 1002** — the deleted account still had a working login |
|
||||
| `postgres` container | **Up 2 hours (healthy)** |
|
||||
| Home + Docker storage | **454M intact** |
|
||||
| linger, `/run/user/1002`, subuid ranges | **all present** |
|
||||
|
||||
So item 1 of `01` is now observed rather than argued. A member deleted from the platform kept a shell, a
|
||||
running daemon, a live container and their data. Nothing broke, which is what makes it dangerous: the silence
|
||||
is the bug.
|
||||
|
||||
**The teardown, as actually executed and verified:**
|
||||
|
||||
```bash
|
||||
sudo loginctl terminate-user green
|
||||
sudo pkill -u green # NOT in the sequence I proposed above — see below
|
||||
sudo loginctl disable-linger green
|
||||
sudo userdel green # dropped the subuid/subgid ranges automatically
|
||||
sudo userdel officer_jg
|
||||
sudo rm -rf /home/pastilhas/officerdev/data/jg@pertento.ai
|
||||
```
|
||||
|
||||
**One correction to my own sequence, and it is the useful part of this appendix.**
|
||||
`loginctl terminate-user` did **not** reap everything. A `/bin/zsh -i` owned by green survived it — three
|
||||
hours old, still running after the session was terminated and the runtime directory removed. `userdel` fails
|
||||
with a live process owned by the account, so a `deprovisionOsAccount` that trusts `terminate-user` alone will
|
||||
work on a quiet account and fail on a member who left a shell open, which is the normal case.
|
||||
|
||||
An explicit `pkill -u`, then a `pkill -9 -u` fallback, then a check that the process count is zero, belongs
|
||||
between terminate and `userdel`. Do not treat `terminate-user` as a barrier.
|
||||
|
||||
**Verified clean afterwards:** no accounts ≥1000 but the owner; no files owned by 1001 or 1002 anywhere under
|
||||
`DATA_PATH` or `/home`; `subuid`/`subgid` reduced to the owner alone; linger empty; `/run/user/1000` only;
|
||||
the owner's eight containers all still up and untouched. uid 1001 and 1002 are now safe to reissue precisely
|
||||
because nothing on disk is owned by either — which is the disposable-data form of your `chown -R` proposal,
|
||||
and the property the real function has to guarantee whichever way it gets there.
|
||||
|
||||
`officer_jg` is gone too. The shared-home artefact that started this thread no longer exists on this machine.
|
||||
|
||||
**On ownership:** I will own the spec and the verification for `deprovisionOsAccount` — the sequence above,
|
||||
the reaping gap, the ordering constraints, and a check that proves a box is clean — but I would rather not
|
||||
write the implementation. Four of the five defects caught tonight were in code whose author had already
|
||||
convinced himself it was right, and the thing that caught them was that the author and the verifier were
|
||||
different people. If I write it, that property is gone for the one function whose failure mode is a member
|
||||
inheriting another member's uid. Yours to implement, mine to try to break.
|
||||
|
||||
---
|
||||
|
||||
## Unchanged
|
||||
|
||||
Both gates up, `member` populated by nothing, 84 tests. The two docker handbacks stay mine and stay parked.
|
||||
|
||||
Reference in New Issue
Block a user