RFC 4515

Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters

πŸ“… published June 2006, from ietf

RFC 4515 πŸ“œ Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters

Okay bestie, this is RFC 4515 and it's giving Standards Track energy πŸ¦‹ It came out in June 2006 and it's written by M. Smith, Ed. (Pearl Crescent, LLC) and T. Howes (Opsware, Inc.) ✨

  • Category: Standards Track 🌸
  • Date: June 2006
  • Obsoletes: RFC 2254 πŸ’… so this one replaces it
  • Updates: nothing is listed here

Status of This Memo ✨

Okay so this doc specifies an Internet standards track protocol for the Internet community, and it's asking everyone for discussion and suggestions for improvements 🫢 For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited 🌈

Copyright (C) The Internet Society (2006).

Abstract 🧚

LDAP search filters travel over the LDAP protocol as a binary representation, which is great for the network but not so great for humans πŸ™ˆ This doc defines a human-readable string representation of LDAP search filters. It's built for LDAP URLs (RFC 4516) and for other applications too, so it's super versatile, periodt πŸ’–

Table of Contents πŸ“

1. Introduction ....................................................2
2. LDAP Search Filter Definition ...................................2
3. String Search Filter Definition .................................3
4. Examples ........................................................5
5. Security Considerations .........................................7
6. Normative References ............................................7
7. Informative References ..........................................8
8. Acknowledgements ................................................8
Appendix A: Changes Since RFC 2254 .................................9
   A.1. Technical Changes ..........................................9
   A.2. Editorial Changes ..........................................9

1. Introduction ✨

The Lightweight Directory Access Protocol (LDAP) [RFC4510] defines a network representation of a search filter that gets sent to an LDAP server πŸ¦‹ Some applications would love a shared way to write these filters in a human-readable form, and LDAP URLs [RFC4516] are one example of that. This document defines a human-readable string format for the full range of possible LDAP version 3 search filters, including extended match filters. Iconic πŸ‘‘

This document is an integral part of the LDAP technical specification [RFC4510]. That spec obsoletes the previously defined LDAP technical specification, RFC 3377, in its entirety πŸ’…

This document replaces RFC 2254. The changes from RFC 2254 are summarized in Appendix A πŸŽ€

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 [RFC2119]. These are the capital-letter requirement words, so pay close attention to them, bestie 🫢

2. LDAP Search Filter Definition 🌸

Okay so an LDAP search filter is defined in Section 4.5.1 of [RFC4511] like this πŸ’œ

     Filter ::= CHOICE {
         and                [0] SET SIZE (1..MAX) OF filter Filter,
         or                 [1] SET SIZE (1..MAX) OF filter Filter,
         not                [2] Filter,
         equalityMatch      [3] AttributeValueAssertion,
         substrings         [4] SubstringFilter,
         greaterOrEqual     [5] AttributeValueAssertion,
         lessOrEqual        [6] AttributeValueAssertion,
         present            [7] AttributeDescription,
         approxMatch        [8] AttributeValueAssertion,
         extensibleMatch    [9] MatchingRuleAssertion }

     SubstringFilter ::= SEQUENCE {
         type    AttributeDescription,
         -- initial and final can occur at most once
         substrings    SEQUENCE SIZE (1..MAX) OF substring CHOICE {
          initial        [0] AssertionValue,
          any            [1] AssertionValue,
          final          [2] AssertionValue } }

     AttributeValueAssertion ::= SEQUENCE {
         attributeDesc   AttributeDescription,
         assertionValue  AssertionValue }

     MatchingRuleAssertion ::= SEQUENCE {
         matchingRule    [1] MatchingRuleId OPTIONAL,
         type            [2] AttributeDescription OPTIONAL,
         matchValue      [3] AssertionValue,
         dnAttributes    [4] BOOLEAN DEFAULT FALSE }

     AttributeDescription ::= LDAPString
                     -- Constrained to <attributedescription>
                     -- [RFC4512]

     AttributeValue ::= OCTET STRING

     MatchingRuleId ::= LDAPString

     AssertionValue ::= OCTET STRING

     LDAPString ::= OCTET STRING -- UTF-8 encoded,
                                 -- [Unicode] characters

The AttributeDescription, as defined in [RFC4511], is a string representation of the attribute description that's discussed in [RFC4512]. The AttributeValue and AssertionValue OCTET STRINGs have the form defined in [RFC4517]. The Filter gets encoded for network transmission using the Basic Encoding Rules (BER) defined in [X.690], with the simplifications described in [RFC4511] 🧚

3. String Search Filter Definition πŸ’–

