init
This commit is contained in:
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||
require 'test/unit'
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user