Beyond MUST and MAY lists, what does an LDAP attribute type definition constrain about the values an entry stores?
answer
- the classes are only half
- each type has its own definition
- syntax fixes the form of a value
- equality decides what counts as duplicate
- SINGLE-VALUE caps the attribute at one
basics
~20 sObject classes say which attribute types may appear; the attribute type definition constrains each value. SYNTAX fixes the form, EQUALITY decides when two values are the same, SINGLE-VALUE caps the count, and NO-USER-MODIFICATION reserves the attribute to the server.
solid answer
~40 sAn object class's `MUST` and `MAY` lists say which attribute types may appear on an entry; the attribute type definition says what a value of that type may be. `SYNTAX` fixes the form a value takes, and a value that does not conform is refused with `invalidAttributeSyntax (21)`. `EQUALITY` names the matching rule that decides when two values are the same value — `caseIgnoreMatch (2.5.13.2)` for most text, `distinguishedNameMatch (2.5.13.1)` for DN-valued types — which is what makes a duplicate `attributeOrValueExists (20)`. `ORDERING` and `SUBSTR` name the rules for ranked and partial comparison where the type supports them. `SINGLE-VALUE` caps the attribute at one value on an entry, breached with `constraintViolation (19)`, and `NO-USER-MODIFICATION` marks a type the server maintains and a client may not write.
code
pseudocode · 12 linesfunction check_value(entry, attribute_type, value):
definition = look up attribute_type in the published schema
if there is no definition:
reject with undefinedAttributeType (17)
if value does not conform to definition SYNTAX:
reject with invalidAttributeSyntax (21)
if definition is SINGLE-VALUE and entry already holds one value:
reject with constraintViolation (19)
for each existing in values of attribute_type already on entry:
if definition EQUALITY matches existing to value:
reject with attributeOrValueExists (20)
accept valuego deeper
Recall that each attribute type has its own published definition, so even an allowed attribute can be refused when the value is the wrong shape or is the second of a type that permits only one.
Walk the clauses one by one — syntax, equality, ordering, substring, single-value, no-user-modification — and say which refusal each produces when a write breaks it.
Show that you reason about values as a set whose duplicates are decided by a matching rule rather than by bytes, which is why a case change is not a new value and a bulk import can silently collapse rows.
The tradeoff is how much meaning you push into the type definitions everyone shares against how much each consuming system re-validates for itself, badly and differently.
## Two halves of one data model Candidates usually learn the object class half of LDAP schema and stop there: classes list attribute types, the union of `MUST` and `MAY` is the permitted set, done. That half only says *which attributes may appear*. The other half says *what a value of that attribute may be*, and it lives in the attribute type definitions the server publishes alongside the classes. An attribute type definition carries an OID, a `NAME`, an optional `SUP` naming a supertype, and then the clauses that do the constraining. It is these clauses, not the class lists, that decide whether a particular value is acceptable and whether a second value of the same type is a duplicate or a legitimate addition. ## The clauses, and what each one fixes | Clause | What it fixes | Typical refusal | |---|---|---| | `SYNTAX` | the form a single value may take | `invalidAttributeSyntax (21)` | | `EQUALITY` | when two values count as the same value | `attributeOrValueExists (20)` | | `ORDERING` | whether values of the type can be ranked at all | the comparison is simply unavailable | | `SUBSTR` | whether partial matching is defined for the type | the comparison is simply unavailable | | `SINGLE-VALUE` | at most one value on any one entry | `constraintViolation (19)` | | `NO-USER-MODIFICATION` | the server owns the value | the client's write is refused | A type whose definition names no `ORDERING` rule cannot be ranked, and one with no `SUBSTR` rule has no defined partial match. That is a property of the definition rather than a limitation of any particular server, and it is why some attributes can be compared in ways others cannot. How a matching rule then *behaves* while a search filter is evaluated is a separate subject; what the definition does is fix which rule applies. ## Attribute values are a set An attribute is multi-valued unless its definition says `SINGLE-VALUE`, and its values form a **set**: unordered, and free of duplicates. Two consequences follow, and both surprise people. First, there is no first value. A client that writes three values and reads them back in a different order has not lost data; ordering was never promised. Second, *duplicate* is decided by the type's `EQUALITY` matching rule and not by comparing bytes. Under `caseIgnoreMatch (2.5.13.2)`, two strings differing only in capitalisation are the same value, so adding the second is refused with `attributeOrValueExists (20)`. Under `caseExactMatch (2.5.13.5)` they are two distinct values. For a DN-valued attribute such as `member`, `distinguishedNameMatch (2.5.13.1)` compares the name structurally rather than as text, so two spellings of one Distinguished Name are one value. An import that assumes byte comparison will either collapse rows it expected to keep or trip over refusals it did not expect. ## Which refusal means what Four result codes cluster here and mixing them up costs real diagnostic time: 1. `undefinedAttributeType (17)` — the server's schema has no definition for that attribute type at all. Nothing can be checked, so nothing is stored. 2. `objectClassViolation (65)` — the type is defined, but no class the entry declares lists it, or a mandatory type is missing. 3. `invalidAttributeSyntax (21)` — the type is defined and allowed, but the value does not fit its `SYNTAX`. 4. `constraintViolation (19)` — the value fits, but some other constraint of the definition does not, the commonest being a second value on a `SINGLE-VALUE` type. Read in that order they describe a funnel: is the type known, is it allowed here, is the value well formed, is this particular value permissible on this particular entry. ## Attributes the client may not write `NO-USER-MODIFICATION` marks a type whose values the directory server maintains. Client writes to it are refused, because the value is not the client's to set. The provenance attributes carry it — `creatorsName`, `createTimestamp`, `modifiersName`, `modifyTimestamp` — as do server-assigned identifiers such as `entryUUID (1.3.6.1.1.16.4)` and the pointer `subschemaSubentry (2.5.18.10)`. These are operational attributes: outside `MUST` and `MAY` altogether, and left out of a read's default result set, so a client that wants them names them explicitly. ## Why it matters in an estate Every constraint you put in the type definition is a rule the directory server enforces once for every client. Every constraint you leave out is a rule each consuming system has to re-implement, and they will not implement it the same way. That is the whole argument for spending time on the second half of the schema rather than only the class lists.
- Why can a directory entry not hold the same attribute value twice?An attribute's values are a set: unordered and duplicate-free. What counts as a duplicate is decided by the type's `EQUALITY` matching rule rather than by byte comparison, so under `caseIgnoreMatch (2.5.13.2)` two values differing only in case are one value, and the write adding the second is refused with `attributeOrValueExists (20)`.
- What does NO-USER-MODIFICATION mark, and which attributes typically carry it?It marks an attribute type whose values the directory server maintains itself, so a client's write to it is refused. The provenance attributes recording who created and last changed an entry — `creatorsName`, `createTimestamp`, `modifiersName`, `modifyTimestamp` — and server-assigned identifiers such as `entryUUID (1.3.6.1.1.16.4)` are the usual carriers.
- Where does a client find the definition of an attribute type it does not recognise?In the `attributeTypes` values of the subschema subentry the server publishes, which carry each type's OID, name and clauses in the same form the specification uses. The definitions are readable over the protocol, so a client can discover a type's syntax and matching rules rather than assume them.
saying these in an interview costs you the question
- Thinks MUST and MAY lists are the only schema constraint on a write.
- Says any attribute may hold many values regardless of its definition.
- Treats two values differing only in case as always distinct values.
- Assumes the client's own field validation is what rejects a bad value.
- Confuses an undefined attribute type with one the entry's classes disallow.