RFC 2596

Use of Language Codes in LDAP

πŸ“… published May 1999, from ietf

RFC 2596: Use of Language Codes in LDAP πŸ¦‹

okay bestie, this is the one about how LDAP handles languages! 🌸 The title block says it's from May 1999 and it's a Standards Track doc. It's by M. Wahl (Innosoft International, Inc.) and T. Howes (Netscape Communications Corp.), published under the Network Working Group as Request for Comments: 2596. The title block here doesn't list anything it obsoletes or updates, so no drama there πŸ’…


Status of This Memo ✨

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

Copyright (C) The Internet Society (1999). All Rights Reserved.


1. Abstract 🌸

Okay so LDAP ([1]) is the protocol clients use to look up and change info in a distributed directory system. That info is stored as attributes [2] on entries, and most of those attributes are human-readable strings. It's so useful to be able to say what natural language an attribute value is written in πŸ‡«πŸ‡·πŸ‡―πŸ‡΅

This doc explains how language codes [3] get carried around in LDAP and how LDAP servers are supposed to read them. Every implementation MUST be prepared to accept language codes in the LDAP protocols. Servers might or might not be able to store attributes with language codes in the directory, and this doc doesn't say how to figure out which attributes can or can't have language codes 🫢

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 RFC 2119 [4] ✨

2. Language Codes πŸŽ€

Section 2 of RFC 1766 [3] describes the language code format that LDAP uses. The short version: it's a string of ASCII alphabetic characters and hyphens. Examples are "fr", "en-US" and "ja-JP" πŸ‡«πŸ‡·πŸ‡ΊπŸ‡ΈπŸ‡―πŸ‡΅

Language codes are case insensitive, so "en-us" is the same as "EN-US" and "en-US" πŸ’–

Implementations MUST NOT otherwise interpret the structure of the code when comparing two codes, and MUST treat them as simply strings of characters. Client and server implementations MUST allow any arbitrary string that follows the patterns in RFC 1766 to be used as a language code πŸ’…

3. Use of Language Codes in LDAP πŸ’œ

This section explains how LDAP implementations MUST interpret language codes when they're doing operations. Pay attention, this is the important part 😭

Generally, an attribute with a language code gets treated as a subtype of the attribute without one. But if a server doesn't support storing language codes with attribute values in the DIT, then it MUST always treat an attribute with a language code as an unrecognized attribute πŸ’€

3.1. Attribute Description πŸ¦‹

An attribute is made of a type, a list of options for that type, and a set of one or more values. In LDAP, the type and the options get combined into the AttributeDescription, which is defined in section 4.1.5 of [1]. It's represented as an attribute type name plus a possibly-empty list of options. One of those options ties a natural language to the values for that attribute ✨

     language-option = "lang-" lang-code

     lang-code = printable-ascii ; a code as defined in RFC 1766

A value can have multiple language options on it, so no biggie there 🌈

The language code doesn't change the character set encoding for string representations of DirectoryString syntax values. The UTF-8 representation of UniversalString (ISO 10646) is always used, no exceptions 🫢

Here are some valid AttributeDescriptions:

     givenName;lang-en-US
     CN;lang-ja

In LDAP and in this doc's examples, a directory attribute is shown as an AttributeDescription with a list of values. The data could be stored on the LDAP server in a different representation though, so keep that in mind 🧚

3.2. Distinguished Names and Relative Distinguished Names πŸ’…

No attribute description options are allowed in Distinguished Names or Relative Distinguished Names. So language codes MUST NOT be used in forming DNs. Not even a little πŸ™ˆ

3.3. Search Filter πŸ”

If a language code shows up in an AttributeDescription in a search filter, then only the attribute values in the directory that match the base attribute type or its subtype, the language code, and the assertion value will match the filter πŸ’–

For example, take an equality match filter of type "name;lang-en-US" with assertion value "Billy Ray", and run it against this directory entry:

     objectclass: top                     DOES NOT MATCH (wrong type)
     objectclass: person                  DOES NOT MATCH (wrong type)
     name;lang-EN-US: Billy Ray           MATCHES
     name;lang-EN-US: Billy Bob           DOES NOT MATCH (wrong value)
     CN;lang-en-us: Billy Ray                MATCHES
     CN;lang-EN-US;dynamic: Billy Ray     MATCHES
     CN;lang-en;dynamic: Billy Ray        DOES NOT MATCH (differing lang-)
     name: Billy Ray                      DOES NOT MATCH (no lang-)
     SN: Ray                              DOES NOT MATCH (wrong value)

