Howard,
this is where I got so far with the specification (and the code :)
/* * request: * * controlValue ::= SEQUENCE OF DerefSpec * * DerefSpec ::= SEQUENCE { * derefAttr AttributeDescription, * attributes AttributeList } * * AttributeList ::= SEQUENCE OF attr AttributeDescription * * * response: * * controlValue ::= SEQUENCE OF DerefRes * * DerefRes ::= SEQUENCE { * spec DerefSpec, * vals DerefVals } * * DerefVals ::= SEQUENCE OF DerefVal * * DerefVal ::= SEQUENCE { * derefSpecVal AttributeValue, * attrSets AttrSets } * * AttrSets ::= SEQUENCE of attrSet AttributeValues * * AttributeValues ::= SET OF value AttributeValue * * * example request: * * { { member, { GUID, SID } }, { memberOf, { GUID, SID } } } * * example response: * * { { { memberOf, { GUID, SID } }, * { { "cn=abartlet,cn=users,dc=abartlet,dc=net", * { { "0bc11d00-e431-40a0-8767-344a320142fa" }, * { "S-1-2-3-2345" } } }, * { "cn=ando,cn=users,dc=sys-net,dc=it", * { { "0bc11d00-e431-40a0-8767-344a320142fb" }, * { "S-1-2-3-2346" } } } } } } */
I designed the response this way, because it'd allow to make it as compact as possible while allowing for multiple as well as missing attribute values in each attrSet. However I'm facing two issues, which I can't solve directly since I don't have X.690 handy right now:
- does BER allow to have an empty set/sequence? Apparently, I'm unable to set an empty set using ber_printf("[]").
- does it make sense to have a structured response like this, where the attribute types are listed first, and aggregate values follow, so that the order of the value sets (including empty sets, if allowed) matches the order of the attributes? I mean:
{ member, { cn, uid, drink } }
is supposed to match
{ "cn=Ando,dc=sys-net,dc=it", { [ "Ando", "Pierangelo Masarati" ], [ "ando" ], [] } }
such that set #0 ([ "Ando", "Pierangelo Masarati" ]) refers to attr #0 (cn), set #1 ([ "ando" ]) refers to attr #1 (uid), and set #2 ([]) refers to attr #2 (drink).
In fact, one could argue that the order in attrSets needs not necessarily be the same of the attributes in spec. This would require to use an alternative definition like
/* * response: * * controlValue ::= SEQUENCE OF DerefRes * * DerefRes ::= SEQUENCE { * derefAttrVal DerefAttrVal, * attrsVals SEQUENCE OF attrVals DerefAttrsVals } * * DerefAttrVal ::= SEQUENCE { * attr AttributeDescription, * val AttributeValue } * * DerefAttrVals ::= SEQUENCE { * attr AttributeDescription, * vals SET OF val AttributeValue } */
which implies a repetition of all the attribute descriptions for each derefAttrVal. Comments?
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ----------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Fax: +39 0382 476497 Email: ando@sys-net.it -----------------------------------
Pierangelo Masarati wrote:
Howard,
this is where I got so far with the specification (and the code :)
That's good progress. You said you'd start this weekend, so you're ahead of schedule. ;)
/*
- request:
- controlValue ::= SEQUENCE OF DerefSpec
- DerefSpec ::= SEQUENCE {
derefAttr AttributeDescription,
attributes AttributeList }
- AttributeList ::= SEQUENCE OF attr AttributeDescription
- response:
- controlValue ::= SEQUENCE OF DerefRes
- DerefRes ::= SEQUENCE {
spec DerefSpec,
vals DerefVals }
- DerefVals ::= SEQUENCE OF DerefVal
- DerefVal ::= SEQUENCE {
derefSpecVal AttributeValue,
attrSets AttrSets }
- AttrSets ::= SEQUENCE of attrSet AttributeValues
- AttributeValues ::= SET OF value AttributeValue
- example request:
- { { member, { GUID, SID } }, { memberOf, { GUID, SID } } }
- example response:
- { { { memberOf, { GUID, SID } },
{ { "cn=abartlet,cn=users,dc=abartlet,dc=net",
{ { "0bc11d00-e431-40a0-8767-344a320142fa" },
{ "S-1-2-3-2345" } } },
{ "cn=ando,cn=users,dc=sys-net,dc=it",
{ { "0bc11d00-e431-40a0-8767-344a320142fb" },
{ "S-1-2-3-2346" } } } } } }
*/
I designed the response this way, because it'd allow to make it as compact as possible while allowing for multiple as well as missing attribute values in each attrSet. However I'm facing two issues, which I can't solve directly since I don't have X.690 handy right now:
- does BER allow to have an empty set/sequence? Apparently, I'm unable
to set an empty set using ber_printf("[]").
I think we should avoid that, but I'll look it up later.
- does it make sense to have a structured response like this, where the
attribute types are listed first, and aggregate values follow, so that the order of the value sets (including empty sets, if allowed) matches the order of the attributes? I mean:
{ member, { cn, uid, drink } }
is supposed to match
{ "cn=Ando,dc=sys-net,dc=it", { [ "Ando", "Pierangelo Masarati" ], [ "ando" ], [] } }
such that set #0 ([ "Ando", "Pierangelo Masarati" ]) refers to attr #0 (cn), set #1 ([ "ando" ]) refers to attr #1 (uid), and set #2 ([]) refers to attr #2 (drink).
In fact, one could argue that the order in attrSets needs not necessarily be the same of the attributes in spec. This would require to use an alternative definition like
/*
- response:
- controlValue ::= SEQUENCE OF DerefRes
- DerefRes ::= SEQUENCE {
derefAttrVal DerefAttrVal,
attrsVals SEQUENCE OF attrVals DerefAttrsVals }
- DerefAttrVal ::= SEQUENCE {
attr AttributeDescription,
val AttributeValue }
- DerefAttrVals ::= SEQUENCE {
attr AttributeDescription,
vals SET OF val AttributeValue }
*/
which implies a repetition of all the attribute descriptions for each derefAttrVal. Comments?
I theink DerefResponse should just be DerefRes ::= SEQUENCE of Attribute
(See RFC4511 for Attribute)
I.e., there doesn't need to be a lot of structure here, and repeating the AttributeDescription is fine. And we can ignore the issue of empty sets by just not returning them if there's no corresponding value. (Same as a search entry response, really.(
I have some question in my mind about whether we should accommodate returning multivalued attrs in the response. I guess there's no reason not to, for the general case. For the Samba use case it obviously won't make a difference.
Howard Chu wrote:
Pierangelo Masarati wrote:
Howard,
this is where I got so far with the specification (and the code :)
That's good progress. You said you'd start this weekend, so you're ahead of schedule. ;)
That's because usually I only spare time in the we :)
which implies a repetition of all the attribute descriptions for each derefAttrVal. Comments?
I theink DerefResponse should just be DerefRes ::= SEQUENCE of Attribute
(See RFC4511 for Attribute)
I.e., there doesn't need to be a lot of structure here, and repeating the AttributeDescription is fine. And we can ignore the issue of empty sets by just not returning them if there's no corresponding value. (Same as a search entry response, really.(
OK, allowing for repetitions definitely simplifies things, possibly at the cost of bandwidth, and eliminates the need for empty sets.
I have some question in my mind about whether we should accommodate returning multivalued attrs in the response. I guess there's no reason not to, for the general case.
I'd go general, and simplify later, to avoid having to modify the specs later.
For the Samba use case it obviously won't make a difference.
Agreed. p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ----------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Fax: +39 0382 476497 Email: ando@sys-net.it -----------------------------------
Pierangelo Masarati writes:
- does BER allow to have an empty set/sequence?
Yes.
Apparently, I'm unable to set an empty set using ber_printf("[]").
You could look at the OpenLDAP code for RFC 4511's PartialAttribute.vals - can be an empty SET OF AttributeValue. SearchRequest.attributes - can be an empty SEQUENCE OF LDAPString. (No opinion on whether that's better than making it OPTIONAL or something, I haven't looked at what this is about yet.)
Hallvard B Furuseth wrote:
Pierangelo Masarati writes:
- does BER allow to have an empty set/sequence?
Yes.
Apparently, I'm unable to set an empty set using ber_printf("[]").
You could look at the OpenLDAP code for RFC 4511's PartialAttribute.vals - can be an empty SET OF AttributeValue. SearchRequest.attributes - can be an empty SEQUENCE OF LDAPString. (No opinion on whether that's better than making it OPTIONAL or something, I haven't looked at what this is about yet.)
That's what I've done so far. The current specification I'm delineating is:
/* * 1. Specification * * 1.1 Request * * controlValue ::= SEQUENCE OF DerefSpec * * DerefSpec ::= SEQUENCE { * derefAttr attributeDescription, ; DN-valued * attributes AttributeList } * * AttributeList ::= SEQUENCE OF attr AttributeDescription * * * 1.2 Response * * controlValue ::= SEQUENCE OF DerefRes * * From RFC 4511: * PartialAttribute ::= SEQUENCE { * type AttributeDescription, * vals SET OF value AttributeValue } * * PartialAttributeList ::= SEQUENCE OF * partialAttribute PartialAttribute * * DerefRes ::= SEQUENCE { * derefAttr AttributeDescription, * derefVal LDAPDN, * attrVals PartialAttributeList * * 2. Examples * * 2.1 Example * * 2.1.1 Request * * { { member, { GUID, SID } }, { memberOf, { GUID, SID } } } * * 2.1.2 Response * * { { memberOf, "cn=abartlet,cn=users,dc=abartlet,dc=net", * { GUID, [ "0bc11d00-e431-40a0-8767-344a320142fa" ], * SID, [ "S-1-2-3-2345" ] } }, * { memberOf, "cn=ando,cn=users,dc=sys-net,dc=it", * { GUID, [ "0bc11d00-e431-40a0-8767-344a320142fb" ], * SID, [ "S-1-2-3-2346" ] } } } * * 2.2 Example * * 2.2.1 Request * * { { member, { cn, uid, drink } } } * * 2.2.2 Response * * { { member, "cn=ando,cn=users,dc=sys-net,dc=it", * { cn, [ "ando", "Pierangelo Masarati" ], * uid, [ "ando" ] } } } */
Right now, the implementation only looks for exact attribute descriptions; probably, we should consider the possibility to:
- honor inheritance both in derefAttr & type
- allow objectClasses as shortcuts for attribute sets in attributes
but I don't want to complicate things too much right now.
This brings me to consider the possibility to selectively stop honoring inheritance in otherwise regular operations. I was initially thinking of something like a special language tag option ("x-nosubs"), but this would probably violate RFC 3688 in many places. So I'm more inclined towards a control that lists what attributes and objectClasses in a request (search and compare requests, by now) should not honor inheritance, possibly using separate sets for filtering and requested/asserted attributes. I'll probably post a separate message for this food for thoughts...
I have another issue in mind: given the above specification, if the same derefAttr appears in more than one DerefSpec, one could hardly tell which DerefSpec one DerefRes belongs to. For example:
request: { { member { cn, sn } }, { member { uid } } } response: { { member, "cn=ando" }, { member, "cn=ando" } }
because the client's identity had read access to entryDN but not to cn, sn, uid attrs, we'd have a duplicate result. Of course, this could have been much better formulated as
request: { { member { cn, sn, uid } } } response: { { member, "cn=ando" } }
for this reason I'm inclined towards requesting that each derefAttr in a sequence of DerefSpec to be unique.
I'll complete the client side library and commit things shortly, definitely by next week.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ----------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Fax: +39 0382 476497 Email: ando@sys-net.it -----------------------------------
Pierangelo Masarati wrote:
I have another issue in mind: given the above specification, if the same derefAttr appears in more than one DerefSpec, one could hardly tell which DerefSpec one DerefRes belongs to. For example:
request: { { member { cn, sn } }, { member { uid } } } response: { { member, "cn=ando" }, { member, "cn=ando" } }
because the client's identity had read access to entryDN but not to cn, sn, uid attrs, we'd have a duplicate result. Of course, this could have been much better formulated as
request: { { member { cn, sn, uid } } } response: { { member, "cn=ando" } }
for this reason I'm inclined towards requesting that each derefAttr in a sequence of DerefSpec to be unique.
Yes, that should be a requirement.