Okay this is the main event bestie πŸ’… The string representation of an LDAP search filter is a string of UTF-8 [RFC3629] encoded Unicode characters [Unicode]. It's defined by the grammar below, which follows the ABNF notation from [RFC4234]. Any productions that aren't defined here come from Section 1.4 (Common ABNF Productions) of [RFC4512], unless noted otherwise. The filter format uses prefix notation πŸ¦‹

   filter         = LPAREN filtercomp RPAREN
   filtercomp     = and / or / not / item
   and            = AMPERSAND filterlist
   or             = VERTBAR filterlist
   not            = EXCLAMATION filter
   filterlist     = 1*filter
   item           = simple / present / substring / extensible
   simple         = attr filtertype assertionvalue
   filtertype     = equal / approx / greaterorequal / lessorequal
   equal          = EQUALS
   approx         = TILDE EQUALS
   greaterorequal = RANGLE EQUALS
   lessorequal    = LANGLE EQUALS
   extensible     = ( attr [dnattrs]
                        [matchingrule] COLON EQUALS assertionvalue )
                    / ( [dnattrs]
                         matchingrule COLON EQUALS assertionvalue )
   present        = attr EQUALS ASTERISK
   substring      = attr EQUALS [initial] any [final]
   initial        = assertionvalue
   any            = ASTERISK *(assertionvalue ASTERISK)
   final          = assertionvalue
   attr           = attributedescription
                      ; The attributedescription rule is defined in
                      ; Section 2.5 of [RFC4512].
   dnattrs        = COLON "dn"
   matchingrule   = COLON oid
   assertionvalue = valueencoding
   ; The <valueencoding> rule is used to encode an <AssertionValue>
   ; from Section 4.1.6 of [RFC4511].
   valueencoding  = 0*(normal / escaped)
   normal         = UTF1SUBSET / UTFMB
   escaped        = ESC HEX HEX
   UTF1SUBSET     = %x01-27 / %x2B-5B / %x5D-7F
                       ; UTF1SUBSET excludes 0x00 (NUL), LPAREN,
                       ; RPAREN, ASTERISK, and ESC.
   EXCLAMATION    = %x21 ; exclamation mark ("!")
   AMPERSAND      = %x26 ; ampersand (or AND symbol) ("&")
   ASTERISK       = %x2A ; asterisk ("*")
   COLON          = %x3A ; colon (":")
   VERTBAR        = %x7C ; vertical bar (or pipe) ("|")
   TILDE          = %x7E ; tilde ("~")

Heads up, this bit is important πŸ™ˆ Even though both the <substring> and <present> productions in the grammar above can produce the "attr=*" construct, this construct is only used to denote a presence filter ✨

The <valueencoding> rule makes sure the entire filter string is a valid UTF-8 string 🌈 It also says that the octets representing the ASCII characters "*" (ASCII 0x2a), "(" (ASCII 0x28), ")" (ASCII 0x29), "" (ASCII 0x5c), and NUL (ASCII 0x00) get represented as a backslash "" (ASCII 0x5c) followed by the two hexadecimal digits that give the value of the encoded octet πŸ’…

This simple escaping mechanism gets rid of filter-parsing ambiguities. It also lets any filter that can be represented in LDAP be represented as a NUL-terminated string 🫢 Other octets that are part of the <normal> set may also be escaped with this mechanism. Non-printing ASCII characters are one example πŸ¦‹

For AssertionValues that contain UTF-8 character data, each octet of the character being escaped gets replaced by a backslash and two hex digits, which together form a single octet in the character's code. For example, a filter checking whether the "cn" attribute contained a value with the character "" anywhere in it would be written as "(cn=\2a*)" πŸŽ€

As the <valueencoding> rule shows, implementations MUST escape all octets greater than 0x7F that aren't part of a valid UTF-8 encoding sequence when they generate a string representation of a search filter πŸ”₯ Implementations SHOULD accept input strings that aren't valid UTF-8 strings too. This is needed because RFC 2254 didn't clearly define the term "string representation". In particular, it didn't mention that the string representation of an LDAP search filter is a string of UTF-8-encoded Unicode characters πŸ’€

4. Examples ✨

okay so this section is basically a filter buffet πŸ“ it shows a bunch of search filters written in this notation, so you can see how they actually look

(cn=Babs Jensen)
(!(cn=Tim Howes))
(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))
(o=univ*of*mich*)
(seeAlso=)

next up are the extensible matching examples, where things get spicy 🌢️

(cn:caseExactMatch:=Fred Flintstone)
(cn:=Betty Rubble)
(sn:dn:2.4.6.8.10:=Barney Rubble)
(o:dn:=Ace Industry)
(:1.2.3:=Wilma Flintstone)
(:DN:2.4.6.8.10:=Dino)

the first one uses the matching rule caseExactMatch πŸ’…

the second one shows a MatchingRuleAssertion form with no matchingRule at all, so it's giving minimalist πŸ¦‹