(Quick note: "CN" and "SN" are subtypes of "name" 🌸)

Client implementors should however note that putting a language code in a search filter AttributeDescription will often filter out values you actually wanted, because the language code has to match exactly. For example, the filter (name;lang-en=Billy Ray) does NOT match the attribute name;lang-en-US: Billy Ray πŸ™ˆ

If the server doesn't support storing language codes with attribute values in the DIT, then any filter with a language code will always fail to match, since it's treated as an unrecognized attribute type. No error comes back for this. A presence filter evaluates to FALSE, and all the other forms evaluate to Undefined πŸ’€

If no language code is in the search filter, then only the base attribute type and the assertion value need to match the value in the directory ✨

For example, take an equality match filter of type "name" with assertion value "Billy Ray", and run it against this directory entry:

     objectclass: top                     DOES NOT MATCH (wrong type)
     objectclass: person                  DOES NOT MATCH (wrong type)
     name;lang-EN-US: Billy Ray           MATCHES
     name;lang-EN-US: Billy Bob           DOES NOT MATCH (wrong value)
     CN;lang-EN-US;dynamic: Billy Ray     MATCHES
     CN;lang-en;dynamic: Billy Ray        MATCHES
     name: Billy Ray                      MATCHES
     SN: Ray                              DOES NOT MATCH (wrong value)

So in general, clients SHOULD NOT use the language code option in AttributeDescription fields in search filters. πŸ¦‹

3.4. Compare πŸ’œ

A language code can show up in an AttributeDescription used in a compare request AttributeValueAssertion. Servers treat this the same way they treat a language code in a search filter with an equality match, which we just covered 🌈 If the entry has no attribute with the same subtype and language code, the server returns the noSuchAttributeType error 😭

For example, take a compare request of type "name" with assertion value "Johann", and run it against an entry that looks like this:

     objectclass: top
     objectclass: person
     givenName;lang-de-DE: Johann
     CN: Johann Sibelius
     SN: Sibelius

That'll make the server return compareTrue πŸŽ‰

But if the client sends a compare request of type "name;lang-de" with assertion value "Johann" against the same entry, the request fails with the noSuchAttributeType error πŸ’€

If the server doesn't support storing language codes with attribute values in the DIT, then any comparison with a language code will always fail to find an attribute type, and noSuchAttributeType gets returned πŸ™ˆ

So generally, clients SHOULD NOT use the language code option in AttributeDescription fields in the compare request. πŸ’…

Clients MAY provide language codes in AttributeDescription in the requested attribute list in a search request. ✨

If a language code is in an attribute description, then only the attribute values in a directory entry that have that same language code get returned. So if a client asks for an attribute "description;lang-en", the server MUST NOT return values of an attribute "description" or "description;lang-fr". Nope, not those πŸ™…β€β™€οΈ

Clients MAY provide in the attribute list multiple AttributeDescriptions that have the same base attribute type but different options. For example, a client MAY provide both "name;lang-en" and "name;lang-fr", and that lets an attribute with either language code come back. There's no need to also ask for "name" and "name;lang-en", since all subtypes of name would match "name" anyway 🧚

If a server doesn't support storing language codes with attribute values in the DIT, then any attribute descriptions in the list that include language codes get ignored, just like unknown attribute types πŸ«₯

If a request asks for all attributes, or asks for an attribute without a language code, then all attribute values come back no matter what their language code is 🌈

For example, say the client requests a "description" attribute, and a matching entry contains:

     objectclass: top
     objectclass: organization
     O: Software GmbH
     description: software
     description;lang-en: software products
     description;lang-de: Softwareprodukte
     postalAddress: Berlin 8001 Germany
     postalAddress;lang-de: Berlin 8001 Deutschland

The server will return:

     description: software
     description;lang-en: software products
     description;lang-de: Softwareprodukte

