2.16 Enumeration
Query asks about objects the authority can already name. Enumeration
asks a source to produce them: to fill a POSIX passwd or group
table, or to page through a group whose membership will not fit in one
answer.
A source is never required to enumerate. A source that declines is fully conforming, and this section exists as much to make declining safe as to make enumerating possible.
2.16.1 EnumerateSource #
msg_type = 0x0006. Authority to source. Opens a conversation.
| Field | Encoding | Limit |
|---|---|---|
kind | u8 | PGSS §2.B |
fields | u32 | PGSS §2.B |
of | length-framed key entry (§2.15) | |
cursor | length-framed bytes | 256 bytes |
kind MUST NOT be Any.
An empty of enumerates every object of kind the source holds. A
non-empty of MUST name a group, and enumerates that group's members.
cursor is empty on the first request, and otherwise carries the next
from the source's immediately preceding reply.
2.16.2 EnumerateResult #
msg_type = 0x8006. Source to authority. Terminal.
| Field | Encoding | Limit |
|---|---|---|
outcome | u8 | §2.B |
entries | array of result entries (§2.15) | 256 |
next | length-framed bytes | 256 bytes |
An empty next ends the enumeration. A non-empty next means there is
more, even where entries is empty.
A source MUST size a page against the smaller of this chapter's message ceiling and PGSS Logon's, because the authority re-encodes what it returns into the latter (§2.A). Neither the 256-entry bound nor the message ceiling here prevents a page nobody can deliver.
A source that will not enumerate replies Refused, with entries and
next empty. An authority MUST record it as a source that did not
contribute, and MUST NOT retry it for the remainder of that enumeration
— across pages as well as within one (PGSS §2.17).
Refused and an empty Found are different answers and MUST NOT be
conflated. Found with entries and next both empty says there
are none: the group exists and has no recorded members, or the source
holds no objects of that kind. Refused says this source is not
answering. A source that returns an empty Found where it means the
second has told the authority a falsehood it cannot detect, and the
authority will go on asking it — the non-retry rule above has nothing to
attach to.
The cases most often got wrong, all of which are Refused and not an
empty Found: a group whose membership the source will not expose, a
key that names an object the source does not hold, a key that names a
principal where a group was required, and a cursor the source can no
longer honour.
2.16.3 Cursors belong to the source #
A cursor is opaque to the authority. The authority MUST NOT construct, parse or modify one; it relays what it was given.
A source MAY encode anything into a cursor, and MAY refuse one it no
longer honours — a store rewritten underneath a half-finished walk is
the ordinary case, not an exceptional one. A refused cursor is
Refused, and the authority MUST NOT restart the enumeration on the
source's behalf.
A source MUST NOT assume a cursor comes back on the same conversation, or on the same connection, and MUST NOT hold per-cursor state it is unwilling to discard.
The authority's own cursor, the one it hands its client, is its to construct — PGSS §2.17 requires it to reject one it did not issue, which it can only do for a cursor it made. A source's cursor travels inside it, not as it.
2.16.4 Why members are here and not only in Query #
MEMBERS is a field of Query (§2.15), so the common case — a small
group, whose members fit alongside the rest of the record — costs one
exchange.
A group whose membership will not fit is reported through PGSS Logon's
TooLarge (PGSS §2.16), and this is where the caller is sent. Paging a
membership through the mechanism that already pages is cheaper than a
third message, and considerably cheaper than the alternative of a
partial member list, which is a wrong answer rather than a smaller one.
2.16.5 Enumeration is not existence #
An authority MUST NOT use enumeration to determine whether a principal exists, and MUST NOT infer from a source declining to enumerate that the source holds nothing.
A directory-backed source able to answer any single question while quite unable to answer all of them is the expected case, not a degraded one.