mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-27 03:20:22 +08:00
391 lines
16 KiB
XML
391 lines
16 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
|
|
<!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
|
|
<!ENTITY rfc822 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.0822.xml'>
|
|
<!ENTITY rfc2222 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2222.xml'>
|
|
<!ENTITY rfc2251 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2251.xml'>
|
|
<!ENTITY rfc2252 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2252.xml'>
|
|
<!ENTITY rfc2254 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2254.xml'>
|
|
<!ENTITY rfc2255 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2255.xml'>
|
|
<!ENTITY rfc3377 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3377.xml'>
|
|
<!ENTITY rfc3383 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3383.xml'>
|
|
|
|
]>
|
|
<?xml-stylesheet type='text/xsl' href='http://www.greenbytes.de/tech/webdav/rfc2629.xslt' ?>
|
|
<?rfc toc="yes" ?>
|
|
<?rfc tocdepth="2" ?>
|
|
<?rfc tocindent="no" ?>
|
|
<?rfc symrefs="yes" ?>
|
|
<?rfc sortrefs="yes"?>
|
|
<?rfc iprnotified="no" ?>
|
|
<?rfc strict="yes" ?>
|
|
<rfc ipr="full3978" docName="draft-chu-ldap-xordered-00.txt">
|
|
<front>
|
|
<title abbrev="LDAP Ordering Extension">Ordered Entries and Values in LDAP</title>
|
|
<author initials="H" fullname="Howard Chu" surname="Chu">
|
|
<organization>Symas Corp.</organization>
|
|
<address>
|
|
<postal>
|
|
<street>18740 Oxnard Street, Suite 313A</street>
|
|
<city>Tarzana</city>
|
|
<region>California</region>
|
|
<code>91356</code>
|
|
<country>USA</country>
|
|
</postal>
|
|
<phone>+1 818 757-7087</phone>
|
|
<email>hyc@symas.com</email>
|
|
</address>
|
|
</author>
|
|
<date year="2006" month="May"/>
|
|
<abstract>
|
|
<t>As LDAP is used more extensively for managing various
|
|
kinds of data, one often encounters a need to preserve both the
|
|
ordering and the content of data, despite the inherently unordered
|
|
structure of entries and attribute values in the directory. This
|
|
document describes a scheme to attach ordering information to
|
|
attributes in a directory so that the ordering may be
|
|
preserved and propagated to other LDAP applications.</t>
|
|
</abstract>
|
|
</front>
|
|
|
|
<middle>
|
|
|
|
<section title="Introduction">
|
|
<t>Information in LDAP directories is usually handled by
|
|
applications in the form of ordered lists, which tends to encourage
|
|
application developers to
|
|
assume they are maintained as such, i.e., it is assumed that information
|
|
stored in a particular order will always be retrieved and presented in
|
|
that same order. The fact that directory attributes actually store sets of
|
|
values, which are inherently unordered, often causes grief to users
|
|
migrating their data into LDAP. Similar concerns arise over the order
|
|
in which entries themselves are stored and retrieved from the directory.</t>
|
|
<t>This document describes a schema extension that may be
|
|
used in LDAP attribute definitions to store ordering information along
|
|
with the attribute values, so that the ordering can be recovered when
|
|
retrieved by an LDAP client. The extension also provides automated
|
|
management of this ordering information to ease manipulation of the
|
|
ordered values.</t>
|
|
</section>
|
|
|
|
<section title="Conventions">
|
|
<t>Imperative keywords defined in <xref target="RFC2119"/> are used
|
|
in this document, and carry the meanings described there.</t>
|
|
</section>
|
|
|
|
<section title="Ordering Extension">
|
|
<section title="Overview">
|
|
<t>The "X-ORDERED" schema extension is added to an
|
|
AttributeTypeDescription to signify the use of this ordering mechanism. The
|
|
extension has two variants, selected by either the 'VALUES' or 'SIBLINGS'
|
|
qdstrings. In general this extension is only compatible with AttributeTypes
|
|
that have a string-oriented syntax.</t>
|
|
<t>The "X-ORDERED 'VALUES'" extension is used with multi-valued
|
|
attributes to maintain the order of multiple values of a given attribute.
|
|
For example, this feature is useful for storing data such as access control
|
|
rules, which must be evaluated in a specific order. If the access control
|
|
information is stored in a multi-valued attribute without a means of
|
|
preserving the the order of the rules, the access control rules cannot be
|
|
evaluated properly. As the use of LDAP to store security policy and access
|
|
control information becomes more prevalent, the necessity of this feature
|
|
continues to grow.</t>
|
|
<t>
|
|
The "X-ORDERED 'SIBLINGS'" extension is used with single-valued attributes
|
|
to maintain the order of all the onelevel children of a parent entry. That is,
|
|
ordering will be maintained for all the child entries whose RDNs are all of
|
|
the same AttributeType. The motivation for this feature is much the same
|
|
as for the 'VALUES' feature. Sometimes the information with the ordering
|
|
dependency is too complex or highly structured to be conveniently stored
|
|
in values of a multi-valued attribute. For example, one could store a
|
|
prioritized list of servers as a set of separate entries, each entry
|
|
containing separate attributes for a URL, a set of authentication
|
|
credentials, and various other parameters. Using the 'SIBLINGS' feature
|
|
with the attribute in the entries' RDNs would ensure that when obtaining
|
|
the list of these entries, the list is returned in the intended order.
|
|
</t>
|
|
</section>
|
|
<section title="Encoding">
|
|
<t>Ordering information is encoded by prepending a value's ordinal
|
|
index to each value, enclosed in braces. The following BNF specifies the
|
|
encoding. It uses elements defined in <xref target="RFC2252"/>.
|
|
<list style="empty">
|
|
<t>d = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"</t>
|
|
<t>numericstring = 1*d</t>
|
|
<t>ordering-prefix = "{" numericstring "}"</t>
|
|
<t>value = <any sequence of octets></t>
|
|
<t>ordered-value = ordering-prefix value</t>
|
|
</list></t>
|
|
<t>The ordinals are zero-based and increment by one for each value.</t>
|
|
<t>Note that when storing ordered-values into the directory, the
|
|
ordering-prefix can usually be omitted as it will be generated automatically.
|
|
But if the original value already begins with a sequence of characters in
|
|
the form of an ordering-prefix, then an ordering-prefix must always be
|
|
provided with that value, otherwise the value will be processed and
|
|
stored incorrectly.</t>
|
|
<t>Using this extension on an attribute requires that ordering-prefix
|
|
is a legal value of the LDAP syntax of that attribute.</t>
|
|
</section>
|
|
<section title="Ordering Properties">
|
|
<t>Since the ordering-prefix is stored with the attribute values,
|
|
it will be propagated to any clients or servers that access the data.</t>
|
|
<t>Servers implementing this scheme SHOULD sort the values according
|
|
to their ordering-prefix before returning them in search results.</t>
|
|
<t>The presence of the ordering extension alters the matching rules
|
|
that apply to the attribute:
|
|
<list>
|
|
<t>When presented with an AssertionValue that does not have an
|
|
ordering-prefix, the ordering-prefix in the AttributeValue is ignored.</t>
|
|
<t>When presented with an AssertionValue that consists solely of an
|
|
ordering-prefix, only the ordering-prefix of the AttributeValue is compared;
|
|
the remainder of the value is ignored.</t>
|
|
<t>When presented with an AssertionValue containing both the
|
|
ordering-prefix and a value, both components are compared to determine a match.</t>
|
|
</list></t>
|
|
<t>A side effect of these properties is that even attributes that
|
|
normally would have no equality matching rule can be matched by an
|
|
ordering-prefix.</t>
|
|
<t>The ordering-prefix may also be used in Modification requests to
|
|
specify which values to delete, and in which position values should be added.
|
|
When processing deletions and insertions, all of the ordinals are recounted
|
|
after each individual modification.</t>
|
|
<t>If a value being added does not have
|
|
an ordering-prefix, it is simply appended to the list and the appropriate
|
|
ordering-prefix is automatically generated. Likewise if an ordering-prefix
|
|
is provided that is greater than or equal to the number of existing values.</t>
|
|
<t>See the examples in the next section.</t>
|
|
</section>
|
|
</section>
|
|
<section title="Examples">
|
|
<section title="Sample Schema">
|
|
<t>This schema is used for all of the examples:</t>
|
|
<t>( EXAMPLE_AT.1 NAME 'olcDatabase'<vspace/>
|
|
EQUALITY caseIgnoreMatch<vspace/>
|
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15<vspace/>
|
|
SINGLE-VALUE X-ORDERED 'SIBLINGS' )</t>
|
|
<t>( EXAMPLE_AT.2 NAME 'olcSuffix'<vspace/>
|
|
EQUALITY distinguishedNameMatch<vspace/>
|
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12<vspace/>
|
|
X-ORDERED 'VALUES' )</t>
|
|
<t>( EXAMPLE_OC.1 NAME 'olcDatabaseConfig' <vspace/>
|
|
SUP top STRUCTURAL<vspace/>
|
|
MAY ( olcDatabase $ olcSuffix ) )</t>
|
|
</section>
|
|
<section title="Ordered Values">
|
|
<t>Given this entry:</t>
|
|
<t>dn: olcDatabase={1}bdb,cn=config<vspace/>
|
|
olcDatabase: {1}bdb<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}dc=example,dc=com<vspace/>
|
|
olcSuffix: {1}o=example.com<vspace/>
|
|
olcSuffix: {2}o=The Example Company<vspace/>
|
|
olcSuffix: {3}o=example,c=us</t>
|
|
|
|
<t>We can perform these Modify operations:
|
|
<list style="numbers">
|
|
|
|
<t>dn: olcDatabase={1}bdb,cn=config<vspace/>
|
|
changetype: modify<vspace/>
|
|
delete: olcSuffix<vspace/>
|
|
olcSuffix: {0}<vspace/>
|
|
-<vspace/>
|
|
This operation deletes the first olcSuffix, regardless of its
|
|
value. All other values are bumped up one position. The olcSuffix
|
|
attribute will end up containing:<vspace/>
|
|
olcSuffix: {0}o=example.com<vspace/>
|
|
olcSuffix: {1}o=The Example Company<vspace/>
|
|
olcSuffix: {2}o=example,c=us</t>
|
|
|
|
<t>Starting from the original entry, we could issue this change
|
|
instead:<vspace/>
|
|
delete: olcSuffix<vspace/>
|
|
olcSuffix: o=example.com<vspace/>
|
|
-<vspace/>
|
|
This operation deletes the olcSuffix that matches the value,
|
|
regardless of its ordering-prefix. The olcSuffix attribute will contain:<vspace/>
|
|
olcSuffix: {0}dc=example,dc=com<vspace/>
|
|
olcSuffix: {1}o=The Example Company<vspace/>
|
|
olcSuffix: {2}o=example,c=us</t>
|
|
|
|
<t>Again, starting from the original entry, we could issue this
|
|
change:<vspace/>
|
|
delete: olcSuffix<vspace/>
|
|
olcSuffix: {2}o=The Example Company<vspace/>
|
|
-<vspace/>
|
|
Here both the ordering-prefix and the value must match, otherwise
|
|
the Modify would fail with noSuchAttribute. In this case the
|
|
olcSuffix attribute results in:<vspace/>
|
|
olcSuffix: {0}dc=example,dc=com<vspace/>
|
|
olcSuffix: {1}o=example.com<vspace/>
|
|
olcSuffix: {2}o=example,c=us</t>
|
|
|
|
<t>Adding a new value without an ordering-prefix simply appends:<vspace/>
|
|
add: olcSuffix<vspace/>
|
|
olcSuffix: o=example.org<vspace/>
|
|
-<vspace/>
|
|
The resulting attribute would be:<vspace/>
|
|
olcSuffix: {0}dc=example,dc=com<vspace/>
|
|
olcSuffix: {1}o=example.com<vspace/>
|
|
olcSuffix: {2}o=The Example Company<vspace/>
|
|
olcSuffix: {3}o=example,c=us<vspace/>
|
|
olcSuffix: {4}o=example.org</t>
|
|
|
|
<t>Adding a new value with an ordering-prefix inserts into the
|
|
specified position:<vspace/>
|
|
add: olcSuffix<vspace/>
|
|
olcSuffix: {0}o=example.org<vspace/>
|
|
-<vspace/>
|
|
The resulting attribute would be:<vspace/>
|
|
olcSuffix: {0}o=example.org<vspace/>
|
|
olcSuffix: {1}dc=example,dc=com<vspace/>
|
|
olcSuffix: {2}o=example.com<vspace/>
|
|
olcSuffix: {3}o=The Example Company<vspace/>
|
|
olcSuffix: {4}o=example,c=us</t>
|
|
|
|
<t>Modifying multiple values in one operation:<vspace/>
|
|
add: olcSuffix<vspace/>
|
|
olcSuffix: {0}ou=Dis,o=example.com<vspace/>
|
|
olcSuffix: {0}ou=Dat,o=example,com<vspace/>
|
|
-<vspace/>
|
|
delete: olcSuffix:<vspace/>
|
|
olcSuffix: {2}<vspace/>
|
|
olcSuffix: {1}<vspace/>
|
|
-<vspace/>
|
|
The resulting attribute would be:<vspace/>
|
|
olcSuffix: {0}ou=Dat,o=example,com<vspace/>
|
|
olcSuffix: {1}dc=example,dc=com<vspace/>
|
|
olcSuffix: {2}o=example.com<vspace/>
|
|
olcSuffix: {3}o=The Example Company<vspace/>
|
|
olcSuffix: {4}o=example,c=us</t>
|
|
|
|
<t>If the Adds and Deletes in the previous example were done
|
|
in the opposite order:<vspace/>
|
|
delete: olcSuffix:<vspace/>
|
|
olcSuffix: {2}<vspace/>
|
|
olcSuffix: {1}<vspace/>
|
|
-<vspace/>
|
|
add: olcSuffix<vspace/>
|
|
olcSuffix: {0}ou=Dis,o=example.com<vspace/>
|
|
olcSuffix: {0}ou=Dat,o=example,com<vspace/>
|
|
-<vspace/>
|
|
The result would be:<vspace/>
|
|
olcSuffix: {0}ou=Dat,o=example,com<vspace/>
|
|
olcSuffix: {1}ou=Dis,o=example.com<vspace/>
|
|
olcSuffix: {2}o=example.org<vspace/>
|
|
olcSuffix: {3}o=The Example Company<vspace/>
|
|
olcSuffix: {4}o=example,c=us</t>
|
|
</list>
|
|
|
|
</t>
|
|
<t>Note that matching against an ordering-prefix can also
|
|
be done in Compare operations and Search filters. E.g.,
|
|
the filter "(olcSuffix={4})" would match all entries with
|
|
at least 5 olcSuffix values.</t>
|
|
</section>
|
|
<section title="Ordered Siblings">
|
|
<t>The rules for Ordered Siblings are basically the same
|
|
as for Ordered Values, except instead of working primarily with the Modify
|
|
request, the operations of interest here are Add, Delete, and ModRDN.</t>
|
|
<t>Given these entries:</t>
|
|
<t>dn: olcDatabase={0}config,cn=config<vspace/>
|
|
olcDatabase: {0}config<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}cn=config</t>
|
|
|
|
<t>dn: olcDatabase={1}bdb,cn=config<vspace/>
|
|
olcDatabase: {1}bdb<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}dc=example,dc=com</t>
|
|
|
|
<t>We can perform these operations:
|
|
<list style="numbers">
|
|
<t>Add a new entry with no ordering-prefix:<vspace/>
|
|
dn: olcDatabase=hdb,cn=config<vspace/>
|
|
changetype: add<vspace/>
|
|
olcDatabase: hdb<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}dc=example,dc=org<vspace/>
|
|
The resulting entry will be:<vspace/>
|
|
dn: olcDatabase={2}hdb,cn=config<vspace/>
|
|
olcDatabase: {2}hdb<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}dc=example,dc=org</t>
|
|
|
|
<t>Continuing on with these three entries, we can add another
|
|
entry with a specific ordering-prefix:<vspace/>
|
|
dn: olcDatabase={1}ldif,cn=config<vspace/>
|
|
changetype: add<vspace/>
|
|
olcDatabase: {1}ldif<vspace/>
|
|
objectClass: olcDatabaseConfig<vspace/>
|
|
olcSuffix: {0}o=example.com<vspace/>
|
|
<vspace/>This would give us four entries, whose DNs are:
|
|
<list style="empty">
|
|
<t>dn: olcDatabase={0}config,cn=config</t>
|
|
<t>dn: olcDatabase={1}ldif,cn=config</t>
|
|
<t>dn: olcDatabase={2}bdb,cn=config</t>
|
|
<t>dn: olcDatabase={3}hdb,cn=config</t>
|
|
</list>
|
|
</t>
|
|
|
|
<t>Issuing a ModRDN request will cause multiple entries to
|
|
be renamed:<vspace/>
|
|
dn: olcDatabase={1}ldif,cn=config<vspace/>
|
|
changetype: modrdn<vspace/>
|
|
newrdn: olcDatabase={99}ldif<vspace/>
|
|
deleteoldrdn: 1<vspace/>
|
|
<vspace/>The resulting entries would be named:
|
|
<list style="empty">
|
|
<t>dn: olcDatabase={0}config,cn=config</t>
|
|
<t>dn: olcDatabase={1}bdb,cn=config</t>
|
|
<t>dn: olcDatabase={2}hdb,cn=config</t>
|
|
<t>dn: olcDatabase={3}ldif,cn=config</t>
|
|
</list>
|
|
</t>
|
|
|
|
<t>As may be expected, a Delete request will also rename the
|
|
remaining entries:<vspace/>
|
|
dn: olcDatabase={1}bdb,cn=config<vspace/>
|
|
changetype: delete<vspace/>
|
|
<vspace/>The remaining entries would be named:
|
|
<list style="empty">
|
|
<t>dn: olcDatabase={0}config,cn=config</t>
|
|
<t>dn: olcDatabase={1}hdb,cn=config</t>
|
|
<t>dn: olcDatabase={2}ldif,cn=config</t>
|
|
</list>
|
|
</t>
|
|
</list>
|
|
</t>
|
|
</section>
|
|
|
|
</section>
|
|
<section title="Security Considerations">
|
|
<t>General LDAP security considerations <xref target="RFC3377"/>
|
|
apply.</t>
|
|
</section>
|
|
</middle>
|
|
|
|
<back>
|
|
<references title="Normative References">
|
|
&rfc2119;
|
|
&rfc2252;
|
|
&rfc3377;
|
|
&rfc3383;
|
|
<reference anchor="X680">
|
|
<front>
|
|
<title>Abstract Syntax Notation One (ASN.1): Specification of basic notation</title>
|
|
<author>
|
|
<organization>International Telecommunications Union</organization>
|
|
</author>
|
|
<date month="July" year="2002"/>
|
|
</front>
|
|
<seriesInfo name="ITU-T" value="Recommendation X.680"/>
|
|
</reference>
|
|
</references>
|
|
|
|
<section title="IANA Considerations">
|
|
<t>In accordance with <xref target="RFC3383"/> (what needs to be done here?) . We probably need an OID for advertising in supportedFeatures.
|
|
</t>
|
|
|
|
</section>
|
|
</back>
|
|
</rfc>
|