fix(core): resolve the account home through the host resolver - #95
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
Every mutating command derives its activation anchor from the account home. A static musl build cannot see an account held in LDAP, SSSD, or winbind, because the name service switch reaches those backends by loading plugins and a static image has no way to load them. degu's stated deliverable is no-root HPC login nodes, and HPC sites resolve accounts exactly that way, so
init,clean,undo, andtrash purgedid not work there at all. Read-onlyscanandquotawere unaffected; they never touch authority.Observed on a login node with an SSSD account and on a workstation with a winbind account. Same source, same machine, same account — only the libc differs:
degu doctoruncertain, every diagnostic field null, remediation "retry"missing, both anchor paths shown, points atdegu init --initialTwo things compound there. The remediation could never succeed, because retrying a lookup that cannot see the account is not a route to seeing it. And musl reports the miss with a success status and a null result rather than an errno, so "no such user" and "cannot see this user" are indistinguishable at the libc call — the caller cannot even tell which one it hit.
The fix
A miss now puts the same question to the host's own resolver, in a separate process.
This is not a weaker source and not a guess.
getentconsults exactly the name services the host is configured to use, which is what a dynamically linked build would have consulted in-process, so the answer carries the same authority and can name no path the account database does not already name. AmbientHOME, XDG, cwd, configuration, and CLI input still cannot redirect either side of the protocol — the propertyprovision/account.rsdocuments is preserved rather than traded away, and the public wording indocs/safety.mdanddocs/installation.mdremains accurate as written.Absence of the resolver is itself an answer: a host with no
getenthas no name service switch either, so there the local file's lookup was already complete and a miss really is a missing account. The ladder cannot lie.The invocation runs from an absolute path with a fixed argument list, an emptied environment, a neutral working directory and a closed stdin, is bounded in both time and output, and accepts a record only when its UID column is the UID that was asked for. Nothing resolves through
PATHand no shell is involved. Everything downstream is unchanged: trusted ancestry, no-follow preflight, ownership, exact modes, ACL absence, backend certification, strong identity, and binding re-validation all still run on held descriptors after the string arrives.On a host where the local file does answer — every glibc build, and any host with local accounts — nothing changes and no process is spawned.
Diagnosis
The three account outcomes stop reading alike in
doctor:unsupportedand says what to check;uncertainand retryable, with its own reason;This uses the existing
unsupportedstatus, so the JSON schema is unchanged.Placement
The exec bounds live in a shared module rather than beside their caller. The Lustre quota probe already runs the same shape against
lfsand is the intended next caller, so this adds one bounded-invocation implementation rather than a third ad-hoc one.Verification
Built for
x86_64-unknown-linux-musland run on a host whose account is absent from/etc/passwdand served by winbind, so the delegate is the only path that can resolve it.doctormoves fromuncertainwith every field null tomissingwith both anchor paths and a usable next step. The artifact remainsstatic-pie linked, so the release contract's static assertion still holds.cargo clippy --workspace --all-targets --locked -- -D warningsis clean on Linux and macOS. 25 tests were added: record parsing including a non-UTF-8 home, a UID that does not match the request, an ambiguous multi-record answer and a wrong column count; delegate behaviour against a stand-in resolver, covering a normal record, the arguments the resolver receives, a not-found exit, a missing first path, no resolver at all, and a flood; and the invocation bounds themselves, covering environment isolation, output overflow, timeout kill, and a flood past the pipe buffer.