This commit is contained in:
pvincent
2026-06-05 11:20:14 +00:00
commit 79d31f61c4
50 changed files with 6127 additions and 0 deletions
+582
View File
@@ -0,0 +1,582 @@
# OpenLDAP Core schema
# $OpenLDAP: pkg/ldap/servers/slapd/schema/core.schema,v 1.68.2.6 2005/01/20 17:01:18 kurt Exp $
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2005 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
#
## Portions Copyright (C) The Internet Society (1997-2003).
## 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.
#
#
# Includes LDAPv3 schema items from:
# RFC 2252/2256 (LDAPv3)
#
# Select standard track schema items:
# RFC 1274 (uid/dc)
# RFC 2079 (URI)
# RFC 2247 (dc/dcObject)
# RFC 2587 (PKI)
# RFC 2589 (Dynamic Directory Services)
#
# Select informational schema items:
# RFC 2377 (uidObject)
#
# Standard attribute types from RFC 2256
#
# system schema
#attributetype ( 2.5.4.0 NAME 'objectClass'
# DESC 'RFC2256: object classes of the entity'
# EQUALITY objectIdentifierMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
# system schema
#attributetype ( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' )
# DESC 'RFC2256: name of aliased object'
# EQUALITY distinguishedNameMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
attributetype ( 2.5.4.2 NAME 'knowledgeInformation'
DESC 'RFC2256: knowledge information'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
# system schema
#attributetype ( 2.5.4.3 NAME ( 'cn' 'commonName' )
# DESC 'RFC2256: common name(s) for which the entity is known by'
# SUP name )
attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
DESC 'RFC2256: last (family) name(s) for which the entity is known by'
SUP name )
attributetype ( 2.5.4.5 NAME 'serialNumber'
DESC 'RFC2256: serial number of the entity'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )
attributetype ( 2.5.4.6 NAME ( 'c' 'countryName' )
DESC 'RFC2256: ISO-3166 country 2-letter code'
EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.11
SINGLE-VALUE )
attributetype ( 2.5.4.7 NAME ( 'l' 'localityName' )
DESC 'RFC2256: locality which this object resides in'
SUP name )
attributetype ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' )
DESC 'RFC2256: state or province which this object resides in'
SUP name )
attributetype ( 2.5.4.9 NAME ( 'street' 'streetAddress' )
DESC 'RFC2256: street address of this object'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
attributetype ( 2.5.4.10 NAME ( 'o' 'organizationName' )
DESC 'RFC2256: organization this object belongs to'
SUP name )
attributetype ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' )
DESC 'RFC2256: organizational unit this object belongs to'
SUP name )
attributetype ( 2.5.4.12 NAME 'title'
DESC 'RFC2256: title associated with the entity'
SUP name )
attributetype ( 2.5.4.13 NAME 'description'
DESC 'RFC2256: descriptive information'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
# Obsoleted by enhancedSearchGuide
attributetype ( 2.5.4.14 NAME 'searchGuide'
DESC 'RFC2256: search guide, obsoleted by enhancedSearchGuide'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 )
attributetype ( 2.5.4.15 NAME 'businessCategory'
DESC 'RFC2256: business category'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
attributetype ( 2.5.4.16 NAME 'postalAddress'
DESC 'RFC2256: postal address'
EQUALITY caseIgnoreListMatch
SUBSTR caseIgnoreListSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
attributetype ( 2.5.4.17 NAME 'postalCode'
DESC 'RFC2256: postal code'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
attributetype ( 2.5.4.18 NAME 'postOfficeBox'
DESC 'RFC2256: Post Office Box'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
attributetype ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
DESC 'RFC2256: Physical Delivery Office Name'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
attributetype ( 2.5.4.20 NAME 'telephoneNumber'
DESC 'RFC2256: Telephone Number'
EQUALITY telephoneNumberMatch
SUBSTR telephoneNumberSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
attributetype ( 2.5.4.21 NAME 'telexNumber'
DESC 'RFC2256: Telex Number'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )
attributetype ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
DESC 'RFC2256: Teletex Terminal Identifier'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )
attributetype ( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' )
DESC 'RFC2256: Facsimile (Fax) Telephone Number'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
attributetype ( 2.5.4.24 NAME 'x121Address'
DESC 'RFC2256: X.121 Address'
EQUALITY numericStringMatch
SUBSTR numericStringSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )
attributetype ( 2.5.4.25 NAME 'internationaliSDNNumber'
DESC 'RFC2256: international ISDN number'
EQUALITY numericStringMatch
SUBSTR numericStringSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )
attributetype ( 2.5.4.26 NAME 'registeredAddress'
DESC 'RFC2256: registered postal address'
SUP postalAddress
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
attributetype ( 2.5.4.27 NAME 'destinationIndicator'
DESC 'RFC2256: destination indicator'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
attributetype ( 2.5.4.28 NAME 'preferredDeliveryMethod'
DESC 'RFC2256: preferred delivery method'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
SINGLE-VALUE )
attributetype ( 2.5.4.29 NAME 'presentationAddress'
DESC 'RFC2256: presentation address'
EQUALITY presentationAddressMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
SINGLE-VALUE )
attributetype ( 2.5.4.30 NAME 'supportedApplicationContext'
DESC 'RFC2256: supported application context'
EQUALITY objectIdentifierMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
attributetype ( 2.5.4.31 NAME 'member'
DESC 'RFC2256: member of a group'
SUP distinguishedName )
attributetype ( 2.5.4.32 NAME 'owner'
DESC 'RFC2256: owner (of the object)'
SUP distinguishedName )
attributetype ( 2.5.4.33 NAME 'roleOccupant'
DESC 'RFC2256: occupant of role'
SUP distinguishedName )
attributetype ( 2.5.4.34 NAME 'seeAlso'
DESC 'RFC2256: DN of related object'
SUP distinguishedName )
# system schema
#attributetype ( 2.5.4.35 NAME 'userPassword'
# DESC 'RFC2256/2307: password of user'
# EQUALITY octetStringMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
# Must be transferred using ;binary
# with certificateExactMatch rule (per X.509)
attributetype ( 2.5.4.36 NAME 'userCertificate'
DESC 'RFC2256: X.509 user certificate, use ;binary'
EQUALITY certificateExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
# Must be transferred using ;binary
# with certificateExactMatch rule (per X.509)
attributetype ( 2.5.4.37 NAME 'cACertificate'
DESC 'RFC2256: X.509 CA certificate, use ;binary'
EQUALITY certificateExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
# Must be transferred using ;binary
attributetype ( 2.5.4.38 NAME 'authorityRevocationList'
DESC 'RFC2256: X.509 authority revocation list, use ;binary'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
# Must be transferred using ;binary
attributetype ( 2.5.4.39 NAME 'certificateRevocationList'
DESC 'RFC2256: X.509 certificate revocation list, use ;binary'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
# Must be stored and requested in the binary form
attributetype ( 2.5.4.40 NAME 'crossCertificatePair'
DESC 'RFC2256: X.509 cross certificate pair, use ;binary'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 )
# 2.5.4.41 is defined above as it's used for subtyping
#attributetype ( 2.5.4.41 NAME 'name'
# EQUALITY caseIgnoreMatch
# SUBSTR caseIgnoreSubstringsMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
attributetype ( 2.5.4.42 NAME ( 'givenName' 'gn' )
DESC 'RFC2256: first name(s) for which the entity is known by'
SUP name )
attributetype ( 2.5.4.43 NAME 'initials'
DESC 'RFC2256: initials of some or all of names, but not the surname(s).'
SUP name )
attributetype ( 2.5.4.44 NAME 'generationQualifier'
DESC 'RFC2256: name qualifier indicating a generation'
SUP name )
attributetype ( 2.5.4.45 NAME 'x500UniqueIdentifier'
DESC 'RFC2256: X.500 unique identifier'
EQUALITY bitStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )
attributetype ( 2.5.4.46 NAME 'dnQualifier'
DESC 'RFC2256: DN qualifier'
EQUALITY caseIgnoreMatch
ORDERING caseIgnoreOrderingMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
attributetype ( 2.5.4.47 NAME 'enhancedSearchGuide'
DESC 'RFC2256: enhanced search guide'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 )
attributetype ( 2.5.4.48 NAME 'protocolInformation'
DESC 'RFC2256: protocol information'
EQUALITY protocolInformationMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )
# 2.5.4.49 is defined above as it's used for subtyping
#attributetype ( 2.5.4.49 NAME 'distinguishedName'
# EQUALITY distinguishedNameMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 2.5.4.50 NAME 'uniqueMember'
DESC 'RFC2256: unique member of a group'
EQUALITY uniqueMemberMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )
attributetype ( 2.5.4.51 NAME 'houseIdentifier'
DESC 'RFC2256: house identifier'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
# Must be transferred using ;binary
attributetype ( 2.5.4.52 NAME 'supportedAlgorithms'
DESC 'RFC2256: supported algorithms'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 )
# Must be transferred using ;binary
attributetype ( 2.5.4.53 NAME 'deltaRevocationList'
DESC 'RFC2256: delta revocation list; use ;binary'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
attributetype ( 2.5.4.54 NAME 'dmdName'
DESC 'RFC2256: name of DMD'
SUP name )
# Standard object classes from RFC2256
# system schema
#objectclass ( 2.5.6.1 NAME 'alias'
# DESC 'RFC2256: an alias'
# SUP top STRUCTURAL
# MUST aliasedObjectName )
objectclass ( 2.5.6.2 NAME 'country'
DESC 'RFC2256: a country'
SUP top STRUCTURAL
MUST c
MAY ( searchGuide $ description ) )
objectclass ( 2.5.6.3 NAME 'locality'
DESC 'RFC2256: a locality'
SUP top STRUCTURAL
MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) )
objectclass ( 2.5.6.4 NAME 'organization'
DESC 'RFC2256: an organization'
SUP top STRUCTURAL
MUST o
MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
x121Address $ registeredAddress $ destinationIndicator $
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
telephoneNumber $ internationaliSDNNumber $
facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )
objectclass ( 2.5.6.5 NAME 'organizationalUnit'
DESC 'RFC2256: an organizational unit'
SUP top STRUCTURAL
MUST ou
MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
x121Address $ registeredAddress $ destinationIndicator $
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
telephoneNumber $ internationaliSDNNumber $
facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )
objectclass ( 2.5.6.6 NAME 'person'
DESC 'RFC2256: a person'
SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
objectclass ( 2.5.6.7 NAME 'organizationalPerson'
DESC 'RFC2256: an organizational person'
SUP person STRUCTURAL
MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
telephoneNumber $ internationaliSDNNumber $
facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l ) )
objectclass ( 2.5.6.8 NAME 'organizationalRole'
DESC 'RFC2256: an organizational role'
SUP top STRUCTURAL
MUST cn
MAY ( x121Address $ registeredAddress $ destinationIndicator $
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
postOfficeBox $ postalCode $ postalAddress $
physicalDeliveryOfficeName $ ou $ st $ l $ description ) )
objectclass ( 2.5.6.9 NAME 'groupOfNames'
DESC 'RFC2256: a group of names (DNs)'
SUP top STRUCTURAL
MUST ( member $ cn )
MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
objectclass ( 2.5.6.10 NAME 'residentialPerson'
DESC 'RFC2256: an residential person'
SUP person STRUCTURAL
MUST l
MAY ( businessCategory $ x121Address $ registeredAddress $
destinationIndicator $ preferredDeliveryMethod $ telexNumber $
teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $
facsimileTelephoneNumber $ preferredDeliveryMethod $ street $
postOfficeBox $ postalCode $ postalAddress $
physicalDeliveryOfficeName $ st $ l ) )
objectclass ( 2.5.6.11 NAME 'applicationProcess'
DESC 'RFC2256: an application process'
SUP top STRUCTURAL
MUST cn
MAY ( seeAlso $ ou $ l $ description ) )
objectclass ( 2.5.6.12 NAME 'applicationEntity'
DESC 'RFC2256: an application entity'
SUP top STRUCTURAL
MUST ( presentationAddress $ cn )
MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $
description ) )
objectclass ( 2.5.6.13 NAME 'dSA'
DESC 'RFC2256: a directory system agent (a server)'
SUP applicationEntity STRUCTURAL
MAY knowledgeInformation )
objectclass ( 2.5.6.14 NAME 'device'
DESC 'RFC2256: a device'
SUP top STRUCTURAL
MUST cn
MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )
objectclass ( 2.5.6.15 NAME 'strongAuthenticationUser'
DESC 'RFC2256: a strong authentication user'
SUP top AUXILIARY
MUST userCertificate )
objectclass ( 2.5.6.16 NAME 'certificationAuthority'
DESC 'RFC2256: a certificate authority'
SUP top AUXILIARY
MUST ( authorityRevocationList $ certificateRevocationList $
cACertificate ) MAY crossCertificatePair )
objectclass ( 2.5.6.17 NAME 'groupOfUniqueNames'
DESC 'RFC2256: a group of unique names (DN and Unique Identifier)'
SUP top STRUCTURAL
MUST ( uniqueMember $ cn )
MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
objectclass ( 2.5.6.18 NAME 'userSecurityInformation'
DESC 'RFC2256: a user security information'
SUP top AUXILIARY
MAY ( supportedAlgorithms ) )
objectclass ( 2.5.6.16.2 NAME 'certificationAuthority-V2'
SUP certificationAuthority
AUXILIARY MAY ( deltaRevocationList ) )
objectclass ( 2.5.6.19 NAME 'cRLDistributionPoint'
SUP top STRUCTURAL
MUST ( cn )
MAY ( certificateRevocationList $ authorityRevocationList $
deltaRevocationList ) )
objectclass ( 2.5.6.20 NAME 'dmd'
SUP top STRUCTURAL
MUST ( dmdName )
MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
x121Address $ registeredAddress $ destinationIndicator $
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
street $ postOfficeBox $ postalCode $ postalAddress $
physicalDeliveryOfficeName $ st $ l $ description ) )
#
# Object Classes from RFC 2587
#
objectclass ( 2.5.6.21 NAME 'pkiUser'
DESC 'RFC2587: a PKI user'
SUP top AUXILIARY
MAY userCertificate )
objectclass ( 2.5.6.22 NAME 'pkiCA'
DESC 'RFC2587: PKI certificate authority'
SUP top AUXILIARY
MAY ( authorityRevocationList $ certificateRevocationList $
cACertificate $ crossCertificatePair ) )
objectclass ( 2.5.6.23 NAME 'deltaCRL'
DESC 'RFC2587: PKI user'
SUP top AUXILIARY
MAY deltaRevocationList )
#
# Standard Track URI label schema from RFC 2079
# system schema
#attributetype ( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI'
# DESC 'RFC2079: Uniform Resource Identifier with optional label'
# EQUALITY caseExactMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
objectclass ( 1.3.6.1.4.1.250.3.15 NAME 'labeledURIObject'
DESC 'RFC2079: object that contains the URI attribute type'
SUP top AUXILIARY
MAY labeledURI )
#
# Derived from RFC 1274, but with new "short names"
#
attributetype ( 0.9.2342.19200300.100.1.1
NAME ( 'uid' 'userid' )
DESC 'RFC1274: user identifier'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
attributetype ( 0.9.2342.19200300.100.1.3
NAME ( 'mail' 'rfc822Mailbox' )
DESC 'RFC1274: RFC822 Mailbox'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
DESC 'RFC1274: simple security object'
SUP top AUXILIARY
MUST userPassword )
# RFC 1274 + RFC 2247
attributetype ( 0.9.2342.19200300.100.1.25
NAME ( 'dc' 'domainComponent' )
DESC 'RFC1274/2247: domain component'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
# RFC 2247
objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'
DESC 'RFC2247: domain component object'
SUP top AUXILIARY MUST dc )
# RFC 2377
objectclass ( 1.3.6.1.1.3.1 NAME 'uidObject'
DESC 'RFC2377: uid object'
SUP top AUXILIARY MUST uid )
# From COSINE Pilot
attributetype ( 0.9.2342.19200300.100.1.37
NAME 'associatedDomain'
DESC 'RFC1274: domain associated with object'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# RFC 2459 -- deprecated in favor of 'mail' (in cosine.schema)
attributetype ( 1.2.840.113549.1.9.1
NAME ( 'email' 'emailAddress' 'pkcs9email' )
DESC 'RFC2459: legacy attribute for email addresses in DNs'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+149
View File
@@ -0,0 +1,149 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/dn'
class TestLdapDn < Test::Unit::TestCase
def setup
@dn = LDAP::Server::DN.new("cn=Steve Kille,o=Isode Limited,o=Companies,c=GB")
end
def test_find_first
assert_equal(nil, @dn.find_first("ou"))
assert_equal("Steve Kille", @dn.find_first("cn"))
assert_equal("Isode Limited", @dn.find_first("o"))
end
def test_find_last
assert_equal(nil, @dn.find_last("ou"))
assert_equal("Steve Kille", @dn.find_last("cn"))
assert_equal("Companies", @dn.find_last("o"))
end
def test_find
assert_equal([], @dn.find("ou"))
assert_equal(["Steve Kille"], @dn.find("cn"))
assert_equal(["Isode Limited", "Companies"], @dn.find("o"))
end
def test_find_nth
assert_equal(nil, @dn.find_nth("ou", 0))
assert_equal("Steve Kille", @dn.find_nth("cn", 0))
assert_equal(nil, @dn.find_nth("cn", 1))
assert_equal("Isode Limited", @dn.find_nth("o", 0))
assert_equal("Companies", @dn.find_nth("o", 1))
assert_equal(nil, @dn.find_nth("o", 2))
end
def test_start_with
assert @dn.start_with?("cn=Steve Kille")
assert @dn.start_with?("cn=Steve Kille, o=Isode Limited")
refute @dn.start_with?("cn=John Doe")
end
def test_start_with_format
assert @dn.start_with_format?("cn=Steve Kille")
assert @dn.start_with_format?("cn=foo, o=bar")
refute @dn.start_with_format?("c=GB")
refute @dn.start_with_format?("c=BE")
end
def test_end_with
assert @dn.end_with?("c=GB")
assert @dn.end_with?("o=Companies, c=GB")
refute @dn.end_with?("c=BE")
end
def test_end_with_format
assert @dn.end_with_format?("c=GB")
assert @dn.end_with_format?("o=foo, c=bar")
refute @dn.end_with_format?("cn=Steve Kille")
refute @dn.end_with_format?("cn=foo")
end
def test_equal
assert @dn.equal?("CN=Steve Kille, o=Isode Limited,O=Companies,c=GB")
refute @dn.equal?("cn=John Doe,o=Isode Limited,o=Companies,c=GB")
end
def test_equal_format
assert @dn.equal_format?("cn=Steve Kille,o=Isode Limited,o=Companies,c=GB")
assert @dn.equal_format?("cn=STEVE KILLE,o=ISODE LIMITED,o=COMPANIES,c=GB")
assert @dn.equal_format?("cn=foo,o=bar,o=baz,c=bat")
assert @dn.equal_format?("CN=foo,O=bar,O=baz,C=bat")
refute @dn.equal_format?("cn=foo,o=Isode Limited,c=GB")
end
def test_include
assert @dn.include?("cn=Steve Kille,o=Isode Limited,o=Companies,c=GB")
assert @dn.include?("cn=Steve Kille")
assert @dn.include?("o=Isode Limited")
assert @dn.include?("o=Isode Limited,o=Companies")
assert @dn.include?("c=GB")
refute @dn.include?("cn=John Doe,o=Isode Limited,o=Companies,c=GB")
refute @dn.include?("cn=Steve Kille,o=Isode Limited,c=GB")
end
def test_include_format
assert @dn.include_format?("cn=foo,o=bar,o=baz,c=bat")
assert @dn.include_format?("cn=foo")
assert @dn.include_format?("o=bar")
assert @dn.include_format?("o=bar,o=baz")
assert @dn.include_format?("c=bat")
refute @dn.include_format?("cn=foo,o=bar,c=bat")
refute @dn.include_format?("cn=bar,c=bat")
end
def test_parse
assert_equal @dn.parse("cn=:cn,o=:company,o=Companies,c=:country"),
{
:cn => 'Steve Kille',
:company => 'Isode Limited',
:country => 'GB'
}
assert_equal @dn.parse("cn=:cn,o=:company,o=:company,c=:country"),
{
:cn => 'Steve Kille',
:company => 'Companies',
:country => 'GB'
}
assert_empty @dn.parse("cn=Steve Kille,o=Isode Limited,o=Companies,c=GB")
assert_equal @dn.parse("cn=:cn,cn=Steve Kille,o=Isode Limited,o=Companies,c=GB"),
{
:cn => nil
}
assert_empty @dn.parse("o=Foo,o=Companies,c=GB")
assert_empty @dn.parse("cn=:cn,o=Foo,o=Companies,c=GB")
end
def test_each
answer = [
{ 'cn' => 'Steve Kille' },
{ 'o' => 'Isode Limited' },
{ 'o' => 'Companies' },
{ 'c' => 'GB' }
]
i = 0
@dn.each do |pair|
assert_equal pair, answer[i]
i += 1
end
end
def test_reverse_each
answer = [
{ 'c' => 'GB' },
{ 'o' => 'Companies' },
{ 'o' => 'Isode Limited' },
{ 'cn' => 'Steve Kille' }
]
i = 0
@dn.reverse_each do |pair|
assert_equal pair, answer[i]
i += 1
end
end
end
+289
View File
@@ -0,0 +1,289 @@
require File.dirname(__FILE__) + '/test_helper'
Thread.abort_on_exception = true
# This test suite requires the ruby-ldap client library to be installed.
#
# Unfortunately, this library is not ruby thread-safe (it blocks until
# it gets a response). Hence we have to fork a child to perform the actual
# LDAP requests, which is nasty. However, it does give us a completely
# independent source of LDAP packets to try.
require 'ldap/server/operation'
require 'ldap/server/server'
require 'net/ldap'
# We subclass the Operation class, overriding the methods to do what we need
class MockOperation < LDAP::Server::Operation
def initialize(connection, messageId)
super(connection, messageId)
@@lastop = [:connect]
end
def simple_bind(version, user, pass)
@@lastop = [:simple_bind, version.to_i, user, pass]
end
def search(basedn, scope, deref, filter)
@@lastop = [:search, basedn, scope.to_i, deref.to_i, filter, @attributes]
send_SearchResultEntry("cn=foo", {"a"=>["1","2"], "b"=>"boing"})
send_SearchResultEntry("cn=bar", {"a"=>["3","4","5"], "b"=>"wibble"})
end
def add(dn, av)
@@lastop = [:add, dn, av]
end
def del(dn)
@@lastop = [:del, dn]
end
def modify(dn, ops)
@@lastop = [:modify, dn, ops]
end
def modifydn(dn, newrdn, deleteoldrdn, newSuperior)
@@lastop = [:modifydn, dn, newrdn, deleteoldrdn, newSuperior]
end
def compare(dn, attr, val)
@@lastop = [:compare, dn, attr, val]
return val != "false"
end
def self.lastop
@@lastop
end
end
class TestLdap < Test::Unit::TestCase
HOST = '127.0.0.1'
PORT = 1389
def start_client
in_ = Queue.new
out = Queue.new
Thread.new do
do_child(in_, out)
end
return in_, out
end
def ensure_server_started
@serv || start_server
end
def start_server(opts={})
# back to a single process (the parent). Now we start our
# listener thread
@serv = LDAP::Server.new({
:bindaddr => '127.0.0.1',
:port => PORT,
:nodelay => true,
:operation_class => MockOperation,
}.merge(opts))
@serv.run_tcpserver
end
def setup
@client = nil
@serv = nil
end
def teardown
if @serv
@serv.stop
@serv = nil
end
if @client
# @client.close
@client = nil
end
end
def conn
ensure_server_started
@client ||= Net::LDAP.new(host: HOST, port: PORT)
end
def test_bind2
pend("net-ldap gem doesn't support protocol 2")
# TODO: Net::LDAP only supports protocol 3
conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 2)
conn.auth("foo","bar")
conn.bind
assert_equal([:simple_bind, 2, "foo", "bar"], MockOperation.lastop)
# cannot bind any more; ldap client library says "already binded." (sic)
end
def test_bind3
conn.auth("foo","bar")
conn.bind
assert_equal([:simple_bind, 3, "foo", "bar"], MockOperation.lastop)
# cannot bind any more; ldap client library says "already binded." (sic)
end
def test_add
entry1 = {
objectclass: ['top', 'domain'],
o: ['TTSKY.NET'],
dc: ['localhost'],
}
conn.add(dn: "dc=localhost, dc=domain", attributes: entry1)
assert_equal([:add, "dc=localhost, dc=domain", {
'objectclass'=>['top', 'domain'],
'o'=>['TTSKY.NET'],
'dc'=>['localhost'],
}], MockOperation.lastop)
entry2 = {
objectclass: ['top', 'person'],
cn: ['Takaaki Tateishi'],
sn: ['ttate','Tateishi', "zero\000zero"],
}
conn.add(dn: "cn=Takaaki Tateishi, dc=localhost, dc=localdomain", attributes: entry2)
assert_equal([:add, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain", {
'objectclass'=>['top', 'person'],
'cn'=>['Takaaki Tateishi'],
'sn'=>['ttate','Tateishi',"zero\000zero"],
}], MockOperation.lastop)
end
def test_del
conn.delete(dn: "cn=Takaaki-Tateishi, dc=localhost, dc=localdomain")
assert_equal([:del, "cn=Takaaki-Tateishi, dc=localhost, dc=localdomain"], MockOperation.lastop)
end
def test_compare
pend("net-ldap gem doesn't support compare requests")
res = conn.compare("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "Takaaki Tateishi")
assert_equal([:compare, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "Takaaki Tateishi"], MockOperation.lastop)
assert res
res = conn.compare("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "false")
assert_equal([:compare, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "false"], MockOperation.lastop)
refute res
end
def test_modrdn
conn.modify_rdn(olddn: "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
newrdn: "cn=Takaaki-Tateishi",
delete_attributes: true)
assert_equal([:modifydn, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn=Takaaki-Tateishi", true, nil], MockOperation.lastop)
# FIXME: ruby-ldap doesn't support the four-argument form
end
def test_modify
entry = [
[:add, :objectclass, ['top', 'domain']],
[:delete, :o, []],
[:replace, :dc, ['localhost']],
]
conn.modify(dn: "dc=localhost, dc=domain", operations: entry)
assert_equal([:modify, "dc=localhost, dc=domain", {
'objectclass' => [:add, 'top', 'domain'],
'o' => [:delete],
'dc' => [:replace, 'localhost'],
}], MockOperation.lastop)
end
def test_search
res = []
conn.search(base: "dc=localhost, dc=localdomain",
scope: Net::LDAP::SearchScope_WholeSubtree,
filter: "(objectclass=*)") do |e|
res << e.to_h
end
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::WholeSubtree,
LDAP::Server::NeverDerefAliases,
[:true], []], MockOperation.lastop)
exp = [
{a: ["1","2"], b: ["boing"], dn: ["cn=foo"]},
{a: ["3","4","5"], b: ["wibble"], dn: ["cn=bar"]},
]
assert_equal exp, res
res = []
# FIXME: ruby-ldap doesn't seem to allow DEREF options to be set
conn.search(base: "dc=localhost, dc=localdomain",
scope: Net::LDAP::SearchScope_BaseObject,
filter: "(&(cn=foo)(objectclass=*)(|(!(sn=*))(ou>=baz)(o<=z)(cn=*and*er)))",
attributes: [:a, :b]) do |e|
res << e.to_h
end
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::BaseObject,
LDAP::Server::NeverDerefAliases,
[:and, [:eq, "cn", nil, "foo"],
[:or, [:not, [:present, "sn"]],
[:ge, "ou", nil, "baz"],
[:le, "o", nil, "z"],
[:substrings, "cn", nil, nil, "and", "er"],
],
], ["a","b"]], MockOperation.lastop)
assert_equal exp, res
end
def test_search_with_range
res = []
conn.search(base: "dc=localhost, dc=localdomain",
scope: Net::LDAP::SearchScope_BaseObject,
attributes: ["a;range=1-2", "b"]) do |e|
res << e.to_h
end
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::BaseObject,
LDAP::Server::NeverDerefAliases,
[:true], ["a","b"]], MockOperation.lastop)
exp = [
{a: [], "a;range=1-*": ["2"], b: ["boing"], dn: ["cn=foo"]},
{a: [], "a;range=1-2": ["4","5"], b: ["wibble"], dn: ["cn=bar"]},
]
assert_equal exp, res
end
def test_search_with_range_limit
start_server(attribute_range_limit: 2)
res = []
conn.search(base: "dc=localhost, dc=localdomain",
scope: Net::LDAP::SearchScope_WholeSubtree,
filter: "(objectclass=*)") do |e|
res << e.to_h
end
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::WholeSubtree,
LDAP::Server::NeverDerefAliases,
[:true], []], MockOperation.lastop)
exp = [
{a: ["1","2"], b: ["boing"], dn: ["cn=foo"]},
{a: [], "a;range=0-1": ["3","4"], b: ["wibble"], dn: ["cn=bar"]},
]
assert_equal exp, res
end
end
+107
View File
@@ -0,0 +1,107 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/filter'
class FilterTest < Test::Unit::TestCase
AV1 = {
"foo" => ["abc","def"],
"bar" => ["wibblespong"],
}
def test_bad
assert_raises(LDAP::ResultError::OperationsError) {
LDAP::Server::Filter.run([:wibbly], AV1)
}
end
def test_const
assert_equal(true, LDAP::Server::Filter.run([:true], AV1))
assert_equal(false, LDAP::Server::Filter.run([:false], AV1))
assert_equal(nil, LDAP::Server::Filter.run([:undef], AV1))
end
def test_present
assert_equal(true, LDAP::Server::Filter.run([:present,"foo"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:present,"zog"], AV1))
end
def test_eq
assert_equal(true, LDAP::Server::Filter.run([:eq,"foo",nil,"abc"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:eq,"foo",nil,"def"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:eq,"foo",nil,"ghi"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:eq,"xyz",nil,"abc"], AV1))
end
def test_eq_case
c = LDAP::Server::MatchingRule.find('2.5.13.2')
assert_equal(true, LDAP::Server::Filter.run([:eq,"foo",c,"ABC"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:eq,"foo",c,"DeF"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:eq,"foo",c,"ghi"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:eq,"xyz",c,"abc"], AV1))
end
def test_not
assert_equal(false, LDAP::Server::Filter.run([:not,[:eq,"foo",nil,"abc"]], AV1))
assert_equal(false, LDAP::Server::Filter.run([:not,[:eq,"foo",nil,"def"]], AV1))
assert_equal(true, LDAP::Server::Filter.run([:not,[:eq,"foo",nil,"ghi"]], AV1))
assert_equal(true, LDAP::Server::Filter.run([:not,[:eq,"xyz",nil,"abc"]], AV1))
end
def test_ge
assert_equal(true, LDAP::Server::Filter.run([:ge,"foo",nil,"ccc"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:ge,"foo",nil,"def"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:ge,"foo",nil,"deg"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:ge,"xyz",nil,"abc"], AV1))
end
def test_le
assert_equal(true, LDAP::Server::Filter.run([:le,"foo",nil,"ccc"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:le,"foo",nil,"abc"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:le,"foo",nil,"abb"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:le,"xyz",nil,"abc"], AV1))
end
def test_substrings
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,"a",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,"def",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,"bc",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,"az",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,"",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"zzz",nil,"",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"a",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"e",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"ba",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"az",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"c"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"ef"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"ab"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"foo",nil,nil,"e"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"bar",nil,"wib","ong"], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"bar",nil,"",""], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"bar",nil,"wib","ble"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"bar",nil,"sp","ong"], AV1))
end
def test_substr_case
c = LDAP::Server::MatchingRule.find('1.3.6.1.4.1.1466.109.114.3')
assert_equal(true, LDAP::Server::Filter.run([:substrings,"bar",c,"WIB",nil], AV1))
assert_equal(true, LDAP::Server::Filter.run([:substrings,"bar",c,"WIB","lES","ong"], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"bar",c,"SPONG",nil], AV1))
assert_equal(false, LDAP::Server::Filter.run([:substrings,"xyz",c,"wib",nil], AV1))
end
def test_and
assert_equal(true, LDAP::Server::Filter.run([:and,[:true],[:true]], AV1))
assert_equal(false, LDAP::Server::Filter.run([:and,[:false],[:true]], AV1))
assert_equal(false, LDAP::Server::Filter.run([:and,[:true],[:false]], AV1))
assert_equal(false, LDAP::Server::Filter.run([:and,[:false],[:false]], AV1))
end
def test_or
assert_equal(true, LDAP::Server::Filter.run([:or,[:true],[:true]], AV1))
assert_equal(true, LDAP::Server::Filter.run([:or,[:false],[:true]], AV1))
assert_equal(true, LDAP::Server::Filter.run([:or,[:true],[:false]], AV1))
assert_equal(false, LDAP::Server::Filter.run([:or,[:false],[:false]], AV1))
end
end
+59
View File
@@ -0,0 +1,59 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/match'
class MatchTest < Test::Unit::TestCase
def test_caseIgnoreOrderingMatch
s = LDAP::Server::MatchingRule.find("2.5.13.3")
assert_equal(LDAP::Server::MatchingRule, s.class)
assert_equal("caseIgnoreOrderingMatch", s.name)
assert_equal("( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", s.to_def)
assert_equal(true, s.le(["foobar","wibble"], "ghi"))
assert_equal(true, s.le(["FOOBAR","WIBBLE"], "ghi"))
assert_equal(true, s.le(["foobar","wibble"], "GHI"))
assert_equal(true, s.le(["FOOBAR","WIBBLE"], "GHI"))
assert_equal(false, s.le(["foobar","wibble"], "fab"))
assert_equal(false, s.le(["FOOBAR","WIBBLE"], "fab"))
assert_equal(false, s.le(["foobar","wibble"], "FAB"))
assert_equal(false, s.le(["FOOBAR","WIBBLE"], "FAB"))
end
def test_caseIgnoreSubstringsMatch
s = LDAP::Server::MatchingRule.find("2.5.13.4")
assert_equal(LDAP::Server::MatchingRule, s.class)
assert_equal("caseIgnoreSubstringsMatch", s.name)
assert_equal(true, s.substrings(["foobar","wibble"], nil, "oob", nil))
assert_equal(true, s.substrings(["foobar","wibble"], nil, "foo", nil))
assert_equal(true, s.substrings(["foobar","wibble"], nil, "bar", nil))
assert_equal(true, s.substrings(["foobar","wibble"], "wib", nil))
assert_equal(true, s.substrings(["foobar","wibble"], nil, "ar"))
assert_equal(true, s.substrings(["foobar","wibble"], "wib", "ble"))
assert_equal(true, s.substrings(["foobar","wibble"], nil, "oo", "bar"))
assert_equal(false, s.substrings(["foobar","wibble"], nil, "ooz", nil))
assert_equal(false, s.substrings(["foobar","wibble"], nil, "foz", nil))
assert_equal(false, s.substrings(["foobar","wibble"], nil, "zar", nil))
assert_equal(false, s.substrings(["foobar","wibble"], "bar", nil))
assert_equal(false, s.substrings(["foobar","wibble"], nil, "oob"))
assert_equal(false, s.substrings(["foobar","wibble"], "foo", "ble"))
assert_equal(false, s.substrings(["foobar","wibble"], "foo", "obar"))
end
def test_unknown
s = LDAP::Server::MatchingRule.find("1.4.7.1")
assert_equal(nil, s) ## this may change to generate a default object
end
def test_nil
s = LDAP::Server::MatchingRule.find(nil)
assert_equal(nil, s)
end
def test_from_def
s = LDAP::Server::MatchingRule.from_def("( 1.2.3 NAME ( 'wibble' 'bibble' ) DESC 'foobar' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )")
assert_equal("1.2.3", s.oid)
assert_equal(['wibble','bibble'], s.names)
assert_equal('wibble', s.to_s)
assert_equal("foobar", s.desc)
assert_equal("IA5 String", s.syntax.desc)
end
end
+113
View File
@@ -0,0 +1,113 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/schema'
require 'ldap/server/match'
class SchemaTest < Test::Unit::TestCase
def test_parse_attr
attr = <<ATTR
( 2.5.4.3 NAME 'cn' OBSOLETE EQUALITY 1.2.3 ORDERING 4.5.678 SUBSTR 9.1.1 SYNTAX 4.3.2{58} SINGLE-VALUE COLLECTIVE NO-USER-MODIFICATION USAGE userApplications )
ATTR
a = LDAP::Server::Schema::AttributeType.new(attr)
assert_equal("2.5.4.3", a.oid)
assert_equal("cn", a.name)
assert_equal(["cn"], a.names)
assert(a.obsolete)
assert_equal("1.2.3", a.equality)
assert_equal("4.5.678", a.ordering)
assert_equal("9.1.1", a.substr)
assert_equal("4.3.2", a.syntax)
assert_equal(58, a.maxlen)
assert(a.singlevalue)
assert(a.collective)
assert(a.nousermod)
assert_equal(:userApplications, a.usage)
assert_equal(attr.chomp, a.to_def)
attr = <<ATTR
( 2.5.4.3 NAME ( 'cn' 'commonName' ) DESC 'RFC2256: common name(s) for which the entity is known by' SUP name )
ATTR
a = LDAP::Server::Schema::AttributeType.new(attr)
assert_equal("2.5.4.3", a.oid)
assert_equal("cn", a.name)
assert_equal(["cn", "commonName"], a.names)
assert_equal("RFC2256: common name(s) for which the entity is known by", a.desc)
assert(! a.obsolete)
assert_equal("name", a.sup)
assert(! a.singlevalue)
assert(! a.collective)
assert(! a.nousermod)
assert_equal(attr.chomp, a.to_def)
end
def test_parse_objectclass
oc = <<OC
( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' DESC 'RFC1274: simple security object' SUP top AUXILIARY MUST userPassword )
OC
a = LDAP::Server::Schema::ObjectClass.new(oc)
assert_equal("0.9.2342.19200300.100.4.19", a.oid)
assert_equal("simpleSecurityObject", a.name)
assert_equal(["simpleSecurityObject"], a.names)
assert(! a.obsolete)
assert_equal("RFC1274: simple security object", a.desc)
assert_equal(["top"], a.sup)
assert_equal(:auxiliary, a.struct)
assert_equal(["userPassword"], a.must)
assert_equal([], a.may)
assert_equal(oc.chomp, a.to_def)
oc = <<OC
( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
OC
a = LDAP::Server::Schema::ObjectClass.new(oc)
assert_equal("2.5.6.6", a.oid)
assert_equal("person", a.name)
assert_equal(["person"], a.names)
assert(! a.obsolete)
assert_equal("RFC2256: a person", a.desc)
assert_equal(["top"], a.sup)
assert_equal(:structural, a.struct)
assert_equal(["sn", "cn"], a.must)
assert_equal(["userPassword","telephoneNumber","seeAlso","description"], a.may)
assert_equal(oc.chomp, a.to_def)
end
def test_loadschema
s = LDAP::Server::Schema.new
s.load_system
s.load_file(File.dirname(__FILE__) + "/core.schema")
s.resolve_oids
a = s.find_attrtype("objectclass")
assert_equal("objectClass", a.name)
a = s.find_attrtype("COMMONNAME")
assert_equal(LDAP::Server::Schema::AttributeType, a.class)
assert_equal("caseIgnoreMatch", a.equality.to_s)
assert_equal(LDAP::Server::MatchingRule, a.equality.class)
assert_equal("caseIgnoreSubstringsMatch", a.substr.to_s)
assert_equal(LDAP::Server::MatchingRule, a.substr.class)
assert_equal("1.3.6.1.4.1.1466.115.121.1.15", a.syntax.to_s)
assert_equal(LDAP::Server::Syntax, a.syntax.class)
assert_equal("cn", a.name)
a = s.find_attrtype("COUNTRYname")
assert_equal("c", a.name)
# I modified core.schema so that countryName has the appropriate syntax
assert(a.syntax.match("GB"))
assert(!a.syntax.match("ABC"))
end
def test_backwards_api
s = LDAP::Server::Schema.new
s.load_system
assert_equal(['subschema','OpenLDAProotDSE','referral','alias','extensibleObject','top'].sort,
s.names('objectClasses').sort)
assert_equal(['dITStructureRules','nameForms','ditContentRules','objectClasses','attributeTypes','matchingRules','matchingRuleUse'],
s.attr('subschema', 'may'))
assert_equal([], s.attr('subschema', 'must'))
assert_equal(nil, s.attr('foo', 'must'))
assert_equal(['top'], s.sup('extensibleObject'))
end
def test_validate
# FIXME
end
end
+40
View File
@@ -0,0 +1,40 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/syntax'
class SyntaxTest < Test::Unit::TestCase
def test_integer
s = LDAP::Server::Syntax.find("1.3.6.1.4.1.1466.115.121.1.27")
assert_equal(LDAP::Server::Syntax, s.class)
assert_equal("Integer", s.desc)
assert_equal("( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", s.to_def)
assert(!s.nhr)
assert(s.match("123"))
assert(!s.match("12A"))
assert_equal(123, s.value_from_s("123"))
assert_equal("456", s.value_to_s(456))
assert_equal("789", s.value_to_s("789"))
end
def test_unknown
s = LDAP::Server::Syntax.find("1.4.7.1")
assert_equal(LDAP::Server::Syntax, s.class)
assert_equal("1.4.7.1", s.oid)
assert_equal("1.4.7.1", s.to_s)
assert_equal("( 1.4.7.1 )", s.to_def)
assert_equal("false", s.value_to_s(false)) # generic value_to_s
assert_equal("true", s.value_from_s("true")) # generic value_from_s
assert(s.match("123")) # match anything
end
def test_nil
s = LDAP::Server::Syntax.find(nil)
assert_equal(nil, s)
end
def test_from_def
s = LDAP::Server::Syntax.from_def("( 1.2.3 DESC 'foobar' )")
assert_equal("1.2.3", s.oid)
assert_equal("foobar", s.desc)
end
end
+2
View File
@@ -0,0 +1,2 @@
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'test/unit'
+60
View File
@@ -0,0 +1,60 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/trie'
class TestTrie < Test::Unit::TestCase
def test_trie_base
trie = LDAP::Server::Trie.new do |trie|
trie.insert 'ou=Users,dc=mydomain,dc=com,op=bind', 'UsersBindTree'
trie.insert 'ou=Users,dc=mydomain,dc=com,op=search', 'UsersSearchTree'
trie.insert 'ou=Groups,dc=mydomain,dc=com,op=search', 'GroupsSearchTree'
trie.insert 'dc=mydomain,dc=com,op=search', 'RootSearchValue'
trie.insert 'dc=com,op=search', ''
end
assert_equal trie.lookup('ou=Users,dc=mydomain,dc=com,op=bind'), 'UsersBindTree'
assert_equal trie.lookup('ou=Users,dc=mydomain,dc=com,op=search'), 'UsersSearchTree'
assert_equal trie.lookup('ou=Groups,dc=mydomain,dc=com,op=search'), 'GroupsSearchTree'
assert_equal trie.lookup('dc=mydomain,dc=com,op=search'), 'RootSearchValue'
assert_equal trie.lookup('dc=com,op=search'), ''
assert_nil trie.lookup 'dc=mydomain,dc=com,op=bind'
assert_nil trie.lookup nil
assert_raises LDAP::Server::Trie::NodeNotFoundError do
trie.lookup 'ou=DoesNotExist,dc=mydomain,dc=com,op=search'
end
end
def test_trie_wildcard
trie = LDAP::Server::Trie.new do |trie|
trie.insert 'uid=:uid,ou=Users,dc=mydomain,dc=com', 'SpecificUsers'
trie.insert 'ou=Users,dc=mydomain,dc=com', 'Users'
trie.insert 'ou=Users,dc=:domain,dc=:tld', 'Domain'
end
assert_equal trie.lookup('uid=john,ou=Users,dc=mydomain,dc=com'), 'SpecificUsers'
assert_equal trie.lookup('uid=jane,ou=Users,dc=mydomain,dc=com'), 'SpecificUsers'
assert_equal trie.lookup('ou=Users,dc=mydomain,dc=com'), 'Users'
assert_equal trie.lookup('ou=Users,dc=otherdomain,dc=net'), 'Domain'
end
def test_trie_match
trie = LDAP::Server::Trie.new do |trie|
trie.insert 'uid=:uid,ou=Users,dc=mydomain,dc=com', 'SpecificUsers'
trie.insert 'ou=Users,dc=mydomain,dc=com', 'Users'
trie.insert 'dc=mydomain,dc=com', 'Domains'
end
assert_equal trie.match('uid=john,ou=Users,dc=mydomain,dc=com'),
['uid=:uid,ou=Users,dc=mydomain,dc=com', 'SpecificUsers']
assert_equal trie.match('cn=john,ou=Users,dc=mydomain,dc=com'),
['ou=Users,dc=mydomain,dc=com', 'Users']
assert_equal trie.match('ou=Users,dc=mydomain,dc=com'),
['ou=Users,dc=mydomain,dc=com', 'Users']
assert_equal trie.match('dc=mydomain,dc=com'),
['dc=mydomain,dc=com', 'Domains']
assert_equal trie.match('dc=otherdomain,dc=com'),
[nil, nil]
end
end
+51
View File
@@ -0,0 +1,51 @@
require File.dirname(__FILE__) + '/test_helper'
require 'ldap/server/util'
class TestLdapUtil < Test::Unit::TestCase
def test_split_dn
# examples from RFC 2253
assert_equal(
[{"cn"=>"Steve Kille"},{"o"=>"Isode Limited"},{"c"=>"GB"}],
LDAP::Server::Operation.split_dn("CN=Steve Kille , O=Isode Limited;C=GB")
)
assert_equal(
[{"ou"=>"Sales","cn"=>"J. Smith"},{"o"=>"Widget Inc."},{"c"=>"US"}],
LDAP::Server::Operation.split_dn("OU=Sales+CN=J. Smith,O=Widget Inc.,C=US")
)
assert_equal(
[{"cn"=>"L. Eagle"},{"o"=>"Sue, Grabbit and Runn"},{"c"=>"GB"}],
LDAP::Server::Operation.split_dn("CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB")
)
assert_equal(
[{"cn"=>"Before\rAfter"},{"o"=>"Test"},{"c"=>"GB"}],
LDAP::Server::Operation.split_dn("CN=Before\\0DAfter,O=Test,C=GB")
)
res = LDAP::Server::Operation.split_dn("SN=Lu\\C4\\8Di\\C4\\87")
assert_equal([{ "sn" => "Lu\xc4\x8di\xc4\x87".force_encoding('ascii-8bit') }], res)
# Just for fun, let's try parsing it as UTF8
chars = res[0]["sn"].force_encoding('utf-8').scan(/./u)
assert_equal(["L", "u", "\u010d", "i", "\u0107"], chars)
end
def test_join_dn
# examples from RFC 2253
assert_equal(
"cn=Steve Kille,o=Isode Limited,c=GB",
LDAP::Server::Operation.join_dn([{"cn"=>"Steve Kille"},{"o"=>"Isode Limited"},{"c"=>"GB"}])
)
# These are equivalent
d1 = "ou=Sales+cn=J. Smith,o=Widget Inc.,c=US"
d2 = "cn=J. Smith+ou=Sales,o=Widget Inc.,c=US"
assert_equal(d1,
LDAP::Server::Operation.join_dn([[["ou","Sales"],["cn","J. Smith"]],[["o","Widget Inc."]],["c","US"]])
)
r = LDAP::Server::Operation.join_dn([{"ou"=>"Sales","cn"=>"J. Smith"},{"o"=>"Widget Inc."},{"c"=>"US"}])
assert(r == d1 || r == d2, "got #{r.inspect}, expected #{d1.inspect} or #{d2.inspect}")
assert_equal(
"cn=L. Eagle,o=Sue\\, Grabbit and Runn,c=GB",
LDAP::Server::Operation.join_dn([{"cn"=>"L. Eagle"},{"o"=>"Sue, Grabbit and Runn"},{"c"=>"GB"}])
)
end
end