the third one uses the :oid notation to say that the matching rule with the OID 2.4.6.8.10 should be used when comparing things. it also uses :dn, which means the attributes in an entry's distinguished name count as part of the entry when the match is evaluated 🧚

the fourth one is an equality match, except DN components get treated as part of the entry during the match 🌸

the fifth one is a filter that should be applied to any attribute that supports the given matching rule. the <attr> part is left out, so that's the whole vibe 🫢

the sixth and final one is also a filter for any attribute supporting the given matching rule, but attributes that support the matching rule and show up in the DN should be considered too πŸ‘‘

now for the escaping examples, which are literally my favourite 😭

(o=Parens R Us \28for all your parenthetical needs\29)
(cn=*\2A*)
(filename=C:\5cMyFile)
(bin=\00\00\00\04)
(sn=Lu\c4\8di\c4\87)
(1.3.6.1.4.1.1466.0=\04\02\48\69)

the first one uses escaping to represent parenthesis characters πŸŽ€

the second shows how to write a * inside an assertion value so it doesn't get read as a substring indicator πŸ™ˆ

the third shows escaping the backslash character itself πŸ’œ

the fourth is a filter that searches for the four-octet value 00 00 00 04 (hex). it's a good example of using escaping to represent arbitrary data, NUL characters included πŸ”₯

the fifth shows escaping used for various non-ASCII UTF-8 characters. the <assertionvalue> part of this one has 5 characters in it:

  • LATIN CAPITAL LETTER L (U+004C)
  • LATIN SMALL LETTER U (U+0075)
  • LATIN SMALL LETTER C WITH CARON (U+010D)
  • LATIN SMALL LETTER I (U+0069)
  • LATIN SMALL LETTER C WITH ACUTE (U+0107)

the sixth and final one is the big finish, and it shows how to assert a BER-encoded value ✨🌈

5. Security Considerations

okay bestie, this part is important 🚨 this memo describes a string representation of LDAP search filters. the representation itself has no known security implications, BUT LDAP search filters absolutely do πŸ’€ LDAP servers interpret them to pick out the entries that get their data returned. so LDAP servers should take care to protect the data they keep from unauthorized access πŸ”’

for more info, check the Security Considerations sections of [RFC4511] and [RFC4513] 🫢

6. Normative References

