Work in progress
This site is in the process of being reviewed and updated.
Introduction
When an entry is added or modified, the server must validate that its attribute values are correct in respect with the schema rules and syntax. We also have to describe the way values should be compared when searching for entries. This page gather information related to those actions.
Usage in ADS
The Syntax checkers are used to enforce the correctness of attribute values. Some are embedded with the server (see below), some other are created by users. We will describe the mechanism which is used to declare a new SyntaxChecker, and how the current ones are designed.
SyntaxCheckers and the schema
We have what we call a MetaSchema which describes the objects used in the schema. The Syntax is itself one of these objects, and as so is described in RFC 4517, paragraph 3.3.8 :
3.3.18. LDAP Syntax Description A value of the LDAP Syntax Description syntax is the description of an LDAP syntax. The LDAP-specific encoding of a value of this syntax is defined by the <SyntaxDescription> rule in [RFC 4512]. The LDAP definition for the LDAP Syntax Description syntax is: ( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' ) The above LDAP definition for the LDAP Syntax Description syntax is itself a legal value of the LDAP Syntax Description syntax. The ASN.1 type corresponding to the LDAP Syntax Description syntax is defined as follows, assuming EXPLICIT TAGS: LDAPSyntaxDescription ::= SEQUENCE { identifier OBJECT IDENTIFIER, description DirectoryString { ub-schema } OPTIONAL } The DirectoryString parameterized ASN.1 type is defined in [X.520]. The value of ub-schema (an integer) is implementation defined. A non-normative definition appears in [X.520].
A user can inject a new Syntax using the above syntax, but it won't be enough for an attribute's value to be checked against it. However, this is a mandatory operation, and it should be done before injected the SyntaxChecker
First, create the Syntax, load it into the server, then write the checker,and inject it into the server.
Security issues
As we will allow a user to load a compiled class, we must use a specific classLoader to protect the server against malevolent code. The only users which will be allowed to inject a Syntax and a Syntax Checker must have authorization to do so.
Writing a Syntax Checker
This is pretty simple. We provide an abstract class which should be extended in order to obtain a valid SyntaxChecker. This abstract class implements an interface, which coe is given here :
/** * Used to validate values of a particular syntax. This interface does not * correlate to any LDAP or X.500 construct. It has been created as a means to * enforce a syntax within the Eve server. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public interface SyntaxChecker { /** * Gets the OID of the attribute syntax. * * @return the object identifier of the Syntax this SyntaxChecker validates */ String getSyntaxOid(); /** * Determines if the attribute's value conforms to the attribute syntax. * * @param value the value of some attribute with the syntax * @return true if the value is in the valid syntax, false otherwise */ boolean isValidSyntax( Object value ); /** * Asserts whether or not the attribute's value conforms to the attribute * syntax. * * @param value the value of some attribute with the syntax * @throws NamingException if the value does not conform to the attribute syntax. */ void assertSyntax( Object value ) throws NamingException; }
The abstract class is responsible to handle the getSyntaxOid() and assertSyntax() methods, so there are only two methods to implement :
- a constructor
- isValidSyntax() method
Last thing, you must declare an OID static member containing the OID for your SyntaxChecker, and call super( OID ) in your constructor.
Implementation sample
Let's have an example. Here is the implementation of the Boolean SyntaxChecker :
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.directory.shared.ldap.schema.syntax; import org.apache.directory.shared.ldap.util.StringTools; /** * A SyntaxChecker which verifies that a value is a Boolean according to RFC 4517. * * From RFC 4517 : * * Boolean = "TRUE" / "FALSE" * * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> * @version $Rev$ */ public class BooleanSyntaxChecker extends AbstractSyntaxChecker { /** The Syntax OID, according to RFC 4517, par. 3.3.3 */ private static final String SC_OID = "1.3.6.1.4.1.1466.115.121.1.7"; /** * * Creates a new instance of BooleanSyntaxChecker. * */ public BooleanSyntaxChecker() { super( SC_OID ); } /* (non-Javadoc) * @see org.apache.directory.shared.ldap.schema.SyntaxChecker#isValidSyntax(java.lang.Object) */ public boolean isValidSyntax( Object value ) { String strValue; if ( value == null ) { return false; } if ( value instanceof String ) { strValue = ( String ) value; } else if ( value instanceof byte[] ) { strValue = StringTools.utf8ToString( ( byte[] ) value ); } else { strValue = value.toString(); } if ( strValue.length() == 0 ) { return false; } return ( ( "TRUE".equals( strValue ) ) || ( "FALSE".equals( strValue ) ) ); } }
The OID is named SC_OID to avoid collision with the class OID which is used in some SyntaxCheckers
There are two constructors : one without parameters, and the other one with a String, which is the OID to set. Sometime, it is necessary to use the second one, for instance if one wants to derive a SyntaxChecker.
ADS Syntax Checkers List
Each attribute type is associated with a syntax which has to be checked. The RFC 4517 list all the mandatory syntax checkers we have to implement into ADS is given in the following table (the bold-blue elements are those which are related to the schema itself)
Here is an interesting message which describes all the incomplet syntaxes referenced by RFC 2252 :
http://www.openldap.org/lists/ietf-ldapbis/200102/msg00049.html
The marker is used to express that the Syntax may have been removed in RFC 4517 while it was used in RFC 2252, or that the implementation is incomplete. When a Syntax is not anymore present in RFC 4517, we have implemented it as a BinarySyntaxChecker (ie, accepting all the values)
name |
OID |
description |
implemented |
Java class |
---|---|---|---|---|
ACI Item |
1.3.6.1.4.1.1466.115.121.1.1 |
We will use the syntax defined by ADS : ACI Item grammar Duplicate values and missing elements are not controled... |
||
|
ACIItemSyntaxChecker |
|||
Access Point |
1.3.6.1.4.1.1466.115.121.1.2 |
<AccessPoint> ::= ( '(' <DistinguishedName> '#' <PresentationAddress> ')' ) | |
(binary) |
AccessPointSyntaxChecker |
Attribute Type Description |
1.3.6.1.4.1.1466.115.121.1.3 |
A value of the Attribute Type Description syntax |
|
AttributeTypeDescriptionSyntaxChecker |
Audio |
1.3.6.1.4.1.1466.115.121.1.4 |
The encoding of a value with Audio syntax is the octets of the value |
(binary) |
AudioSyntaxChecker |
Binary |
1.3.6.1.4.1.1466.115.121.1.5 |
This SyntaxChecker has been removed in RFC 4517 |
(binary) |
BinarySyntaxChecker |
Bit String |
1.3.6.1.4.1.1466.115.121.1.6 |
A value of the Bit String syntax is a sequence of binary digits |
|
BitStringSyntaxChecker |
Boolean |
1.3.6.1.4.1.1466.115.121.1.7 |
A value of the Boolean syntax is one of the |
|
BooleanSyntaxChecker |
Certificate |
1.3.6.1.4.1.1466.115.121.1.8 |
Because of the changes from X.509(1988) and X.509(1993) and additional changes to the ASN.1 |
(binary) |
CertificateSyntaxChecker |
Certificate List |
1.3.6.1.4.1.1466.115.121.1.9 |
Because of the incompatibility of the X.509(1988) and X.509(1993) definitions of revocation |
(binary) |
CertificateListSyntaxChecker |
Certificate Pair |
1.3.6.1.4.1.1466.115.121.1.10 |
Because the Certificate is being carried in binary, values in this syntax MUST only be |
(binary) |
CertificatePairSyntaxChecker |
Country String |
1.3.6.1.4.1.1466.115.121.1.11 |
A value of the Country String syntax is one of the two-character |
|
CountrySyntaxChecker |
DataQualitySyntax |
1.3.6.1.4.1.1466.115.121.1.13 |
<DataQualitySyntax> ::= <compKeyword> '#' <attrQuality> '#' <listQuality> [ '#' <description> ] |
(binary) |
DataQualitySyntaxSyntaxChecker |
Delivery Method |
1.3.6.1.4.1.1466.115.121.1.14 |
A value of the Delivery Method syntax is a sequence of items indicate, |
|
DeliveryMethodSyntaxChecker |
Directory String |
1.3.6.1.4.1.1466.115.121.1.15 |
A value of the Directory String syntax is a string of one or more |
|
DirectoryStringSyntaxChecker |
DIT Content Rule Description |
1.3.6.1.4.1.1466.115.121.1.16 |
A value of the DIT Content Rule Description syntax is the definition |
|
DITContentRuleDescriptionSyntaxChecker |
DIT Structure Rule Description |
1.3.6.1.4.1.1466.115.121.1.17 |
A value of the DIT Structure Rule Description syntax is the |
|
DITStructureRuleDescriptionSyntaxChecker |
DL Submit Permission |
1.3.6.1.4.1.1466.115.121.1.18 |
(no description found on the web...) |
(binary) |
DLSubmitPermissionSyntaxChecker |
DN |
1.3.6.1.4.1.1466.115.121.1.12 |
A value of the DN syntax is the (purported) distinguished name (DN) |
|
DNSyntaxChecker |
DSA Quality Syntax |
1.3.6.1.4.1.1466.115.121.1.19 |
<DsaQualitySyntax> ::= <DSAKeyword> [ '#' <description> ] |
|
DSAQualitySyntaxSyntaxChecker |
DSE Type |
1.3.6.1.4.1.1466.115.121.1.20 |
<DSEType> ::= '(' <DSEBitList> ')' |
|
DSETypeSyntaxChecker |
Enhanced Guide |
1.3.6.1.4.1.1466.115.121.1.21 |
A value of the Enhanced Guide syntax suggests criteria, which consist |
(binary) |
EnhancedGuideSyntaxChecker |
Facsimile Telephone Number |
1.3.6.1.4.1.1466.115.121.1.22 |
A value of the Facsimile Telephone Number syntax is a subscriber |
|
FacsimileTelephoneNumberSyntaxChecker |
Fax |
1.3.6.1.4.1.1466.115.121.1.23 |
A value of the Fax syntax is an image that is produced using the This syntax consider that the value is an OctetString, so a BinarSyntaxChecker will be used |
||
(binary) |
FaxSyntaxChecker |
|||
Generalized Time |
1.3.6.1.4.1.1466.115.121.1.24 |
A value of the Generalized Time syntax is a character string |
|
GeneralizedTimeSyntaxChecker |
Guide |
1.3.6.1.4.1.1466.115.121.1.25 |
A value of the Guide syntax suggests criteria, which consist of |
(binary) |
GuideSyntaxChecker |
IA5 String |
1.3.6.1.4.1.1466.115.121.1.26 |
A value of the IA5 String syntax is a string of zero, one, or more |
|
Ia5StringSyntaxChecker |
Integer |
1.3.6.1.4.1.1466.115.121.1.27 |
A value of the Integer syntax is a whole number of unlimited |
|
IntegerSyntaxChecker |
Jpeg |
1.3.6.1.4.1.1466.115.121.1.28 |
A value of the JPEG syntax is an image in the JPEG File Interchange |
|
JpegSyntaxChecker |
LDAP Syntax Description |
1.3.6.1.4.1.1466.115.121.1.54 |
A value of the LDAP Syntax Description syntax is the description of |
|
LdapSyntaxDescriptionSyntaxChecker |
Master And Shadow Access Points |
1.3.6.1.4.1.1466.115.121.1.29 |
<MasterAndShadowAccessPoints> ::= <MasterOrShadowAccessPoint> | |
(binary) |
MasterAndShadowAccessPointSyntaxChecker |
Matching Rule Description |
1.3.6.1.4.1.1466.115.121.1.30 |
A value of the Matching Rule Description syntax is |
|
MatchingRuleDescriptionSyntaxChecker |
Matching Rule Use Description |
1.3.6.1.4.1.1466.115.121.1.31 |
A value of the Matching Rule Use Description syntax indicates the |
|
MatchingRuleUseDescriptionSyntaxChecker |
Mail Preference |
1.3.6.1.4.1.1466.115.121.1.32 |
<mail-preference> ::= "NO-LISTS" | "ANY-LIST" | "PROFESSIONAL-LISTS" |
(removed) |
MailPreferenceSyntaxChecker |
MHS OR Address |
1.3.6.1.4.1.1466.115.121.1.33 |
No description so far (waiting for RFC 2156 to maturate)) |
(binary) |
MHSORAddressSyntaxChecker |
Name and Optional UID |
1.3.6.1.4.1.1466.115.121.1.34 |
A value of the Name and Optional UID syntax is the distinguished name |
|
NameAndOptionalUIDSyntaxChecker |
Name Form Description |
1.3.6.1.4.1.1466.115.121.1.35 |
A value of the Name Form Description syntax is the definition of a |
|
NameFormSyntaxChecker |
Numeric String |
1.3.6.1.4.1.1466.115.121.1.36 |
A value of the Numeric String syntax is a sequence of one or more |
|
NumericStringSyntaxChecker |
Object Class Description |
1.3.6.1.4.1.1466.115.121.1.37 |
A value of the Object Class Description syntax is the definition of |
|
ObjectClassDescriptionSyntaxChecker |
Octet String |
1.3.6.1.4.1.1466.115.121.1.40 |
RFC 2156 A value of the Octet String syntax is a sequence of zero, one, or |
|
OctetStringSyntaxChecker |
OID |
1.3.6.1.4.1.1466.115.121.1.38 |
A value of the OID syntax is an object identifier: a sequence of two |
|
OidSyntaxChecker |
Other Mailbox |
1.3.6.1.4.1.1466.115.121.1.39 |
A value of the Other Mailbox syntax identifies an electronic mailbox, |
|
OtherMailboxSyntaxChecker |
Postal Address |
1.3.6.1.4.1.1466.115.121.1.41 |
A value of the Postal Address syntax is a sequence of strings of one |
|
PostalAddressSyntaxChecker |
Protocol Information |
1.3.6.1.4.1.1466.115.121.1.42 |
<ProtocolInformation> ::= <NetworkAddress> <space> '#' <SetOfProtocolIdentifier> |
(binary) |
ProtocolInformationSyntaxChecker |
Presentation Address |
1.3.6.1.4.1.1466.115.121.1.43 |
RFC 1278 |
|
PresentationAddressSyntaxChecker |
Printable String |
1.3.6.1.4.1.1466.115.121.1.44 |
A value of the Printable String syntax is a string of one or more |
|
PrintableStringSyntaxChecker |
Subtree Specification |
1.3.6.1.4.1.1466.115.121.1.45 |
<SubtreeSpecification> ::= '(' [<localname>] '#' [<exclusionlist>] '#' [<minimum>] '#' [<maximum>] '#' [<refinement>] ')' |
|
SubreeSpecificationSyntaxChecker |
Supplier And Consumer |
1.3.6.1.4.1.1466.115.121.1.48 |
<SupplierAndConsumers> ::= <Supplier> '#' <Consumers> |
(binary) |
SupplierAndConsumerSyntaxChecker |
Supplier Information |
1.3.6.1.4.1.1466.115.121.1.46 |
<SupplierInformation> ::= |
(binary) |
SupplierInformationSyntaxChecker |
Supplier Or Consumer |
1.3.6.1.4.1.1466.115.121.1.47 |
<SupplierOrConsumer> ::= <Agreement> '#' <AccessPoint> |
(binary) |
SupplierOrConsumerSyntaxChecker |
Supported Algorithm |
1.3.6.1.4.1.1466.115.121.1.49 |
Clause 12.2.2.8, X.509 (3rd edition). It should be binary. |
(binary) |
SupportedAlgorithmSyntaxChecker |
Substring Assertion |
1.3.6.1.4.1.1466.115.121.1.58 |
A value of the Substring Assertion syntax is a sequence of zero, one, |
(binary) |
SubstringAssertionSyntaxChecker |
Telephone Number |
1.3.6.1.4.1.1466.115.121.1.50 |
A value of the Telephone Number syntax is a string of printable |
|
TelephoneNumberSyntaxChecker |
Teletex Terminal Identifier |
1.3.6.1.4.1.1466.115.121.1.51 |
A value of this syntax specifies the identifier and (optionally) |
|
TeletexTerminalIdentifierSyntaxChecker |
Telex Number |
1.3.6.1.4.1.1466.115.121.1.52 |
A value of the Telex Number syntax specifies the telex number, |
|
TelexNumberSyntaxChecker |
UTC Time |
1.3.6.1.4.1.1466.115.121.1.53 |
A value of the UTC Time syntax is a character string representing a |
(obsolete) |
UtcTimeSyntaxChecker |