I see some inconsistency and possibly some misunderstanding (probably
mostly at my side) on controls and criticality. This has been
many times, but probably slapd did not converge yet.
The specs (RFC4511) say that controls CAN be critical or non-critical.
Implementations (DSAs) MAY or MAY NOT recognize controls. I see many
cases; some of them are trivial, but other are not.
Let's consider a matrix, where columns represent criticality (FALSE,
TRUE) and rows represent implementation (FALSE, TRUE).
implemented \ criticality | FALSE | TRUE |
FALSE | F,F | F,T |
TRUE | T,F | T,T |
The specs state that if a control is not implemented, criticality
determines whether the control is ignored (crit == FALSE) or the
operation fails (crit == TRUE). If the control is implemented, then
criticality determines whether, in case the control cannot be
applied, whether the control is ignored (crit == FALSE) or the
operation fails (crit == TRUE).
It should be clear that the criticality field is already overloaded:
in the first case the implementation does not know the control,
while in the second case it knows the control so much that it can
determine whether or not it can be applied.
Let's now add a third, fuzzy dimension: control semantics. In fact,
in many specs, the control semantics tries to bend the meaning of
criticality towards common sense.
The specs say that all four combinations F,F; F,T; T,F; T,T are
perfectly legitimate, and describe how a DSA MUST behave in all cases
(or CAN, when an arbitrary behavior is legitimate).
Let me start with intuitive considerations: there are cases in which
some of the four possible behaviors should (lowercase "should") not be
allowed by common sense. However, this seems to violate a strict
interpretation of the specs. I'll bring examples shortly. But in any
case, I believe slapd should behave:
2) biased towards security
a) RFC4370, proxied authorization control, states that "Clients MUST
include the criticality flag and MUST set it to TRUE. Servers MUST
reject any request containing a Proxy Authorization Control without a
criticality flag or with the flag set to FALSE with a protocolError
error." and explains why: "These requirements protect clients from
submitting a request that is executed with an unintended authorization
identity." This is just common sense, and is part of the control's
semantics, but it disagrees with RFC4511, which is normative.
Currently, slapd does not follow this common sense advice, and allows
non-critical proxied authorization requests. Please note the first
"MUST" (for the DUA) and the second "MUST" (for the DSA; this is in
violation of RFC4511).
b) <draft-zeilenga-ldap-dontusecopy-04> (a work in progress) states
"The criticality MUST be TRUE. There is no corresponding response
control." This again is common sense, since if the control is not
recognized, the operation's semantics would be totally different, as
(out of sync) copies could be used instead of the original data, which
is the purpose of the control. Please note the "MUST" (uppercase; for
Currently, slapd follows the advice of this work in progress, but
probably need to be changed in order to be published as an RFC,
as it is now it does not comply with RFC4511 (see ITS#5785).
Note that RFC4511 provides a sentence, about what controls
specifications are to provide, that sounds a little bit ambiguous:
"[...] direction as to what value the sender should provide for the
criticality field (note: the semantics of the criticality field are
defined above should not be altered by the control's specification)".
In the end, the responsibility for getting into trouble is all
the DUA; the specs "are to" (lowercase, no "MUST") provide what the
sender "should" (lowercase, no "SHOULD") provide for the criticality
I believe that this is absolutely correct, but as a DSA implementor,
not only a DUA implementor, I also believe that it is the
of the DSA to make sure its integrity and security is not
a poorly behaving DUA. I recommend we take two actions:
1) make sure slapd behaves consistently in all those cases, no matter
whether we choose to follow the letter of RFC4511 or to tend towards
security and integrity side
2) act in direction of a modification of RFC4511 that somehow allows
semantics of a control to override those of the criticality field. I
believe the criticality field is a mandatory mechanism to promote
interoperability when it comes to extensions. However, there are
where either interoperability exists or doesn't. In those cases, we
cannot simply delegate security and integrity to the DUA, as the DSA
responsible of both in the end.
I believe the main consequence of allowing the DSA to reject (as
something closely related to a protocol violation) a control whose
criticality does not conform with that control's specification in
terms of semantics would be that in the case of criticality set to
FALSE two implementations would behave differently depending on
whether that control is implemented or not. But this degree of
arbitrarity does not differ much from that implicitly allowed by
clients when they set criticality to FALSE.
Sending dontUseCopy with FALSE is an error. RFC4511 says we should
return possibly outdated data in response. Receiving an error in
response to an error, instead of incorrect data because the control
was ignored, seems more appropriate. Not per se, but rather because
it brings less harm than it could by behaving according to RFC4511.
This is my 2c (well, reading back, it looks like more than just 2 :)