these are the references the spec leans on, so they're the important ones πŸ“š

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
  • [RFC4234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, October 2005.
  • [RFC4510] Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): Technical Specification Road Map", RFC 4510, June 2006.
  • [RFC4511] Sermersheim, J., Ed., "Lightweight Directory Access Protocol (LDAP): The Protocol", RFC 4511, June 2006.
  • [RFC4512] Zeilenga, K., "Lightweight Directory Access Protocol (LDAP): Directory Information Models", RFC 4512, June 2006.
  • [RFC4513] Harrison, R., Ed., "Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms", RFC 4513, June 2006.
  • [RFC4517] Legg, S., Ed., "Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules", RFC 4517, June 2006.
  • [Unicode] The Unicode Consortium, "The Unicode Standard, Version 3.2.0" is defined by "The Unicode Standard, Version 3.0" (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), as amended by the "Unicode Standard Annex #27: Unicode 3.1" (http://www.unicode.org/reports/tr27/) and by the "Unicode Standard Annex #28: Unicode 3.2."

7. Informative References

extra reading if you want to go deeper 🌷

  • [RFC4516] Smith, M., Ed. and T. Howes, "Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator", RFC 4516, June 2006.
  • [X.690] Specification of ASN.1 encoding rules: Basic, Canonical, and Distinguished Encoding Rules, ITU-T Recommendation X.690, 1994.

8. Acknowledgements

big thank you energy πŸ₯° this document replaces RFC 2254 by Tim Howes. RFC 2254 was a product of the IETF ASID Working Group.

the changes in this revised spec are based on discussions among the authors, discussions within the LDAP (v3) Revision Working Group (ldapbis), and discussions within other IETF Working Groups. the contributions of the individuals in those working groups are gratefully acknowledged 🫢✨

Appendix A: Changes Since RFC 2254 πŸ¦‹

A.1. Technical Changes

the big behind-the-scenes glow-up πŸ’…

  • Replaced the [ISO 10646] reference with [Unicode].
  • The following technical changes were made to the contents of the "String Search Filter Definition" section:
    • Added a statement that the string representation is a string of UTF-8-encoded Unicode characters.
    • Revised all of the ABNF to use common productions from [RFC4512].
    • Replaced the value rule with a new assertionvalue rule within the "simple", "extensible", and "substring" (initial, any, and final) rules. This matches a change made in [RFC4517].
    • Added "(" and ")" around the components of the <extensible> subproductions for clarity.
    • Revised the attr, matchingrule, and assertionvalue ABNF to more precisely reference productions from the [RFC4512] and [RFC4511] documents.
    • In the "String Search Filter Definition" section, replaced "greater" and "less" with "greaterorequal" and "lessorequal" to avoid confusion.
    • Introduced the valueencoding and associated normal and escaped rules to reduce the dependence on descriptive text. The normal production restricts filter strings to valid UTF-8 sequences.
    • Added a statement about expected behavior in light of RFC 2254's lack of a clear definition of "string representation."

A.2. Editorial Changes

the cosmetic touch-ups πŸŽ€

  • Changed the document title to include the "LDAP:" prefix.
  • IESG Note: removed the note about the lack of satisfactory mandatory authentication mechanisms.
  • Header and "Authors' Addresses" sections: added Mark Smith as the document editor and updated affiliation and contact information.
  • "Table of Contents" and "Intellectual Property" sections: added.
  • Copyright: updated per the latest IETF guidelines.
  • "Abstract" section: separated from the introductory material.
  • "Introduction" section: new section, separated from the Abstract. Updated the second paragraph to indicate that RFC 2254 is replaced by this document (instead of RFC 1960). Added a reference to the [RFC4510] document.
  • "LDAP Search Filter Definition" section: made corrections to the LDAP search filter ABNF so it matches the one used in [RFC4511].
  • Clarified the definition of 'value' (now 'assertionvalue') to take into account the fact that it is not precisely an AttributeAssertion from [RFC4511] Section 4.1.6 (special handling is required for some characters). Added a note that each octet of a character to be escaped is replaced by a backslash and two hex digits, which represent a single octet.
  • "Examples" section: added four additional examples: (seeAlso=), (cn:=Betty Rubble), (:1.2.3:=Wilma Flintstone), and (1.3.6.1.4.1.1466.0=\04\02\48\69). Replaced one occurrence of "a value" with "an assertion value". Corrected the description of the example (sn:dn:2.4.6.8.10:=Barney Rubble). Replaced the numeric OID in the first extensible match example with "caseExactMatch" to demonstrate use of the descriptive form. Used "DN" (uppercase) in the last extensible match example to remind the reader to treat the <dnattrs> production as case insensitive. Reworded the description of the fourth escaping mechanism example to avoid making assumptions about byte order. Added text to the fifth escaping mechanism example to spell out what the non-ASCII characters are in Unicode terms.
  • "Security Considerations" section: added references to [RFC4511] and [RFC4513].
  • "Normative References" section: renamed from "References" per new RFC guidelines. Changed from [1] style to [RFC4511] style throughout the document. Added entries for [Unicode], [RFC2119], [RFC4513], [RFC4512], and [RFC4510], and updated the UTF-8 reference. Replaced the RFC 822 reference with a reference to RFC 4234.
  • "Informative References" section: (new section) moved [X.690] to this section. Added a reference to [RFC4516].
  • "Acknowledgements" section: added.
  • "Appendix A: Changes Since RFC 2254" section: added.
  • Surrounded the names of all ABNF productions with "<" and ">" where they are used in descriptive text.
  • Replaced all occurrences of "LDAPv3" with "LDAP."

Authors' Addresses

meet the authors πŸ§‘β€πŸ’»

Mark Smith, Editor
Pearl Crescent, LLC
447 Marlpool Dr.
Saline, MI 48176
USA

Phone: +1 734 944-2856
EMail: mcs@pearlcrescent.com


Tim Howes
Opsware, Inc.
599 N. Mathilda Ave.
Sunnyvale, CA 94085
USA

Phone: +1 408 744-7509
EMail: howes@opsware.com
Copyright (C) The Internet Society (2006).

this document is subject to the rights, licenses and restrictions contained in BCP 78, 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 ✨

okay bestie, so the IETF is basically saying "we are NOT picking a side on whether any IP rights apply to the tech in this doc πŸ™…β€β™€οΈ." They also aren't claiming they went looking for any rights out there. πŸ’… If you want the rules on RFC rights stuff, check out BCP 78 and BCP 79 πŸ’–

copies of IPR disclosures sent to the IETF Secretariat are a thing, and so are any assurances of licenses that might be available. the same goes for the result of any attempt to get a general license or permission for implementers or users to use these proprietary rights. you can find all of that on the IETF online IPR repository at http://www.ietf.org/ipr πŸ—‚οΈβœ¨

the IETF also wants you to speak up πŸ“£ if you know about any copyrights, patents, patent applications, or other proprietary rights that might cover tech you'd need to implement this standard. just send it to ietf-ipr@ietf.org πŸ“¬πŸ’œ

Acknowledgement 🌸

funding for the RFC Editor function comes from the IETF Administrative Support Activity (IASA). the RFC Editor gets its money from there, and that's the whole tea πŸ«ΆπŸ“

πŸ“¦ where this page comes from