3.6. Add Operation πŸŽ€

Clients MAY provide language codes in AttributeDescription in attributes of a new entry to be created, but there's a catch: the client MUST NOT use language codes in the attribute value or values that form the RDN of the entry. ⚠️

A client MAY provide multiple attributes with the same attribute type and value, so long as each attribute has a different language code, and at most one attribute doesn't have a language code option πŸ’–

Servers that support storing language codes in the DIT MUST allow any attribute they recognize that has the Directory String syntax to have a language option associated with it. Servers SHOULD allow language options to be associated with other attributes. πŸ¦‹

For example, this is a legal request:

     objectclass: top
     objectclass: person
     objectclass: residentialPerson
     name: John Smith
     CN: John Smith
     CN;lang-en: John Smith
     SN: Smith
     streetAddress: 1 University Street
     streetAddress;lang-en: 1 University Street
     streetAddress;lang-fr: 1 rue Universite
     houseIdentifier;lang-fr: 9e etage

If a server doesn't support storing language codes with attribute values in the DIT, then it MUST treat an AttributeDescription with a language code as an unrecognized attribute. If the server forbids adding unrecognized attributes, then it MUST fail the add request with the appropriate result code. πŸ’€


to be continued, bestie! πŸ«ΆπŸ’– part 2 is coming soon ✨

3.7. Modify Operation πŸ’…

okay so, a client MAY tuck a language code into an AttributeDescription when it's part of a modification element in a modify operation. 🌸

bestie, this part is serious ngl. Attribute types and language codes MUST match exactly against the values stored in the directory. πŸ”₯ For example, if you're doing a "delete", then any stored values with a language code MUST have that code provided in the modify operation too, and any stored values WITHOUT a language code get NO language code provided. no mixing, no cap πŸ™…β€β™€οΈ

If the server can't store language codes with attribute values in the DIT, then it MUST treat an AttributeDescription with a language code as an unrecognized attribute, and it MUST fail the request with an appropriate result code. πŸ’€ rude but fair.

3.8. Diagnostic Messages πŸŽ€

Servers SHOULD only use printable ASCII characters in the errorMessage field, because not every client can display the full range of Unicode. πŸ™ˆ so keep those error messages simple and cute, bestie ✨

4. Differences from X.500(1997) πŸ¦‹

okay so X.500(1997) has its own thing called contexts for representing language tags, and LDAP does it differently. here's the tea:

  • a) an X.500 operation that specifies a language code on a value matches a value in the directory that has NO language code.
  • b) LDAP references RFC 1766, which lets new tags get registered with IANA. 🧚
  • c) LDAP does not allow language codes in distinguished names. πŸ™…β€β™€οΈ
  • d) X.500 describes subschema administration procedures for associating language codes with particular attribute types. πŸ“š

5. Security Considerations πŸ”

there are no known security considerations for this document. πŸ’– For LDAP security in general, check the security considerations sections of [1] and [2]. 🫢

6. Acknowledgements 🌈

this doc is a product of the IETF ASID and LDAPEXT working groups, and Martin Duerst gave lots of valuable comments on an earlier version. the whole squad πŸ‘‘

7. Bibliography πŸ“–

[1] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access Protocol (v3)", RFC 2251, December 1997.

[2] Wahl, M., Coulbeck, A., Howes, T. and S. Kille, "Lightweight X.500 Directory Access Protocol Attribute Syntax Definitions", RFC 2252, December 1997.

[3] Alvestrand, H.,"Tags for the Identification of Languages", RFC 1766, March 1995.

[4] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

8. Authors' Addresses 🧁

Mark Wahl
Innosoft International, Inc.
8911 Capital of Texas Hwy Suite 4140
Austin, TX 78759 USA

EMail:  M.Wahl@innosoft.com


Tim Howes
Netscape Communications Corp.
501 E. Middlefield Rd
Mountain View, CA 94043 USA

Phone:  +1 650 937-3419
EMail:   howes@netscape.com

Copyright (C) The Internet Society (1999). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS 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.

Acknowledgement πŸ™

Funding for the RFC Editor function is currently provided by the Internet Society. ✨

πŸ“¦ where this page comes from