RFC 3928
Lightweight Directory Access Protocol (LDAP) Client Update Protocol (LCUP)
RFC 3928: Lightweight Directory Access Protocol (LDAP) Client Update Protocol (LCUP) ๐
(part 1 of 6 ๐)
okay bestie, RFC 3928 is a Standards Track doc from the IETF Network Working Group, dated October 2004 โจ. The first author is R. Megginson, Ed. (Netscape Communications Corp.), and the others are M. Smith (Pearl Crescent, LLC), O. Natkovich (Yahoo), and J. Parham (Microsoft Corporation) ๐. The title block doesn't list any RFCs that it obsoletes or updates, so it's standing on its own ๐ฆ. The whole thing is about the Lightweight Directory Access Protocol (LDAP) Client Update Protocol, which everyone calls LCUP ๐ .
Status of this Memo โจ
This document is an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements ๐ซถ. If you want the standardization state and status, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. Distribution of this memo is unlimited ๐.
Copyright Notice ๐
Copyright (C) The Internet Society (2004).
Abstract ๐ฆ
This document defines the Lightweight Directory Access Protocol (LDAP) Client Update Protocol (LCUP). The protocol lets an LDAP client sync up with the content of a directory information tree (DIT) that's stored by an LDAP server, and it lets the client get notified about changes to that content ๐ง.
Table of Contents ๐
1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Applicability. . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Specification of Protocol Elements . . . . . . . . . . . . . . 5
3.1. ASN.1 Considerations . . . . . . . . . . . . . . . . . . 5
3.2. Universally Unique Identifiers . . . . . . . . . . . . . 5
3.3. LCUP Scheme and LCUP Cookie. . . . . . . . . . . . . . . 5
3.4. LCUP Context . . . . . . . . . . . . . . . . . . . . . . 6
3.5. Additional LDAP Result Codes defined by LCUP . . . . . . 6
3.6. Sync Request Control . . . . . . . . . . . . . . . . . . 7
3.7. Sync Update Control. . . . . . . . . . . . . . . . . . . 7
3.8. Sync Done Control. . . . . . . . . . . . . . . . . . . . 8
4. Protocol Usage and Flow. . . . . . . . . . . . . . . . . . . . 8
4.1. LCUP Search Requests . . . . . . . . . . . . . . . . . . 8
4.1.1. Initial Synchronization and Full Resync . . . . . 9
4.1.2. Incremental or Update Synchronization . . . . . . 10
4.1.3. Persistent Only . . . . . . . . . . . . . . . . . 10
4.2. LCUP Search Responses. . . . . . . . . . . . . . . . . . 10
4.2.1. Sync Update Informational Responses . . . . . . . 11
4.2.2. Cookie Return Frequency . . . . . . . . . . . . . 11
4.2.3. Definition of an Entry That Has Entered the
Result Set. . . . . . . . . . . . . . . . . . . . 12
4.2.4. Definition of an Entry That Has Changed . . . . . 13
4.2.5. Definition of an Entry That Has Left the
Result Set. . . . . . . . . . . . . . . . . . . . 13
4.2.6. Results For Entries Present in the Result Set . . 14
4.2.7. Results For Entries That Have Left the Result
Set . . . . . . . . . . . . . . . . . . . . . . . 14
4.3. Responses Requiring Special Consideration . . . . . . . . 15
4.3.1. Returning Results During the Persistent Phase . . 15
4.3.2. No Mixing of Sync Phase with Persist Phase. . . . 16
4.3.3. Returning Updated Results During the Sync Phase . 16
4.3.4. Operational Attributes and Administrative
Entries . . . . . . . . . . . . . . . . . . . . . 16
4.3.5. Virtual Attributes. . . . . . . . . . . . . . . . 17
4.3.6. Modify DN and Delete Operations Applied to
Subtrees. . . . . . . . . . . . . . . . . . . . . 17
4.3.7. Convergence Guarantees. . . . . . . . . . . . . . 18
4.4. LCUP Search Termination. . . . . . . . . . . . . . . . . 18
4.4.1. Server Initiated Termination. . . . . . . . . . . 18
4.4.2. Client Initiated Termination. . . . . . . . . . . 19
4.5. Size and Time Limits . . . . . . . . . . . . . . . . . . 19
4.6. Operations on the Same Connection. . . . . . . . . . . . 19
4.7. Interactions with Other Controls . . . . . . . . . . . . 19
4.8. Replication Considerations . . . . . . . . . . . . . . . 20
5. Client Side Considerations . . . . . . . . . . . . . . . . . . 20
5.1. Using Cookies with Different Search Criteria . . . . . . 20
5.2. Renaming the Base Object . . . . . . . . . . . . . . . . 20
5.3. Use of Persistent Searches With Respect to Resources . . 21
5.4. Continuation References to Other LCUP Contexts . . . . . 21
5.5. Referral Handling. . . . . . . . . . . . . . . . . . . . 21
5.6. Multiple Copies of Same Entry During Sync Phase. . . . . 21
5.7. Handling Server Out of Resources Condition . . . . . . . 21
6. Server Implementation Considerations . . . . . . . . . . . . . 22
6.1. Server Support for UUIDs . . . . . . . . . . . . . . . . 22
6.2. Example of Using an RUV as the Cookie Value. . . . . . . 22
6.3. Cookie Support Issues. . . . . . . . . . . . . . . . . . 22
6.3.1. Support for Multiple Cookie Schemes . . . . . . . 22
6.3.2. Information Contained in the Cookie . . . . . . . 23
6.4. Persist Phase Response Time. . . . . . . . . . . . . . . 23
6.5. Scaling Considerations . . . . . . . . . . . . . . . . . 23
6.6. Alias Dereferencing. . . . . . . . . . . . . . . . . . . 24
7. Synchronizing Heterogeneous Data Stores. . . . . . . . . . . . 24
8. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 24
9. Security Considerations. . . . . . . . . . . . . . . . . . . . 24
10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 25
10.1. Normative References . . . . . . . . . . . . . . . . . . 25
10.2. Informative References . . . . . . . . . . . . . . . . . 26
11. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 26
Appendix - Features Left Out of LCUP . . . . . . . . . . . . . . . 27
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 29
Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 30
1. Overview ๐
okay so the LCUP protocol is meant to let LDAP clients synchronize with the content that LDAP servers store ๐.
The problem areas it tackles include:
- Mobile clients that keep a local read-only copy of the directory data ๐ฑ. While they're off-line, they use that local copy. When they connect to the network, they sync with the current directory content, and they can optionally get notified about changes that happen while they're online ๐. Think of a mail client keeping a local copy of the corporate address book, syncing with the master copy whenever it's connected to the corporate network ๐.
- Apps that sync heterogeneous data stores ๐๏ธ. A meta directory application, for example, would periodically pull a list of modified entries from the directory, build the changes, and apply them to a foreign data store ๐.
- Clients that need to take action when a directory entry changes ๐ฌ. For example, an electronic mail repository might want to do a "create mailbox" task when a new person entry is added to an LDAP directory, and a "delete mailbox" task when a person entry is removed ๐ฌ.
The problem areas that are not being considered:
- Directory server to directory server sync ๐ . The IETF is working on an LDAP replication protocol called LDUP [RFC3384], which is designed specifically for this problem area ๐ ๏ธ.
There are already several protocols in use for LDAP client-server sync ๐คท. Each one meets the needs of a certain group of clients (like on-line clients or off-line clients), but none of them satisfies the requirements of every client in that group. For instance, a mobile client that was off-line and wants to get up to date with the server, then stay up to date while connected, can't be easily supported by any of the existing protocols ๐ฉ.
LCUP is designed so the server doesn't need to keep state information specific to individual clients ๐ง . The server may need to keep extra state about attribute modifications, deleted entries, and moved or renamed entries. The clients are responsible for storing info about how up to date they are with the server's content ๐. LCUP's design avoids the need for LCUP-specific update agreements between client and server before LCUP is used ๐. The client decides when and from where to get the changes. LCUP requires clients to start the update session and "pull" the changes from the server ๐ซธ.
LCUP operations are subject to administrative and access control policies enforced by the server. ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [RFC2119].
2. Applicability ๐ฏ
LCUP works best when these conditions are met:
- The server stores some degree of historical state or change information, which cuts down the amount of wire traffic needed for incremental synchronizations ๐. The best balance between server state and wire traffic varies between implementations and usage scenarios, so it's left up to implementers ๐งโ๐ป.
- The client can't be assumed to understand the physical information model (virtual attributes, operational attributes, subentries, etc.) that the server implements ๐. Optimizations would be possible if those assumptions could be made ๐ก.
- Metadata changes, renames, and deletions of large subtrees are very infrequent ๐. LCUP makes these assumptions to reduce the client complexity needed to deal with these special operations. Even so, when they do happen, they may result in a large number of incremental update messages or a full resync ๐ญ.
3. Specification of Protocol Elements ๐งฉ
The following sections define the new elements required to use this protocol ๐.
3.1. ASN.1 Considerations ๐ธ
Protocol elements are described using ASN.1 [X.680]. The term "BER-encoded" means the element is to be encoded using the Basic Encoding Rules [X.690] under the restrictions detailed in Section 5.1 of [RFC2251]. All ASN.1 in this document uses implicit tags ๐.
3.2. Universally Unique Identifiers ๐ฆ
okay so distinguished names can change, which makes them lowkey unreliable as identifiers ๐ so LCUP needs something that stays put. enter the Universally Unique Identifier (UUID for short), which MUST be used to uniquely identify entries used with LCUP โจ the UUID rides along inside the Sync Update control value (more on that below) that comes back with each search result ๐
the server SHOULD provide the UUID as a single valued operational attribute of the entry, like "entryUUID" ๐ we RECOMMEND that the server gives you a way to do efficient (i.e., indexed) searches on UUID values, so you can use a search filter like (entryUUID=<some UUID value>) and grab an entry by its UUID super fast ๐โโ๏ธ servers SHOULD use a UUID format as specified in [UUID]. the UUID used by LCUP is a value of the following ASN.1 type:
LCUPUUID ::= OCTET STRING
3.3. LCUP Scheme and LCUP Cookie ๐
so LCUP uses a cookie to hold the state of the client's data with respect to the server's data ๐ง each cookie format is uniquely identified by its scheme. the LCUP Scheme is a value of the following ASN.1 type:
LCUPScheme ::= LDAPOID
this is the OID that identifies the format of the LCUP Cookie value. the scheme OID, like all object identifiers, MUST be unique for a given cookie scheme ๐ฅ the cookie value may be opaque, or it may be exposed to LCUP clients. for cookie schemes that expose their value, the preferred form of documentation is an RFC. it is expected that there will be one or more standards track cookie schemes where the value format is exposed and described in detail ๐
the LCUP Cookie is a value of the following ASN.1 type:
LCUPCookie ::= OCTET STRING
this is the actual data describing the state of the client's data. this value may be opaque, or its value may have some well-known format, depending on the scheme ๐
further uses of the LCUP Cookie value are described below.
3.4. LCUP Context ๐ธ
a part of the DIT that is enabled for LCUP is called an LCUP Context โจ a server can support one or more LCUP Contexts. for example, a server with two naming contexts might support LCUP in one naming context but not the other, or support different LCUP cookie schemes in each naming context ๐ each LCUP Context MAY use a different cookie scheme.
here's the tea: an LCUP search will not cross an LCUP Context boundary ๐ instead, it returns a SearchResultReference message, with the LDAP URL specifying the same host and port as currently being searched, and with the baseDN set to the baseDN of the new LCUP Context. the client is then responsible for issuing another search using the new baseDN, and possibly a different cookie if that LCUP Context uses a different cookie. the client is also responsible for maintaining a mapping of the LDAP URL to its corresponding cookie ๐ซถ
3.5. Additional LDAP Result Codes defined by LCUP ๐
implementations of this specification SHALL recognize the following additional resultCode values ๐ญ the LDAP result code names and numbers in the table below were assigned by IANA per RFC 3383 [RFC3383].
lcupResourcesExhausted (113) the server is running out of resources
lcupSecurityViolation (114) the client is suspected of malicious
actions
lcupInvalidData (115) invalid scheme or cookie was supplied
by the client
lcupUnsupportedScheme (116) The cookie scheme is a valid OID but
is not supported by this server
lcupReloadRequired (117) indicates that client data needs to be
reinitialized. This reason is
returned if the server does not
contain sufficient information to
synchronize the client or if the
server's data was reloaded since the
last synchronization session
the uses of these codes are described below. โจ
3.6. Sync Request Control ๐
the Sync Request Control is an LDAP Control [RFC2251, Section 4.1.2] where the controlType is the object identifier 1.3.6.1.1.7.1 and the controlValue, an OCTET STRING, contains a BER-encoded syncRequestControlValue ๐ฆ
syncRequestControlValue ::= SEQUENCE {
updateType ENUMERATED {
syncOnly (0),
syncAndPersist (1),
persistOnly (2) },
sendCookieInterval [0] INTEGER OPTIONAL,
scheme [1] LCUPScheme OPTIONAL,
cookie [2] LCUPCookie OPTIONAL
}
sendCookieInterval: the server SHOULD send the cookie back in the Sync Update control value (defined below) for every sendCookieInterval number of SearchResultEntry and SearchResultReference PDUs returned to the client ๐ for example, if the value is 5, the server SHOULD send the cookie back in the Sync Update control value for every 5 search results returned to the client. if this value is absent, zero or less than zero, the server chooses the interval ๐ง
the Sync Request Control is only applicable to the searchRequest message. the way to use this control is described below. ๐
3.7. Sync Update Control ๐
the Sync Update Control is an LDAP Control [RFC2251, Section 4.1.2] where the controlType is the object identifier 1.3.6.1.1.7.2 and the controlValue, an OCTET STRING, contains a BER-encoded syncUpdateControlValue ๐ง
syncUpdateControlValue ::= SEQUENCE {
stateUpdate BOOLEAN,
entryUUID [0] LCUPUUID OPTIONAL, -- REQUIRED for entries --
UUIDAttribute [1] AttributeType OPTIONAL,
entryLeftSet [2] BOOLEAN,
persistPhase [3] BOOLEAN,
scheme [4] LCUPScheme OPTIONAL,
cookie [5] LCUPCookie OPTIONAL
}
the field UUIDAttribute contains the name or OID of the attribute that the client should use to search for entries based on the UUID ๐ the client should be able to use it in an equality search filter, e.g., "(<uuid attribute>=<entry UUID value>)", and should be able to use it in the attribute list of the search request to return its value. the UUIDAttribute field may be omitted if the server does not support searching on UUID values ๐
the Sync Update Control is only applicable to SearchResultEntry and SearchResultReference messages. although entryUUID is OPTIONAL, it MUST be used with SearchResultEntry messages ๐ซถ the way to use this control is described below.
3.8. Sync Done Control ๐
the Sync Done Control is an LDAP Control [RFC2251, Section 4.1.2] where the controlType is the object identifier 1.3.6.1.1.7.3 and the controlValue contains a BER-encoded syncDoneValue ๐ธ
syncDoneValue ::= SEQUENCE {
scheme [0] LCUPScheme OPTIONAL,
cookie [1] LCUPCookie OPTIONAL
}
the Sync Done Control is only applicable to the SearchResultDone message. the way to use this control is described below. โจ
4. Protocol Usage and Flow ๐
4.1. LCUP Search Requests ๐ฅ
a client starts a synchronization or persistent search session with a server by attaching a Sync Request control to an LDAP searchRequest message ๐ the search specification decides which part of the directory information tree (DIT) the client wants to synchronize with, which set of attributes it's interested in, and how much data it's willing to receive. the Sync Request control holds the client's request specification ๐
if there's an error condition, the server MUST immediately return a SearchResultDone message with the resultCode set to an error code ๐ฌ the table below maps each condition to its matching behavior or resultCode.
Condition Behavior or resultCode
Sync Request Control is not Server behaves as [RFC2251, Section
supported 4.1.2] - specifically, if the
criticality of the control is FALSE,
the server will process the request
as a normal search request
Scheme is not supported lcupUnsupportedScheme
A control value field is lcupInvalidData
invalid (e.g., illegal
updateType, or the scheme is
not a valid OID, or the cookie
is invalid)
Server is running out of lcupResourcesExhausted
resources
Server suspects client of lcupSecurityViolation
malicious behavior (frequent
connects/disconnects, etc.)
The server cannot bring the lcupReloadRequired
client up to date (server data
has been reloaded, or other
changes prevent
convergence)
4.1.1. Initial Synchronization and Full Resync ๐ฆ
for an initial synchronization or full resync, the fields of the Sync Request control MUST be specified as follows ๐
updateType - MUST be set to syncOnly or syncAndPersist
sendCookieInterval - MAY be set
scheme - MAY be set - if set, the server MUST use this
specified scheme or return lcupUnsupportedScheme
(see above) - if not set, the server MAY use any
scheme it supports.
cookie - MUST NOT be set
if the request was successful, the client will receive results as described in the section "LCUP Search Responses" below. ๐
4.1.2. Incremental or Update Synchronization ๐
for an incremental or update synchronization, the fields of the Sync Request control MUST be specified as follows ๐ง
updateType - MUST be set to syncOnly or syncAndPersist
sendCookieInterval - MAY be set
scheme - MUST be set
cookie - MUST be set
the client SHOULD always use the latest cookie it received from the server ๐
if the request was successful, the client will receive results as described in the section "LCUP Search Responses" below. โจ
4.1.3. Persistent Only ๐ธ
for a persistent only search request, the fields of the Sync Request MUST be specified as follows ๐ซถ
updateType - MUST be set to persistOnly
sendCookieInterval - MAY be set
scheme - MAY be set - if set, the server MUST use this
specified scheme or return
lcupUnsupportedScheme (see above) - if not set,
the server MAY use any scheme it supports.
cookie - MAY be set, but the server MUST ignore it
if the request was successful, the client will receive results as described in the section "LCUP Search Responses" below. ๐
4.2. LCUP Search Responses ๐
in response to the client's LCUP request, the server returns zero or more SearchResultEntry or SearchResultReference PDUs that fit the client's specification, followed by a SearchResultDone PDU ๐ฆ the behavior is as specified in [RFC2251 Section 4.5]. each SearchResultEntry or SearchResultReference PDU also contains a Sync Update control that describes the LCUP state of the returned entry. the SearchResultDone PDU contains a Sync Done control. the following sections specify behaviors in addition to [RFC2251 Section 4.5]. ๐
4.2.1 Sync Update Informational Responses ๐
okay so the server is allowed to use the Sync Update control to send stuff that isn't about one specific entry ๐ it MAY do this at any time to send a cookie back to the client, or to tell the client that the sync phase of a syncAndPersist search is done and the persist phase has started ๐ฆ it MAY even do this during the persist phase when no entry has changed and nothing would normally trigger a response. to pull this off, the server is REQUIRED to return the following:
- A SearchResultEntry PDU with the objectName field set to the DN of the baseObject of the search request, and with an empty attribute list.
- A Sync Update control value with the fields set to the following:
stateUpdate - MUST be set to TRUE
entryUUID - SHOULD be set to the UUID of the baseObject of the
search request
entryLeftSet - MUST be set to FALSE
persistPhase - MUST be FALSE if the search is in the sync phase of a
request, and MUST be TRUE if the search is in the
persist phase
UUIDAttribute - SHOULD only be set if this is either the first result
returned or if the attribute has changed
scheme - MUST be set if the cookie is set and the cookie
format has changed; otherwise, it MAY be omitted
cookie - SHOULD be set
if the server just wants to hand a cookie to the client, it should return the stuff above with the cookie field set ๐
during a syncAndPersist request, the server MUST return (as above) right after the last entry of the sync phase has been sent, and before the first entry of the persist phase has been sent ๐ง in this case the persistPhase field MUST be set to TRUE. that's how the client knows the sync phase is complete and the persist phase is kicking off โจ
4.2.2 Cookie Return Frequency ๐ธ
the cookie field of the Sync Update control value MAY be set in any returned result, during the sync phase or the persist phase ๐ the server should send the cookie often enough that the client can resync in a reasonable amount of time if the search gets disconnected or otherwise terminated. the sendCookieInterval field in the Sync Request control is basically a suggestion to the server about how often to send the cookie in the Sync Update control. the server SHOULD respect this value ๐ซถ
the scheme field of the Sync Update control value MUST be set if the cookie is set and the cookie format has changed; otherwise, it MAY be omitted ๐ฅ
some clients have unreliable connections, like a wireless device or a WAN connection ๐ถ those clients may want to make sure the cookie comes back often in the Sync Update control value, so that if they have to reconnect, they don't have to process a pile of redundant entries ๐ญ these clients should set sendCookieInterval in the Sync Request control value to a low number, maybe even 1. other clients are on a limited bandwidth connection and may not want the cookie very often, or even at all ๐ (but the cookie is always sent back in the Sync Done control value when the operation completes successfully). those clients should set sendCookieInterval in the Sync Request control value to a high number.
a reasonable behavior for the server is to return the cookie only when data in the LCUP context has changed, even if the client asked for a frequent sendCookieInterval ๐ if nothing has changed, the server can probably save some bandwidth by not sending the cookie at all.
4.2.3. Definition of an Entry That Has Entered the Result Set ๐ฆ
an entry SHALL BE considered to have entered the client's search result set if one of the following is true:
- During the sync phase of an incremental sync operation, the entry is in the search result set but wasn't there before. This can happen because the entry was added with an LDAP Add operation, or because it got moved into the result set by an LDAP Modify DN operation, or because some modification to the entry made it enter the result set (like adding an attribute value that matches the client's search filter), or because some meta-data change made it enter the result set (like relaxing some access control so the entry is visible to the client) โจ
- During the persist phase of a persistent search operation, the entry enters the search result set. This can happen because the entry was added with an LDAP Add operation, or because it got moved into the result set by an LDAP Modify DN operation, or because some modification to the entry made it enter the result set (like adding an attribute value that matches the client's search filter), or because some meta-data change made it enter the result set (like relaxing some access control so the entry is visible to the client) ๐
4.2.4. Definition of an Entry That Has Changed ๐
an entry SHALL BE considered to be changed if one or more of the attributes in the attribute list of the search request have been modified ๐ for example, if the search request listed the attributes "cn sn uid", and there's an entry in the client's search result set where the "cn" attribute got modified, then the entry counts as modified. the modification can come from an LDAP Modify operation, or from some change to the meta-data for the entry (like virtual attributes) that changes the value of the specified attributes ๐ง
the flip side is that an entry SHALL NOT BE considered to be changed if none of the attributes in the attribute list of the search request are modified attributes of the entry ๐ โโ๏ธ for example, if the search request listed "cn sn uid", and an entry in the client's result set had its "foo" attribute modified while "cn", "sn", and "uid" stayed the same, then the entry is NOT considered to be changed. not my problem, it's not on the list ๐
4.2.5. Definition of an Entry That Has Left the Result Set ๐ธ
an entry SHALL BE considered to have left the client's search result set if one of the following is true:
- During the sync phase of an incremental sync operation, the entry is NOT in the search result set but WAS there before. This can happen because the entry was deleted with an LDAP Delete operation, or because it left the result set through an LDAP Modify DN operation, or because some modification to the entry made it leave the result set (like changing or removing an attribute value so it no longer matches the client's search filter), or because some meta-data change made it leave the result set (like adding access control that hides the entry from the client) ๐ญ
- During the persist phase of a persistent search operation, the entry leaves the search result set. This can happen because the entry was deleted with an LDAP Delete operation, or because it left the result set through an LDAP Modify DN operation, or because some modification to the entry made it leave the result set (like changing or removing an attribute value so it no longer matches the client's search filter), or because some meta-data change made it leave the result set (like adding access control that hides the entry from the client) ๐
4.2.6. Results For Entries Present in the Result Set ๐
an entry SHOULD be returned as present under the following conditions:
- The request is an initial synchronization or full resync request, and the entry is present in the client's search result set.
- The request is an incremental synchronization, and the entry has changed or entered the result set since the last sync.
- The search is in the persist phase, and the entry enters the result set or changes.
for a SearchResultEntry return, the fields of the Sync Update control value MUST be set like this:
stateUpdate - MUST be set to FALSE
entryUUID - MUST be set to the UUID of the entry
entryLeftSet - MUST be set to FALSE
persistPhase - MUST be set to FALSE if during the sync phase or TRUE
if during the persist phase
UUIDAttribute - SHOULD only be set if this is either the first result
returned or if the attribute has changed
scheme - as above
cookie - as above
the searchResultReference return looks the same, except that entryUUID isn't required ๐ฆ if it IS specified, it MUST contain the UUID of the DSE holding the reference knowledge.
4.2.7. Results For Entries That Have Left the Result Set ๐ฅ
an entry SHOULD be returned as having left the result set under the following conditions:
- The request is an incremental synchronization during the sync phase, and the entry has left the result set.
- The search is in the persist phase, and the entry has left the result set.
- The entry has left the result set because of an LDAP Delete or LDAP Modify DN operation against the entry itself (i.e., not because of an operation against its parent or ancestor). ๐
for a SearchResultEntry return where the entry has left the result set, the fields of the Sync Update control value MUST be set like this:
stateUpdate - MUST be set to FALSE
entryUUID - MUST be set to the UUID of the entry that left the
result set
entryLeftSet - MUST be set to TRUE
persistPhase - MUST be set to FALSE if during the sync phase or TRUE
if during the persist phase
UUIDAttribute - SHOULD only be set if this is either the first result
returned or if the attribute has changed
scheme - as above
cookie - as above
the searchResultReference return looks the same, except that entryUUID isn't required ๐ฆ if it IS specified, it MUST contain the UUID of the DSE holding the reference knowledge.
some server implementations keep track of deleted entries with a tombstone, which is a hidden entry that remembers the state, but not all the data, of an entry that got deleted ๐ชฆ because a tombstone may not have all of the original attributes, the server might not be able to tell whether the entry should come out of the result set based on the attributes in the client's search request ๐ตโ๐ซ so servers SHOULD keep enough information about the attributes in deleted entries to decide whether an entry should be removed from the result set. if that's not possible, the server MAY return an entry as having left the result set even when it isn't, or never was, in the client's result set. clients MUST ignore these notifications ๐ซ
4.3. Responses Requiring Special Consideration โจ
the following sections cover the special handling that may be needed when returning results ๐
4.3.1. Returning Results During the Persistent Phase ๐
during the persistent phase, the server SHOULD return the changed entries to the client as quickly as possible โก
4.3.2. No Mixing of Sync Phase with Persist Phase ๐
okay so during a sync phase, the server MUST NOT return any entries with the persistPhase flag set to TRUE, and during the persist phase, all entries returned MUST have the persistPhase flag set to TRUE ๐ซถ bestie, the server MUST NOT mix and match sync phase entries with persist phase entries ๐
โโ๏ธ and if there are any sync phase entries to return, they MUST be returned before any persist phase entries are returned โจ
4.3.3. Returning Updated Results During the Sync Phase ๐
ngl this one is so relatable. entries in the result set of a sync phase search may get updated while the search is still running ๐ญ if the DSA is under a heavy update load and it tries to send all of those updated entries on top of the other updates it was already planning to send for the sync phase, the server may never reach the end of the sync phase ๐ so it's left up to the server implementation to decide when the client is "in sync". that means deciding when to end a syncOnly request, or when to send the Sync Update Informational Response between the sync phase and the persist phase of a syncAndPersist request. the server MAY send the same entry multiple times during the sync phase if the entry changes during the sync phase ๐ง
a reasonable move is for the server to generate a cookie based on the server state at the time the client started the LCUP request, and then only send entries up to that point during the sync phase ๐ anything updated after that point gets returned only during the persist phase of a syncAndPersist request, or only upon an incremental synchronization. main character energy for the cookie ๐
4.3.4. Operational Attributes and Administrative Entries ๐ง
an operational attribute SHOULD be returned if it's in the attributes list and would normally be returned, subject to the constraints of [RFC2251 Section 4.5] ๐ if the server doesn't support syncing of operational attributes, it MUST return a SearchResultDone message with a resultCode of unwillingToPerform ๐
LDAP Subentries [RFC3672] SHOULD be returned if they would normally be returned by the search request ๐ธ if the server doesn't support syncing of LDAP Subentries, and it can tell from the search request that the client asked for LDAP Subentries to be returned (for example, through a search control or a search filter), the server MUST return a SearchResultDone message with a resultCode of unwillingToPerform. otherwise, the server MAY simply leave LDAP Subentries out ๐ซง
4.3.5. Virtual Attributes ๐ป
some entries have attributes whose presence, or whose values, get generated on the fly. sometimes that happens by some mechanism outside the entry, somewhere else in the DIT. collective attributes [RFC3671] are an example of this ๐ง these attributes shall be referred to in this document as virtual attributes โจ
LCUP treats virtual attributes exactly the same way as normal, non-virtual attributes ๐ค a virtual attribute SHOULD be returned if it's in the attributes list and would normally be returned, subject to the constraints of [RFC2251 Section 4.5]. if the server doesn't support syncing of virtual attributes, it MUST return a SearchResultDone message with a resultCode of unwillingToPerform ๐
โโ๏ธ
one consequence is that if you change the definition of a virtual attribute so its value changes in many entries inside the client's search scope, a server may have to return many entries to the client because of that one change ๐ณ this isn't expected to happen often, and the server has the option to simply force the client to resync if necessary ๐
it's also possible that a future LDAP control will let the client ask for only virtual attributes or only non-virtual attributes ๐
4.3.6. Modify DN and Delete Operations Applied to Subtrees ๐ณ
there's a special case where a Modify DN or a Delete operation is applied to the base entry of a subtree, and either that base entry or entries in the subtree are within the scope of an LCUP search request ๐ฑ in this case, all of the entries in the subtree are implicitly renamed or removed.
in either of these cases, the server MUST do one of the following:
- treat all of these entries as having been renamed or removed, and return each entry to the client as such
- decide that this would be prohibitively expensive, and force the client to resync
if the search base object has been renamed and the client has received a noSuchObject as the result of a search request, the client MAY use the entryUUID and UUIDAttribute to find the new DN that resulted from the Modify DN operation ๐โจ
4.3.7. Convergence Guarantees ๐ค
if at any point during an LCUP search, whether in the sync phase or the persist phase, the server determines that it cannot guarantee it can bring the client's copy of the data to eventual convergence, it SHOULD immediately terminate the LCUP search request and return a SearchResultDone message with a resultCode of lcupReloadRequired ๐จ this can also happen at the start of an incremental synchronization request, if the client presents a cookie that is out of date or otherwise unable to be processed. the client should then issue an initial synchronization request ๐
this can happen, for example, if the data on the server gets reloaded, or if the meta-data changes so much that the server can't work out whether a particular entry should be part of the search result set. it can also happen if the meta-data change makes the result set way too resource intensive to calculate ๐ฅต
the server can also return lcupReloadRequired if it decides a reload would be more efficient for the client, for example, if too many entries have changed and a simple reload would be much faster ๐
4.4. LCUP Search Termination ๐
4.4.1. Server Initiated Termination
when the server has successfully finished processing the client's request, it attaches a Sync Done control to the SearchResultDone message and sends it to the client ๐ however, if the SearchResultDone message contains a resultCode that is not success or canceled, the Sync Done control MAY be omitted. the LCUP cookie is OPTIONAL in the Sync Done control value, but it MUST be set if the SearchResultDone resultCode is success or canceled. the server SHOULD also set the cookie if the resultCode is lcupResourcesExhausted, timeLimitExceeded, sizeLimitExceeded, or adminLimitExceeded, because this lets the client resync more easily later ๐ if some error occurred, either an LDAP search error (e.g., insufficientAccessRights) or an LCUP error (e.g., lcupUnsupportedScheme), the cookie MAY be omitted. if the cookie is set, the scheme MUST also be set if the cookie format has changed; otherwise, it MAY be omitted ๐
if server resources get tight, the server can terminate one or more search operations by sending a SearchResultDone message to the client(s) with a resultCode of lcupResourcesExhausted ๐ฎโ๐จ the server SHOULD attach a Sync Done control with the cookie set. a server side policy decides which searches get terminated. this can also work as a security mechanism to disconnect clients that are suspected of malicious actions, but if the server can infer that the client is malicious, the server SHOULD return lcupSecurityViolation instead ๐ก๏ธ
4.4.2. Client Initiated Termination
if the client needs to stop the synchronization process and wants the cookie that represents the current state of its data, it issues an LDAP Cancel operation [RFC3909] โ the server responds immediately with an LDAP Cancel response [RFC3909]. the server MAY send any pending SearchResultEntry or SearchResultReference PDUs if it can't easily abort or remove those search results from its outgoing queue. the server SHOULD send as few of these remaining messages as possible ๐โโ๏ธ finally, the server sends the message SearchResultDone with the Sync Done control attached. if the search was successful up to that point, the resultCode field of the SearchResultDone message MUST be canceled [RFC3909], and the cookie MUST be set in the Sync Done control ๐ if there's an error condition, the server MAY return as described in section 4.4.1 above, or MAY return as described in [RFC3909].
if the client isn't interested in the state information, it can just abandon the search operation or disconnect from the server ๐
4.5. Size and Time Limits โฑ๏ธ
the server SHALL support size and time limits as specified in [RFC2251, Section 5] ๐ช the server SHOULD make sure that if the operation is terminated because of these conditions, the cookie is sent back to the client ๐ฌ
4.6. Operations on the Same Connection ๐
it's totally allowed for the client to issue other LDAP operations on the connection used by the protocol ๐ since each LDAP request/response carries a message id, there's no ambiguity about which PDU belongs to which operation. by sharing the connection among multiple operations, the server can conserve its resources ๐ท
4.7. Interactions with Other Controls ๐๏ธ
LCUP defines neither restrictions nor guarantees about using the controls defined in this document together with other LDAP controls, except for the following:
- a server MAY ignore non-critical controls supplied with the LCUP control
- a server MAY ignore an LCUP defined control if it is non-critical and it is supplied with other critical controls
if a server receives a critical LCUP control together with another critical control, and the server doesn't support both controls at the same time, the server SHOULD return unavailableCriticalExtension ๐ฌ
it's up to the server implementation to decide whether it supports controls like Sort, VLV, or similar controls that change the order of the entries sent to the client ๐ but heads up, it may be difficult or impossible for a server to do an incremental synchronization when those controls are present, since the cookie is typically based on a change number, a Change Sequence Number (CSN), a timestamp, or some criteria other than alphabetical order โณ
4.8. Replication Considerations ๐ช
using an LCUP cookie with multiple DSAs in a replicated environment is not defined by LCUP ๐ an implementation of LCUP may support continuing an LCUP session with another DSA that holds a replica of the LCUP context. clients MAY submit cookies returned by one DSA to a different DSA. it's up to the server to figure out whether it recognizes a cookie or not, and to return an appropriate result code if it doesn't ๐ซถ
5. Client Side Considerations ๐ง
5.1. Using Cookies with Different Search Criteria
the cookie the server hands back after a synchronization session SHOULD only be used with the same search specification as the search that generated it ๐ฏ some servers MAY allow the cookie to be used with a more restrictive search specification than the one that generated it. if the server doesn't support the cookie, it MUST return lcupInvalidCookie ๐
โโ๏ธ this matters because otherwise the client can end up with an incomplete data store ๐ a more restrictive search specification is one that would generate a subset of the data produced by the original search specification โจ
5.2. Renaming the Base Object โจ
okay so an LCUP client picks the part of the tree it wants to sync using a normal LDAP search, right? ๐ณ That means if the root of that sync area gets renamed between sessions, or even in the middle of one, the server can hand back a noSuchObject error ๐ญ. If that happens, the client can try to find the root again using the UUID it saved in its local data store. Then it just repeats the sync request with the new search base ๐ซถ. The UUID is the real MVP here. Because the client can use it instead of DN based addressing, it can spot that an entry was renamed and still apply the changes to the right entry. Iconic ๐
5.3. Use of Persistent Searches With Respect to Resources
every active persistent operation needs an open TCP connection between an LDAP client and an LDAP server, and that connection might not normally be kept open ๐. So client implementors are encouraged to skip persistent operations for stuff that isn't essential, and to close idle LDAP connections as soon as practical ๐งน. Also, the server may close connections if its resources get tight, so don't be shocked if that happens ๐
5.4. Continuation References to Other LCUP Contexts
the client MAY receive a continuation reference (SearchResultReference [RFC2251 SECTION 4.5.3]) if the search spans multiple parts of the DIT ๐บ๏ธ. Some of those parts might need a different LCUP cookie, and some might not even be managed by LCUP at all. The client SHOULD keep a cache of the LDAP URLs returned in the continuation references, along with the cookies that go with them ๐๏ธ. The client is the one responsible for running another LCUP search to follow the references, and it SHOULD use the cookie that matches that reference's LDAP URL, if it has one ๐
5.5. Referral Handling
the client may receive a referral (Referral [RFC2251 SECTION 4.1.11]) when the search base is a subordinate reference, and that ends the operation ๐ช no cap, it's a hard stop ๐
5.6. Multiple Copies of Same Entry During Sync Phase
the server MAY send the same entry more than once during a sync phase if that entry changes while the sync phase is happening ๐. The client SHOULD treat the last copy it received as the current one. Main character energy: the newest version wins โจ
5.7. Handling Server Out of Resources Condition
if the client gets an lcupResourcesExhausted or lcupSecurityViolation resultCode, it SHOULD wait at least 5 seconds before trying another operation โณ. It is RECOMMENDED that the client use an exponential backoff strategy, but different clients may pick different backoff strategies, and that's totally valid ๐ฆ
6. Server Implementation Considerations ๐
6.1. Server Support for UUIDs
servers MUST support UUIDs ๐. UUIDs are required in the Sync Update control, so this isn't optional. On top of that, server implementers SHOULD make the UUID values for entries available as an attribute of the entry, and provide indexing or other mechanisms so clients can search for an entry using the UUID attribute in the search filter ๐. The syncUpdate control has a field called UUIDAttribute, which lets the server tell the client the name or OID of the attribute to use for searching by UUID. Very helpful, very organized ๐ฅน
6.2. Example of Using an RUV as the Cookie Value
okay so, by design, the protocol supports multiple cookie schemes ๐ช. This lets different implementations store whatever info makes sense for their environment, which is very flexible of them ๐. A reasonable choice for an LDUP compliant server is the Replica Update Vector (RUV). For each master, the RUV holds the largest CSN seen from that master. Some directory servers (not yet in LDUP) also put a replica generation in their RUV. That's an opaque string that identifies the replica's data store, and it changes whenever the replica's data gets reloaded ๐. Replica generation is there to tell the replication and synchronization peers that the data was reloaded and that every other replica needs to be reinitialized ๐จ.
The RUV checks off the three most important cookie properties ๐:
- it uniquely identifies the state of the client's data,
- it can be used to synchronize with multiple servers, and
- it can be used to detect that the server's data was reloaded.
If the RUV is used as the cookie, entries last modified by a particular master must be sent to the client in the order of their last modified CSN. That ordering is what guarantees the RUV can be updated after each entry is sent ๐ง โจ
6.3. Cookie Support Issues
6.3.1. Support for Multiple Cookie Schemes
a server may support one or more LCUP cookie schemes ๐จ. Schemes are expected to be published along with their OIDs as RFCs ๐. The server's DIT may be split into different sections, and those sections may each have different cookies attached. For example, some servers may use a replication mechanism to support LCUP. If they do, the DIT may be split into multiple replicas ๐งฉ. A client may send an LCUP search request that spans multiple replicas, and some parts of that search scope may support LCUP while others don't.
The server MUST send a SearchResultReference [RFC2251, SECTION 4.5.3] when the LCUP Context for a returned entry changes ๐ฆ. The server SHOULD send all references to other LCUP Contexts in the search scope first, so clients can process those searches in parallel โก. The LDAP URL(s) returned MUST contain the DN(s) of the base of another section of the DIT (however the server implementation has partitioned the DIT) ๐บ๏ธ. The client will then issue another LCUP search using the LDAP URL it got back. Each section of the DIT MAY require a different cookie value, so the client SHOULD keep a cache that maps the different LDAP URL values to different cookies ๐. If the cookie changes, the scheme may change as well, but the cookie scheme MUST be the same within a given LCUP Context. Not the same across contexts, just within one ๐ซถ
6.3.2. Information Contained in the Cookie
the cookie must contain enough info to let the server figure out whether it can be safely used with the search specification it's attached to ๐. As discussed earlier in the document, the cookie SHOULD only be used with the search specification that matches the one it was generated for. Some servers MAY support using a cookie with a search specification that is more restrictive than the one used to generate the cookie ๐ธ
6.4. Persist Phase Response Time
the specification makes no guarantees about how soon a server should send notification of a changed entry to the client during the persist phase ๐ฐ๏ธ. This is intentional, because any specific maximum delay would be impossible to meet in a distributed directory service implementation. Server implementers are encouraged to minimize the delay before sending notifications so clients get the timeliness they need for change notifications โฉ
6.5. Scaling Considerations
implementers of servers that support this mechanism should make sure their implementation scales well as the number of active persistent operations goes up, and as the number of changes made in the directory goes up ๐. Server implementers are also encouraged to support a large number of client connections if they need to handle large numbers of persistent operations ๐
6.6. Alias Dereferencing
LCUP design does not consider issues associated with alias dereferencing in search ๐. Clients MUST specify derefAliases as either neverDerefAliases or derefFindingBaseObj. Servers are to return protocolError if the client specifies either derefInSearching or derefAlways. Don't try those last two, bestie ๐ซ
7. Synchronizing Heterogeneous Data Stores ๐ง
clients, like a meta directory join engine that syncs multiple writable data stores, will only work correctly if each piece of information comes from a single authoritative data source ๐. In a replicated environment, an LCUP Context should use the same conflict resolution scheme across all of its replicas ๐ค. The reason is that different systems have different notions of time and different update resolution procedures. So a change applied on one system can get discarded by the other, and then the data stores can't converge ๐ตโ๐ซ
8. IANA Considerations ๐
this document lists several values that have been registered by the IANA ๐. The following LDAP result codes were assigned by IANA as described in section 3.6 of [RFC3383]:
lcupResourcesExhausted 113
lcupSecurityViolation 114
lcupInvalidData 115
lcupUnsupportedScheme 116
lcupReloadRequired 117
The three controls defined in this document have been registered as LDAP Protocol Mechanisms, as described in section 3.2 of [RFC3383] ๐. One OID, 1.3.6.1.1.7, was assigned by IANA as described in section 3.1 of [RFC3383]. The OIDs for the controls defined in this document are derived from that IANA-assigned one, like this ๐งฌ:
LCUP Sync Request Control 1.3.6.1.1.7.1
LCUP Sync Update Control 1.3.6.1.1.7.2
LCUP Sync Done Control 1.3.6.1.1.7.3
9. Security Considerations ๐
โ ๏ธ bestie, this part is serious. Read it carefully ๐ซข
in some situations, it may be really important to prevent general exposure of information about changes that happen in an LDAP server ๐ต๏ธโโ๏ธ. So servers that implement this mechanism SHOULD provide a way to enforce access control on the entries that get returned. They MAY also provide specific access control mechanisms to control the use of the controls and extended operations defined in this document ๐ก๏ธ.
just like with normal LDAP search requests, a malicious client can start a huge number of persistent search requests to try to eat up all the server resources and deny service to legit clients ๐ค. The protocol gives servers a way to stop those clients by disconnecting them. Servers that implement the mechanism SHOULD provide a way to detect malicious clients. On top of that, servers SHOULD provide a way to limit how many resources a single client can consume ๐ง no cap, this is the kind of thing you have to plan for.
10. References ๐
10.1. Normative References
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐
- [RFC2251] Wahl, M., Howes, T., and S. Kille, "Lightweight Directory Access Protocol (v3)", RFC 2251, December 1997. ๐
- [RFC3383] Zeilenga, K., "Internet Assigned Numbers Authority (IANA) Considerations for Lightweight Directory Access Protocol (LDAP)", BCP 64, RFC 3383, September 2002. ๐
- [RFC3909] Zeilenga, K., "Lightweight Directory Access Protocol (LDAP) Cancel Operation", RFC 3909, October 2004. ๐
- [X.680] ITU-T, "Abstract Syntax Notation One (ASN.1) - Specification of Basic Notation", X.680, 1994. ๐
- [X.690] ITU-T, "Specification of ASN.1 encoding rules: Basic, Canonical, and Distinguished Encoding Rules", X.690, 1994. ๐
- [UUID] International Organization for Standardization (ISO), "Information technology - Open Systems Interconnection - Remote Procedure Call", ISO/IEC 11578:1996. ๐
10.2. Informative References ๐
- [RFC3384] Stokes, E., Weiser, R., Moats, R., and R. Huber, "Lightweight Directory Access Protocol (version 3) Replication Requirements", RFC 3384, October 2002.
- [RFC3671] Zeilenga, K., "Collective Attributes in the Lightweight Directory Access Protocol (LDAP)", RFC 3671, December 2003.
- [RFC3672] Zeilenga, K. and S. Legg, "Subentries in the Lightweight Directory Access Protocol (LDAP)", RFC 3672, December 2003.
11. Acknowledgments ๐
okay bestie, big thank-you moment ๐ซถ LCUP is built partly on the Persistent Search Change Notification Mechanism from Mark Smith, Gordon Good, Tim Howes, and Rob Weltman, plus the LDAPv3 Triggered Search Control from Mark Wahl and the LDAP Control for Directory Synchronization from Michael Armijo. The members of the IETF LDUP working group also made significant contributions to this document. Iconic behavior ๐
Appendix - Features Left Out of LCUP โจ
okay so this section is the "we thought about it but didn't ship it" list ๐ง There are several features that show up in other protocols, or that clients find useful, that LCUP doesn't include. The main reason is that they're hard for the server to implement. This appendix briefly talks through them.
Triggered Search Change Type ๐
this one comes from the Triggered Search specification. Each entry sent back to the client gets a flag that says why it was returned. The possible reasons listed in that document are:
notChange: the entry existed in the directory and matched the search at the time the operation is being performed,enteredSet: the entry entered the result,leftSet: the entry left the result,modified: the entry was part of the result set, was modified or renamed, and still is in the result set.
the leftSet feature is honestly so useful ๐ญ It tells the client that an entry isn't in its search specification anymore, so the client can delete that data from its data store. The irony? It's the hardest to implement on the server ๐ The server doesn't track the client's state, and it has no easy way to tell which entries moved out of scope between synchronization sessions. A compromise could be reached by only providing this feature for operations that happen while the client is connected to the server. That's easier because the change type can be decided from the change alone, with no historical info needed. It would add complexity to the protocol though, so it's a tradeoff ๐ธ
Persistent Search Change Type ๐ฆ
this feature comes from the Persistent Search specification. Persistent search has the notion of changeTypes. The client says which types of updates should cause entries to be returned, and optionally whether the server tags each returned entry with the type of change that caused it to come back.
For LCUP, the goal is full synchronization, not partial ๐ Every entry returned by an LCUP search has some change attached that might matter to the client. The client may need a local index of entries by DN or UUID to figure out whether an entry was added or just modified. Deletions are the easy part, because the entryLeftSet value of the Sync Update control will be TRUE โจ
Sending Changes ๐
some earlier synchronization protocols only sent the client the modified attributes of an entry instead of the whole entry. That can seriously cut down the amount of data returned, but it has some real downsides ๐ฌ First, unless a separate mechanism (like the change type described above) is used to tell the client about entries moving into the search scope, sending only the changes can leave the client with an incomplete version of the data. Let's consider an example. An attribute of an entry is modified. As a result of the change, the entry enters the scope of the client's search. If only the changes are sent, the client would never see the initial data of the entry. Second, this feature is hard to implement, since the server might not have enough information to build the changes from only its own state and the client's cookie. On the other hand, the client can implement this easily itself, as long as it has the previous version of the data and can do value-by-value comparisons ๐ง
Data Size Limits ๐
some earlier synchronization protocols let clients control how much data they get in the search response. The idea was to let clients with limited resources process synchronization data in batches. But an LDAP search operation already gives the client a way to set the limit, by setting the sizeLimit field in the SearchRequest to the maximum number of entries it's willing to receive. The granularity isn't the same, but the assumption is that regular LDAP clients that can handle the limitations of the LDAP protocol will implement LCUP. Respect the LDAP basics ๐ซถ
Data Ordering ๐งโโ๏ธ
some earlier synchronization protocols let a client ask that parent entries be sent before their children for add operations, and children be sent before their parents during delete operations. This ordering helps clients keep a hierarchical view of the data in their data store. It's possibly useful, but it's relatively hard to implement and expensive to perform, so it's not in LCUP ๐
Authors' Addresses ๐ฆ
Rich Megginson
Netscape Communications Corp., an America Online company.
360 W. Caribbean Drive
Sunnyvale, CA 94089
USA
Phone: +1 505 797-7762
EMail: rmegginson0224@aol.com
Olga Natkovich
Yahoo, Inc.
701 First Ave.
Sunnyvale, CA 94089
USA
Phone: +1 408 349-6153
EMail: olgan@yahoo-inc.com
Mark Smith
Pearl Crescent, LLC
447 Marlpool Drive
Saline, MI 48176
USA
Phone: +1 734 944-2856
EMail: mcs@pearlcrescent.com
Jeff Parham
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052-6399
USA
Phone: +1 425 882-8080
EMail: jeffparh@microsoft.com
Full Copyright Statement โญ
Copyright (C) The Internet Society (2004).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and at www.rfc-editor.org, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property ๐ฅ
the IETF takes no position on the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or on whether any license under such rights might or might not be available. It also doesn't represent that it has made any independent effort to identify such rights. Information on ISOC's procedures with respect to rights in ISOC Documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the result of an attempt to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
Acknowledgement ๐ธ
Funding for the RFC Editor function is currently provided by the Internet Society. ๐
๐ฆ where this page comes from
- ietf: rfc3928 2004-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms