2025-12-25 upload

This commit is contained in:
“shengyudong”
2025-12-25 11:16:59 +08:00
commit 322ac74336
2241 changed files with 639966 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
"""
"""
# Created on 2015.10.20
#
# Author: Giovanni Cannata
#
# Copyright 2015 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from .rfc4511 import Control, Criticality, LDAPOID
from ..utils.asn1 import encode
def build_control(oid, criticality, value, encode_control_value=True):
control = Control()
control.setComponentByName('controlType', LDAPOID(oid))
control.setComponentByName('criticality', Criticality(criticality))
if value is not None:
if encode_control_value:
control.setComponentByName('controlValue', encode(value))
else:
control.setComponentByName('controlValue', value)
return control

View File

@@ -0,0 +1,221 @@
"""
"""
# Created on 2013.07.24
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from pyasn1.error import PyAsn1Error
from .. import SEQUENCE_TYPES, STRING_TYPES, get_config_parameter
from ..core.exceptions import LDAPControlError, LDAPAttributeError, LDAPObjectClassError, LDAPInvalidValueError
from ..protocol.rfc4511 import Controls, Control
from ..utils.conv import to_raw, to_unicode, escape_filter_chars, is_filter_escaped
from ..protocol.formatters.standard import find_attribute_validator
def to_str_or_normalized_unicode(val):
""" Attempt to convert value to a string. If that would error, convert it to normalized unicode.
Python 3 string conversion handles unicode -> str without issue, but python 2 doesn't.
"""
try:
return str(val)
except:
return val.encode('ascii', 'backslashreplace')
def attribute_to_dict(attribute):
try:
return {'type': str(attribute['type']), 'values': [str(val) for val in attribute['vals']]}
except PyAsn1Error: # invalid encoding, return bytes value
return {'type': str(attribute['type']), 'values': [bytes(val) for val in attribute['vals']]}
def attributes_to_dict(attributes):
attributes_dict = dict()
for attribute in attributes:
attribute_dict = attribute_to_dict(attribute)
attributes_dict[attribute_dict['type']] = attribute_dict['values']
return attributes_dict
def referrals_to_list(referrals):
if isinstance(referrals, list):
return [to_str_or_normalized_unicode(referral) for referral in referrals if referral] if referrals else None
else:
return [to_str_or_normalized_unicode(referral) for referral in referrals if referral] if referrals is not None and referrals.hasValue() else None
def search_refs_to_list(search_refs):
return [to_str_or_normalized_unicode(search_ref) for search_ref in search_refs if search_ref] if search_refs else None
def search_refs_to_list_fast(search_refs):
return [to_unicode(search_ref) for search_ref in search_refs if search_ref] if search_refs else None
def sasl_to_dict(sasl):
return {'mechanism': str(sasl['mechanism']), 'credentials': bytes(sasl['credentials']) if sasl['credentials'] is not None and sasl['credentials'].hasValue() else None}
def authentication_choice_to_dict(authentication_choice):
return {'simple': str(authentication_choice['simple']) if authentication_choice.getName() == 'simple' else None, 'sasl': sasl_to_dict(authentication_choice['sasl']) if authentication_choice.getName() == 'sasl' else None}
def partial_attribute_to_dict(modification):
try:
return {'type': str(modification['type']), 'value': [str(value) for value in modification['vals']]}
except PyAsn1Error: # invalid encoding, return bytes value
return {'type': str(modification['type']), 'value': [bytes(value) for value in modification['vals']]}
def change_to_dict(change):
return {'operation': int(change['operation']), 'attribute': partial_attribute_to_dict(change['modification'])}
def changes_to_list(changes):
return [change_to_dict(change) for change in changes]
def attributes_to_list(attributes):
return [to_str_or_normalized_unicode(attribute) for attribute in attributes]
def ava_to_dict(ava):
try:
return {'attribute': str(ava['attributeDesc']), 'value': escape_filter_chars(str(ava['assertionValue']))}
except Exception: # invalid encoding, return bytes value
try:
return {'attribute': str(ava['attributeDesc']), 'value': escape_filter_chars(bytes(ava['assertionValue']))}
except Exception:
return {'attribute': str(ava['attributeDesc']), 'value': bytes(ava['assertionValue'])}
def substring_to_dict(substring):
return {'initial': substring['initial'] if substring['initial'] else '', 'any': [middle for middle in substring['any']] if substring['any'] else '', 'final': substring['final'] if substring['final'] else ''}
def prepare_changes_for_request(changes):
prepared = dict()
for change in changes:
attribute_name = change['attribute']['type']
if attribute_name not in prepared:
prepared[attribute_name] = []
prepared[attribute_name].append((change['operation'], change['attribute']['value']))
return prepared
def build_controls_list(controls):
"""controls is a sequence of Control() or sequences
each sequence must have 3 elements: the control OID, the criticality, the value
criticality must be a boolean
"""
if not controls:
return None
if not isinstance(controls, SEQUENCE_TYPES):
raise LDAPControlError('controls must be a sequence')
built_controls = Controls()
for idx, control in enumerate(controls):
if isinstance(control, Control):
built_controls.setComponentByPosition(idx, control)
elif len(control) == 3 and isinstance(control[1], bool):
built_control = Control()
built_control['controlType'] = control[0]
built_control['criticality'] = control[1]
if control[2] is not None:
built_control['controlValue'] = control[2]
built_controls.setComponentByPosition(idx, built_control)
else:
raise LDAPControlError('control must be a sequence of 3 elements: controlType, criticality (boolean) and controlValue (None if not provided)')
return built_controls
def validate_assertion_value(schema, name, value, auto_escape, auto_encode, validator, check_names):
value = to_unicode(value)
if auto_escape:
if '\\' in value and not is_filter_escaped(value):
value = escape_filter_chars(value)
value = validate_attribute_value(schema, name, value, auto_encode, validator=validator, check_names=check_names)
return value
def validate_attribute_value(schema, name, value, auto_encode, validator=None, check_names=False):
conf_classes_excluded_from_check = [v.lower() for v in get_config_parameter('CLASSES_EXCLUDED_FROM_CHECK')]
conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')]
conf_utf8_syntaxes = get_config_parameter('UTF8_ENCODED_SYNTAXES')
conf_utf8_types = [v.lower() for v in get_config_parameter('UTF8_ENCODED_TYPES')]
if schema and schema.attribute_types:
if ';' in name:
name = name.split(';')[0]
if check_names and schema.object_classes and name.lower() == 'objectclass':
if to_unicode(value).lower() not in conf_classes_excluded_from_check and to_unicode(value) not in schema.object_classes:
raise LDAPObjectClassError('invalid class in objectClass attribute: ' + str(value))
elif check_names and name not in schema.attribute_types and name.lower() not in conf_attributes_excluded_from_check:
raise LDAPAttributeError('invalid attribute ' + name)
else: # try standard validators
validator = find_attribute_validator(schema, name, validator)
validated = validator(value)
if validated is False:
try: # checks if the value is a byte value erroneously converted to a string (as "b'1234'"), this is a common case in Python 3 when encoding is not specified
if value[0:2] == "b'" and value [-1] == "'":
value = to_raw(value[2:-1])
validated = validator(value)
except Exception:
raise LDAPInvalidValueError('value \'%s\' non valid for attribute \'%s\'' % (value, name))
if validated is False:
raise LDAPInvalidValueError('value \'%s\' non valid for attribute \'%s\'' % (value, name))
elif validated is not True: # a valid LDAP value equivalent to the actual value
value = validated
# converts to utf-8 for well known Unicode LDAP syntaxes
if auto_encode and ((name in schema.attribute_types and schema.attribute_types[name].syntax in conf_utf8_syntaxes) or name.lower() in conf_utf8_types):
value = to_unicode(value) # tries to convert from local encoding to Unicode
return to_raw(value)
def prepare_filter_for_sending(raw_string):
i = 0
ints = []
raw_string = to_raw(raw_string)
while i < len(raw_string):
if (raw_string[i] == 92 or raw_string[i] == '\\') and i < len(raw_string) - 2: # 92 (0x5C) is backslash
try:
ints.append(int(raw_string[i + 1: i + 3], 16))
i += 2
except ValueError: # not an ldap escaped value, sends as is
ints.append(92) # adds backslash
else:
if str is not bytes: # Python 3
ints.append(raw_string[i])
else: # Python 2
ints.append(ord(raw_string[i]))
i += 1
if str is not bytes: # Python 3
return bytes(ints)
else: # Python 2
return ''.join(chr(x) for x in ints)
def prepare_for_sending(raw_string):
return to_raw(raw_string) if isinstance(raw_string, STRING_TYPES) else raw_string

View File

@@ -0,0 +1,436 @@
"""
"""
# Created on 2014.10.28
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
import re
from binascii import hexlify
from uuid import UUID
from datetime import datetime, timedelta
from ...utils.conv import to_unicode
from ...core.timezone import OffsetTzInfo
def format_unicode(raw_value):
try:
if str is not bytes: # Python 3
return str(raw_value, 'utf-8', errors='strict')
else: # Python 2
return unicode(raw_value, 'utf-8', errors='strict')
except (TypeError, UnicodeDecodeError):
pass
return raw_value
def format_integer(raw_value):
try:
return int(raw_value)
except (TypeError, ValueError): # expected exceptions
pass
except Exception: # any other exception should be investigated, anyway the formatter return the raw_value
pass
return raw_value
def format_binary(raw_value):
try:
return bytes(raw_value)
except TypeError: # expected exceptions
pass
except Exception: # any other exception should be investigated, anyway the formatter return the raw_value
pass
return raw_value
def format_uuid(raw_value):
try:
return str(UUID(bytes=raw_value))
except (TypeError, ValueError):
return format_unicode(raw_value)
except Exception: # any other exception should be investigated, anyway the formatter return the raw_value
pass
return raw_value
def format_uuid_le(raw_value):
try:
return '{' + str(UUID(bytes_le=raw_value)) + '}'
except (TypeError, ValueError):
return format_unicode(raw_value)
except Exception: # any other exception should be investigated, anyway the formatter return the raw_value
pass
return raw_value
def format_boolean(raw_value):
if raw_value in [b'TRUE', b'true', b'True']:
return True
if raw_value in [b'FALSE', b'false', b'False']:
return False
return raw_value
def format_ad_timestamp(raw_value):
"""
Active Directory stores date/time values as the number of 100-nanosecond intervals
that have elapsed since the 0 hour on January 1, 1601 till the date/time that is being stored.
The time is always stored in Greenwich Mean Time (GMT) in the Active Directory.
"""
utc_timezone = OffsetTzInfo(0, 'UTC')
if raw_value == b'9223372036854775807': # max value to be stored in a 64 bit signed int
return datetime.max.replace(tzinfo=utc_timezone) # returns datetime.datetime(9999, 12, 31, 23, 59, 59, 999999, tzinfo=OffsetTzInfo(offset=0, name='UTC'))
try:
timestamp = int(raw_value)
if timestamp < 0: # ad timestamp cannot be negative
timestamp = timestamp * -1
except Exception:
return raw_value
try:
return datetime.fromtimestamp(timestamp / 10000000.0 - 11644473600,
tz=utc_timezone) # forces true division in python 2
except (OSError, OverflowError, ValueError): # on Windows backwards timestamps are not allowed
try:
unix_epoch = datetime.fromtimestamp(0, tz=utc_timezone)
diff_seconds = timedelta(seconds=timestamp / 10000000.0 - 11644473600)
return unix_epoch + diff_seconds
except Exception:
pass
except Exception:
pass
return raw_value
try: # uses regular expressions and the timezone class (python3.2 and later)
from datetime import timezone
time_format = re.compile(
r'''
^
(?P<Year>[0-9]{4})
(?P<Month>0[1-9]|1[0-2])
(?P<Day>0[1-9]|[12][0-9]|3[01])
(?P<Hour>[01][0-9]|2[0-3])
(?:
(?P<Minute>[0-5][0-9])
(?P<Second>[0-5][0-9]|60)?
)?
(?:
[.,]
(?P<Fraction>[0-9]+)
)?
(?:
Z
|
(?:
(?P<Offset>[+-])
(?P<OffHour>[01][0-9]|2[0-3])
(?P<OffMinute>[0-5][0-9])?
)
)
$
''',
re.VERBOSE
)
def format_time(raw_value):
try:
match = time_format.fullmatch(to_unicode(raw_value))
if match is None:
return raw_value
matches = match.groupdict()
offset = timedelta(
hours=int(matches['OffHour'] or 0),
minutes=int(matches['OffMinute'] or 0)
)
if matches['Offset'] == '-':
offset *= -1
# Python does not support leap second in datetime (!)
if matches['Second'] == '60':
matches['Second'] = '59'
# According to RFC, fraction may be applied to an Hour/Minute (!)
fraction = float('0.' + (matches['Fraction'] or '0'))
if matches['Minute'] is None:
fraction *= 60
minute = int(fraction)
fraction -= minute
else:
minute = int(matches['Minute'])
if matches['Second'] is None:
fraction *= 60
second = int(fraction)
fraction -= second
else:
second = int(matches['Second'])
microseconds = int(fraction * 1000000)
return datetime(
int(matches['Year']),
int(matches['Month']),
int(matches['Day']),
int(matches['Hour']),
minute,
second,
microseconds,
timezone(offset),
)
except Exception: # exceptions should be investigated, anyway the formatter return the raw_value
pass
return raw_value
except ImportError:
def format_time(raw_value):
"""
From RFC4517:
A value of the Generalized Time syntax is a character string
representing a date and time. The LDAP-specific encoding of a value
of this syntax is a restriction of the format defined in [ISO8601],
and is described by the following ABNF:
GeneralizedTime = century year month day hour
[ minute [ second / leap-second ] ]
[ fraction ]
g-time-zone
century = 2(%x30-39) ; "00" to "99"
year = 2(%x30-39) ; "00" to "99"
month = ( %x30 %x31-39 ) ; "01" (January) to "09"
/ ( %x31 %x30-32 ) ; "10" to "12"
day = ( %x30 %x31-39 ) ; "01" to "09"
/ ( %x31-32 %x30-39 ) ; "10" to "29"
/ ( %x33 %x30-31 ) ; "30" to "31"
hour = ( %x30-31 %x30-39 ) / ( %x32 %x30-33 ) ; "00" to "23"
minute = %x30-35 %x30-39 ; "00" to "59"
second = ( %x30-35 %x30-39 ) ; "00" to "59"
leap-second = ( %x36 %x30 ) ; "60"
fraction = ( DOT / COMMA ) 1*(%x30-39)
g-time-zone = %x5A ; "Z"
/ g-differential
g-differential = ( MINUS / PLUS ) hour [ minute ]
MINUS = %x2D ; minus sign ("-")
"""
if len(raw_value) < 10 or not all((c in b'0123456789+-,.Z' for c in raw_value)) or (
b'Z' in raw_value and not raw_value.endswith(
b'Z')): # first ten characters are mandatory and must be numeric or timezone or fraction
return raw_value
# sets position for fixed values
year = int(raw_value[0: 4])
month = int(raw_value[4: 6])
day = int(raw_value[6: 8])
hour = int(raw_value[8: 10])
minute = 0
second = 0
microsecond = 0
remain = raw_value[10:]
if remain and remain.endswith(b'Z'): # uppercase 'Z'
sep = b'Z'
elif b'+' in remain: # timezone can be specified with +hh[mm] or -hh[mm]
sep = b'+'
elif b'-' in remain:
sep = b'-'
else: # timezone not specified
return raw_value
time, _, offset = remain.partition(sep)
if time and (b'.' in time or b',' in time):
# fraction time
if time[0] in b',.':
minute = 6 * int(time[1] if str is bytes else chr(time[1])) # Python 2 / Python 3
elif time[2] in b',.':
minute = int(raw_value[10: 12])
second = 6 * int(time[3] if str is bytes else chr(time[3])) # Python 2 / Python 3
elif time[4] in b',.':
minute = int(raw_value[10: 12])
second = int(raw_value[12: 14])
microsecond = 100000 * int(time[5] if str is bytes else chr(time[5])) # Python 2 / Python 3
elif len(time) == 2: # mmZ format
minute = int(raw_value[10: 12])
elif len(time) == 0: # Z format
pass
elif len(time) == 4: # mmssZ
minute = int(raw_value[10: 12])
second = int(raw_value[12: 14])
else:
return raw_value
if sep == b'Z': # UTC
timezone = OffsetTzInfo(0, 'UTC')
else: # build timezone
try:
if len(offset) == 2:
timezone_hour = int(offset[:2])
timezone_minute = 0
elif len(offset) == 4:
timezone_hour = int(offset[:2])
timezone_minute = int(offset[2:4])
else: # malformed timezone
raise ValueError
except ValueError:
return raw_value
if timezone_hour > 23 or timezone_minute > 59: # invalid timezone
return raw_value
if str is not bytes: # Python 3
timezone = OffsetTzInfo((timezone_hour * 60 + timezone_minute) * (1 if sep == b'+' else -1),
'UTC' + str(sep + offset, encoding='utf-8'))
else: # Python 2
timezone = OffsetTzInfo((timezone_hour * 60 + timezone_minute) * (1 if sep == b'+' else -1),
unicode('UTC' + sep + offset, encoding='utf-8'))
try:
return datetime(year=year,
month=month,
day=day,
hour=hour,
minute=minute,
second=second,
microsecond=microsecond,
tzinfo=timezone)
except (TypeError, ValueError):
pass
return raw_value
def format_ad_timedelta(raw_value):
"""
Convert a negative filetime value to a timedelta.
"""
# Active Directory stores attributes like "minPwdAge" as a negative
# "filetime" timestamp, which is the number of 100-nanosecond intervals that
# have elapsed since the 0 hour on January 1, 1601.
#
# Handle the minimum value that can be stored in a 64 bit signed integer.
# See https://docs.microsoft.com/en-us/dotnet/api/system.int64.minvalue
# In attributes like "maxPwdAge", this signifies never.
if raw_value == b'-9223372036854775808':
return timedelta.max
# We can reuse format_ad_timestamp to get a datetime object from the
# timestamp. Afterwards, we can subtract a datetime representing 0 hour on
# January 1, 1601 from the returned datetime to get the timedelta.
return format_ad_timestamp(raw_value) - format_ad_timestamp(0)
def format_time_with_0_year(raw_value):
try:
if raw_value.startswith(b'0000'):
return raw_value
except Exception:
try:
if raw_value.startswith('0000'):
return raw_value
except Exception:
pass
return format_time(raw_value)
def format_sid(raw_value):
"""
SID= "S-1-" IdentifierAuthority 1*SubAuthority
IdentifierAuthority= IdentifierAuthorityDec / IdentifierAuthorityHex
; If the identifier authority is < 2^32, the
; identifier authority is represented as a decimal
; number
; If the identifier authority is >= 2^32,
; the identifier authority is represented in
; hexadecimal
IdentifierAuthorityDec = 1*10DIGIT
; IdentifierAuthorityDec, top level authority of a
; security identifier is represented as a decimal number
IdentifierAuthorityHex = "0x" 12HEXDIG
; IdentifierAuthorityHex, the top-level authority of a
; security identifier is represented as a hexadecimal number
SubAuthority= "-" 1*10DIGIT
; Sub-Authority is always represented as a decimal number
; No leading "0" characters are allowed when IdentifierAuthority
; or SubAuthority is represented as a decimal number
; All hexadecimal digits must be output in string format,
; pre-pended by "0x"
Revision (1 byte): An 8-bit unsigned integer that specifies the revision level of the SID. This value MUST be set to 0x01.
SubAuthorityCount (1 byte): An 8-bit unsigned integer that specifies the number of elements in the SubAuthority array. The maximum number of elements allowed is 15.
IdentifierAuthority (6 bytes): A SID_IDENTIFIER_AUTHORITY structure that indicates the authority under which the SID was created. It describes the entity that created the SID. The Identifier Authority value {0,0,0,0,0,5} denotes SIDs created by the NT SID authority.
SubAuthority (variable): A variable length array of unsigned 32-bit integers that uniquely identifies a principal relative to the IdentifierAuthority. Its length is determined by SubAuthorityCount.
"""
try:
if raw_value.startswith(b'S-1-'):
return raw_value
except Exception:
try:
if raw_value.startswith('S-1-'):
return raw_value
except Exception:
pass
try:
if str is not bytes: # Python 3
revision = int(raw_value[0])
sub_authority_count = int(raw_value[1])
identifier_authority = int.from_bytes(raw_value[2:8], byteorder='big')
if identifier_authority >= 4294967296: # 2 ^ 32
identifier_authority = hex(identifier_authority)
sub_authority = ''
i = 0
while i < sub_authority_count:
sub_authority += '-' + str(
int.from_bytes(raw_value[8 + (i * 4): 12 + (i * 4)], byteorder='little')) # little endian
i += 1
else: # Python 2
revision = int(ord(raw_value[0]))
sub_authority_count = int(ord(raw_value[1]))
identifier_authority = int(hexlify(raw_value[2:8]), 16)
if identifier_authority >= 4294967296: # 2 ^ 32
identifier_authority = hex(identifier_authority)
sub_authority = ''
i = 0
while i < sub_authority_count:
sub_authority += '-' + str(int(hexlify(raw_value[11 + (i * 4): 7 + (i * 4): -1]), 16)) # little endian
i += 1
return 'S-' + str(revision) + '-' + str(identifier_authority) + sub_authority
except Exception: # any exception should be investigated, anyway the formatter return the raw_value
pass
return raw_value

View File

@@ -0,0 +1,238 @@
"""
"""
# Created on 2014.10.28
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from ... import SEQUENCE_TYPES
from .formatters import format_ad_timestamp, format_binary, format_boolean,\
format_integer, format_sid, format_time, format_unicode, format_uuid, format_uuid_le, format_time_with_0_year,\
format_ad_timedelta
from .validators import validate_integer, validate_time, always_valid,\
validate_generic_single_value, validate_boolean, validate_ad_timestamp, validate_sid,\
validate_uuid_le, validate_uuid, validate_zero_and_minus_one_and_positive_int, validate_guid, validate_time_with_0_year,\
validate_ad_timedelta
# for each syntax can be specified a format function and a input validation function
standard_formatter = {
'1.2.840.113556.1.4.903': (format_binary, None), # Object (DN-binary) - Microsoft
'1.2.840.113556.1.4.904': (format_unicode, None), # Object (DN-string) - Microsoft
'1.2.840.113556.1.4.905': (format_unicode, None), # String (Teletex) - Microsoft
'1.2.840.113556.1.4.906': (format_integer, validate_integer), # Large integer - Microsoft
'1.2.840.113556.1.4.907': (format_binary, None), # String (NT-sec-desc) - Microsoft
'1.2.840.113556.1.4.1221': (format_binary, None), # Object (OR-name) - Microsoft
'1.2.840.113556.1.4.1362': (format_unicode, None), # String (Case) - Microsoft
'1.3.6.1.4.1.1466.115.121.1.1': (format_binary, None), # ACI item [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.2': (format_binary, None), # Access point [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.3': (format_unicode, None), # Attribute type description
'1.3.6.1.4.1.1466.115.121.1.4': (format_binary, None), # Audio [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.5': (format_binary, None), # Binary [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.6': (format_unicode, None), # Bit String
'1.3.6.1.4.1.1466.115.121.1.7': (format_boolean, validate_boolean), # Boolean
'1.3.6.1.4.1.1466.115.121.1.8': (format_binary, None), # Certificate [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.9': (format_binary, None), # Certificate List [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.10': (format_binary, None), # Certificate Pair [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.11': (format_unicode, None), # Country String
'1.3.6.1.4.1.1466.115.121.1.12': (format_unicode, None), # Distinguished name (DN)
'1.3.6.1.4.1.1466.115.121.1.13': (format_binary, None), # Data Quality Syntax [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.14': (format_unicode, None), # Delivery method
'1.3.6.1.4.1.1466.115.121.1.15': (format_unicode, None), # Directory string
'1.3.6.1.4.1.1466.115.121.1.16': (format_unicode, None), # DIT Content Rule Description
'1.3.6.1.4.1.1466.115.121.1.17': (format_unicode, None), # DIT Structure Rule Description
'1.3.6.1.4.1.1466.115.121.1.18': (format_binary, None), # DL Submit Permission [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.19': (format_binary, None), # DSA Quality Syntax [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.20': (format_binary, None), # DSE Type [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.21': (format_binary, None), # Enhanced Guide
'1.3.6.1.4.1.1466.115.121.1.22': (format_unicode, None), # Facsimile Telephone Number
'1.3.6.1.4.1.1466.115.121.1.23': (format_binary, None), # Fax
'1.3.6.1.4.1.1466.115.121.1.24': (format_time, validate_time), # Generalized time
'1.3.6.1.4.1.1466.115.121.1.25': (format_binary, None), # Guide [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.26': (format_unicode, None), # IA5 string
'1.3.6.1.4.1.1466.115.121.1.27': (format_integer, validate_integer), # Integer
'1.3.6.1.4.1.1466.115.121.1.28': (format_binary, None), # JPEG
'1.3.6.1.4.1.1466.115.121.1.29': (format_binary, None), # Master and Shadow Access Points [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.30': (format_unicode, None), # Matching rule description
'1.3.6.1.4.1.1466.115.121.1.31': (format_unicode, None), # Matching rule use description
'1.3.6.1.4.1.1466.115.121.1.32': (format_unicode, None), # Mail Preference [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.33': (format_unicode, None), # MHS OR Address [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.34': (format_unicode, None), # Name and optional UID
'1.3.6.1.4.1.1466.115.121.1.35': (format_unicode, None), # Name form description
'1.3.6.1.4.1.1466.115.121.1.36': (format_unicode, None), # Numeric string
'1.3.6.1.4.1.1466.115.121.1.37': (format_unicode, None), # Object class description
'1.3.6.1.4.1.1466.115.121.1.38': (format_unicode, None), # OID
'1.3.6.1.4.1.1466.115.121.1.39': (format_unicode, None), # Other mailbox
'1.3.6.1.4.1.1466.115.121.1.40': (format_binary, None), # Octet string
'1.3.6.1.4.1.1466.115.121.1.41': (format_unicode, None), # Postal address
'1.3.6.1.4.1.1466.115.121.1.42': (format_binary, None), # Protocol Information [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.43': (format_binary, None), # Presentation Address [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.44': (format_unicode, None), # Printable string
'1.3.6.1.4.1.1466.115.121.1.45': (format_binary, None), # Subtree specification [OBSOLETE
'1.3.6.1.4.1.1466.115.121.1.46': (format_binary, None), # Supplier Information [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.47': (format_binary, None), # Supplier Or Consumer [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.48': (format_binary, None), # Supplier And Consumer [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.49': (format_binary, None), # Supported Algorithm [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.50': (format_unicode, None), # Telephone number
'1.3.6.1.4.1.1466.115.121.1.51': (format_unicode, None), # Teletex terminal identifier
'1.3.6.1.4.1.1466.115.121.1.52': (format_unicode, None), # Teletex number
'1.3.6.1.4.1.1466.115.121.1.53': (format_time, validate_time), # Utc time (deprecated)
'1.3.6.1.4.1.1466.115.121.1.54': (format_unicode, None), # LDAP syntax description
'1.3.6.1.4.1.1466.115.121.1.55': (format_binary, None), # Modify rights [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.56': (format_binary, None), # LDAP Schema Definition [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.57': (format_unicode, None), # LDAP Schema Description [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.58': (format_unicode, None), # Substring assertion
'1.3.6.1.1.16.1': (format_uuid, validate_uuid), # UUID
'1.3.6.1.1.16.4': (format_uuid, validate_uuid), # entryUUID (RFC 4530)
'2.16.840.1.113719.1.1.4.1.501': (format_uuid, validate_guid), # GUID (Novell)
'2.16.840.1.113719.1.1.5.1.0': (format_binary, None), # Unknown (Novell)
'2.16.840.1.113719.1.1.5.1.6': (format_unicode, None), # Case Ignore List (Novell)
'2.16.840.1.113719.1.1.5.1.12': (format_binary, None), # Tagged Data (Novell)
'2.16.840.1.113719.1.1.5.1.13': (format_binary, None), # Octet List (Novell)
'2.16.840.1.113719.1.1.5.1.14': (format_unicode, None), # Tagged String (Novell)
'2.16.840.1.113719.1.1.5.1.15': (format_unicode, None), # Tagged Name And String (Novell)
'2.16.840.1.113719.1.1.5.1.16': (format_binary, None), # NDS Replica Pointer (Novell)
'2.16.840.1.113719.1.1.5.1.17': (format_unicode, None), # NDS ACL (Novell)
'2.16.840.1.113719.1.1.5.1.19': (format_time, validate_time), # NDS Timestamp (Novell)
'2.16.840.1.113719.1.1.5.1.22': (format_integer, validate_integer), # Counter (Novell)
'2.16.840.1.113719.1.1.5.1.23': (format_unicode, None), # Tagged Name (Novell)
'2.16.840.1.113719.1.1.5.1.25': (format_unicode, None), # Typed Name (Novell)
'supportedldapversion': (format_integer, None), # supportedLdapVersion (Microsoft)
'octetstring': (format_binary, validate_uuid_le), # octect string (Microsoft)
'1.2.840.113556.1.4.2': (format_uuid_le, validate_uuid_le), # objectGUID (Microsoft)
'1.2.840.113556.1.4.13': (format_ad_timestamp, validate_ad_timestamp), # builtinCreationTime (Microsoft)
'1.2.840.113556.1.4.26': (format_ad_timestamp, validate_ad_timestamp), # creationTime (Microsoft)
'1.2.840.113556.1.4.49': (format_ad_timestamp, validate_ad_timestamp), # badPasswordTime (Microsoft)
'1.2.840.113556.1.4.51': (format_ad_timestamp, validate_ad_timestamp), # lastLogoff (Microsoft)
'1.2.840.113556.1.4.52': (format_ad_timestamp, validate_ad_timestamp), # lastLogon (Microsoft)
'1.2.840.113556.1.4.60': (format_ad_timedelta, validate_ad_timedelta), # lockoutDuration (Microsoft)
'1.2.840.113556.1.4.61': (format_ad_timedelta, validate_ad_timedelta), # lockOutObservationWindow (Microsoft)
'1.2.840.113556.1.4.74': (format_ad_timedelta, validate_ad_timedelta), # maxPwdAge (Microsoft)
'1.2.840.113556.1.4.78': (format_ad_timedelta, validate_ad_timedelta), # minPwdAge (Microsoft)
'1.2.840.113556.1.4.96': (format_ad_timestamp, validate_zero_and_minus_one_and_positive_int), # pwdLastSet (Microsoft, can be set to -1 only)
'1.2.840.113556.1.4.146': (format_sid, validate_sid), # objectSid (Microsoft)
'1.2.840.113556.1.4.159': (format_ad_timestamp, validate_ad_timestamp), # accountExpires (Microsoft)
'1.2.840.113556.1.4.662': (format_ad_timestamp, validate_ad_timestamp), # lockoutTime (Microsoft)
'1.2.840.113556.1.4.1696': (format_ad_timestamp, validate_ad_timestamp), # lastLogonTimestamp (Microsoft)
'1.3.6.1.4.1.42.2.27.8.1.17': (format_time_with_0_year, validate_time_with_0_year) # pwdAccountLockedTime (Novell)
}
def find_attribute_helpers(attr_type, name, custom_formatter):
"""
Tries to format following the OIDs info and format_helper specification.
Search for attribute oid, then attribute name (can be multiple), then attribute syntax
Precedence is:
1. attribute name
2. attribute oid(from schema)
3. attribute names (from oid_info)
4. attribute syntax (from schema)
Custom formatters can be defined in Server object and have precedence over the standard_formatters
If no formatter is found the raw_value is returned as bytes.
Attributes defined as SINGLE_VALUE in schema are returned as a single object, otherwise are returned as a list of object
Formatter functions can return any kind of object
return a tuple (formatter, validator)
"""
formatter = None
if custom_formatter and isinstance(custom_formatter, dict): # if custom formatters are defined they have precedence over the standard formatters
if name in custom_formatter: # search for attribute name, as returned by the search operation
formatter = custom_formatter[name]
if not formatter and attr_type and attr_type.oid in custom_formatter: # search for attribute oid as returned by schema
formatter = custom_formatter[attr_type.oid]
if not formatter and attr_type and attr_type.oid_info:
if isinstance(attr_type.oid_info[2], SEQUENCE_TYPES): # search for multiple names defined in oid_info
for attr_name in attr_type.oid_info[2]:
if attr_name in custom_formatter:
formatter = custom_formatter[attr_name]
break
elif attr_type.oid_info[2] in custom_formatter: # search for name defined in oid_info
formatter = custom_formatter[attr_type.oid_info[2]]
if not formatter and attr_type and attr_type.syntax in custom_formatter: # search for syntax defined in schema
formatter = custom_formatter[attr_type.syntax]
if not formatter and name in standard_formatter: # search for attribute name, as returned by the search operation
formatter = standard_formatter[name]
if not formatter and attr_type and attr_type.oid in standard_formatter: # search for attribute oid as returned by schema
formatter = standard_formatter[attr_type.oid]
if not formatter and attr_type and attr_type.oid_info:
if isinstance(attr_type.oid_info[2], SEQUENCE_TYPES): # search for multiple names defined in oid_info
for attr_name in attr_type.oid_info[2]:
if attr_name in standard_formatter:
formatter = standard_formatter[attr_name]
break
elif attr_type.oid_info[2] in standard_formatter: # search for name defined in oid_info
formatter = standard_formatter[attr_type.oid_info[2]]
if not formatter and attr_type and attr_type.syntax in standard_formatter: # search for syntax defined in schema
formatter = standard_formatter[attr_type.syntax]
if formatter is None:
return None, None
return formatter
def format_attribute_values(schema, name, values, custom_formatter):
if not values: # RFCs states that attributes must always have values, but a flaky server returns empty values too
return []
if not isinstance(values, SEQUENCE_TYPES):
values = [values]
if schema and schema.attribute_types and name in schema.attribute_types:
attr_type = schema.attribute_types[name]
else:
attr_type = None
attribute_helpers = find_attribute_helpers(attr_type, name, custom_formatter)
if not isinstance(attribute_helpers, tuple): # custom formatter
formatter = attribute_helpers
else:
formatter = format_unicode if not attribute_helpers[0] else attribute_helpers[0]
formatted_values = [formatter(raw_value) for raw_value in values] # executes formatter
if formatted_values:
return formatted_values[0] if (attr_type and attr_type.single_value) else formatted_values
else: # RFCs states that attributes must always have values, but AD return empty values in DirSync
return []
def find_attribute_validator(schema, name, custom_validator):
if schema and schema.attribute_types and name in schema.attribute_types:
attr_type = schema.attribute_types[name]
else:
attr_type = None
attribute_helpers = find_attribute_helpers(attr_type, name, custom_validator)
if not isinstance(attribute_helpers, tuple): # custom validator
validator = attribute_helpers
else:
if not attribute_helpers[1]:
if attr_type and attr_type.single_value:
validator = validate_generic_single_value # validate only single value
else:
validator = always_valid # unknown syntax, accepts single and multi value
else:
validator = attribute_helpers[1]
return validator

View File

@@ -0,0 +1,502 @@
"""
"""
# Created on 2016.08.09
#
# Author: Giovanni Cannata
#
# Copyright 2016 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from binascii import a2b_hex, hexlify
from datetime import datetime
from calendar import timegm
from uuid import UUID
from struct import pack
from ... import SEQUENCE_TYPES, STRING_TYPES, NUMERIC_TYPES, INTEGER_TYPES
from .formatters import format_time, format_ad_timestamp
from ...utils.conv import to_raw, to_unicode, ldap_escape_to_bytes, escape_bytes
# Validators return True if value is valid, False if value is not valid,
# or a value different from True and False that is a valid value to substitute to the input value
def check_backslash(value):
if isinstance(value, (bytearray, bytes)):
if b'\\' in value:
value = value.replace(b'\\', b'\\5C')
elif isinstance(value, STRING_TYPES):
if '\\' in value:
value = value.replace('\\', '\\5C')
return value
def check_type(input_value, value_type):
if isinstance(input_value, value_type):
return True
if isinstance(input_value, SEQUENCE_TYPES):
for value in input_value:
if not isinstance(value, value_type):
return False
return True
return False
# noinspection PyUnusedLocal
def always_valid(input_value):
return True
def validate_generic_single_value(input_value):
if not isinstance(input_value, SEQUENCE_TYPES):
return True
try: # object couldn't have a __len__ method
if len(input_value) == 1:
return True
except Exception:
pass
return False
def validate_zero_and_minus_one_and_positive_int(input_value):
"""Accept -1 and 0 only (used by pwdLastSet in AD)
"""
if not isinstance(input_value, SEQUENCE_TYPES):
if isinstance(input_value, NUMERIC_TYPES) or isinstance(input_value, STRING_TYPES):
return True if int(input_value) >= -1 else False
return False
else:
if len(input_value) == 1 and (isinstance(input_value[0], NUMERIC_TYPES) or isinstance(input_value[0], STRING_TYPES)):
return True if int(input_value[0]) >= -1 else False
return False
def validate_integer(input_value):
if check_type(input_value, (float, bool)):
return False
if check_type(input_value, INTEGER_TYPES):
return True
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = [] # builds a list of valid int values
from decimal import Decimal, InvalidOperation
for element in input_value:
try: #try to convert any type to int, an invalid conversion raise TypeError or ValueError, doublecheck with Decimal type, if both are valid and equal then then int() value is used
value = to_unicode(element) if isinstance(element, bytes) else element
decimal_value = Decimal(value)
int_value = int(value)
if decimal_value == int_value:
valid_values.append(int_value)
else:
return False
except (ValueError, TypeError, InvalidOperation):
return False
if sequence:
return valid_values
else:
return valid_values[0]
def validate_bytes(input_value):
return check_type(input_value, bytes)
def validate_boolean(input_value):
# it could be a real bool or the string TRUE or FALSE, # only a single valued is allowed
if validate_generic_single_value(input_value): # valid only if a single value or a sequence with a single element
if isinstance(input_value, SEQUENCE_TYPES):
input_value = input_value[0]
if isinstance(input_value, bool):
if input_value:
return 'TRUE'
else:
return 'FALSE'
if str is not bytes and isinstance(input_value, bytes): # python3 try to converts bytes to string
input_value = to_unicode(input_value)
if isinstance(input_value, STRING_TYPES):
if input_value.lower() == 'true':
return 'TRUE'
elif input_value.lower() == 'false':
return 'FALSE'
return False
def validate_time_with_0_year(input_value):
# validates generalized time but accept a 0000 year too
# if datetime object doesn't have a timezone it's considered local time and is adjusted to UTC
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if str is not bytes and isinstance(element, bytes): # python3 try to converts bytes to string
element = to_unicode(element)
if isinstance(element, STRING_TYPES): # tries to check if it is already be a Generalized Time
if element.startswith('0000') or isinstance(format_time(to_raw(element)), datetime): # valid Generalized Time string
valid_values.append(element)
else:
return False
elif isinstance(element, datetime):
changed = True
if element.tzinfo: # a datetime with a timezone
valid_values.append(element.strftime('%Y%m%d%H%M%S%z'))
else: # datetime without timezone, assumed local and adjusted to UTC
offset = datetime.now() - datetime.utcnow()
valid_values.append((element - offset).strftime('%Y%m%d%H%M%SZ'))
else:
return False
if changed:
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_time(input_value):
# if datetime object doesn't have a timezone it's considered local time and is adjusted to UTC
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if str is not bytes and isinstance(element, bytes): # python3 try to converts bytes to string
element = to_unicode(element)
if isinstance(element, STRING_TYPES): # tries to check if it is already be a Generalized Time
if isinstance(format_time(to_raw(element)), datetime): # valid Generalized Time string
valid_values.append(element)
else:
return False
elif isinstance(element, datetime):
changed = True
if element.tzinfo: # a datetime with a timezone
valid_values.append(element.strftime('%Y%m%d%H%M%S%z'))
else: # datetime without timezone, assumed local and adjusted to UTC
offset = datetime.now() - datetime.utcnow()
valid_values.append((element - offset).strftime('%Y%m%d%H%M%SZ'))
else:
return False
if changed:
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_ad_timestamp(input_value):
"""
Active Directory stores date/time values as the number of 100-nanosecond intervals
that have elapsed since the 0 hour on January 1, 1601 till the date/time that is being stored.
The time is always stored in Greenwich Mean Time (GMT) in the Active Directory.
"""
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if str is not bytes and isinstance(element, bytes): # python3 try to converts bytes to string
element = to_unicode(element)
if isinstance(element, NUMERIC_TYPES):
if 0 <= element <= 9223372036854775807: # min and max for the AD timestamp starting from 12:00 AM January 1, 1601
valid_values.append(element)
else:
return False
elif isinstance(element, STRING_TYPES): # tries to check if it is already be a AD timestamp
if isinstance(format_ad_timestamp(to_raw(element)), datetime): # valid Generalized Time string
valid_values.append(element)
else:
return False
elif isinstance(element, datetime):
changed = True
if element.tzinfo: # a datetime with a timezone
valid_values.append(to_raw((timegm(element.utctimetuple()) + 11644473600) * 10000000, encoding='ascii'))
else: # datetime without timezone, assumed local and adjusted to UTC
offset = datetime.now() - datetime.utcnow()
valid_values.append(to_raw((timegm((element - offset).timetuple()) + 11644473600) * 10000000, encoding='ascii'))
else:
return False
if changed:
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_ad_timedelta(input_value):
"""
Should be validated like an AD timestamp except that since it is a time
delta, it is stored as a negative number.
"""
if not isinstance(input_value, INTEGER_TYPES) or input_value > 0:
return False
return validate_ad_timestamp(input_value * -1)
def validate_guid(input_value):
"""
object guid in uuid format (Novell eDirectory)
"""
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if isinstance(element, STRING_TYPES):
try:
valid_values.append(UUID(element).bytes)
changed = True
except ValueError: # try if the value is an escaped ldap byte sequence
try:
x = ldap_escape_to_bytes(element)
valid_values.append(UUID(bytes=x).bytes)
changed = True
continue
except ValueError:
if str is not bytes: # python 3
pass
else:
valid_values.append(element)
continue
return False
elif isinstance(element, (bytes, bytearray)): # assumes bytes are valid
valid_values.append(element)
else:
return False
if changed:
# valid_values = [check_backslash(value) for value in valid_values]
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_uuid(input_value):
"""
object entryUUID in uuid format
"""
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if isinstance(element, STRING_TYPES):
try:
valid_values.append(str(UUID(element)))
changed = True
except ValueError: # try if the value is an escaped byte sequence
try:
valid_values.append(str(UUID(element.replace('\\', ''))))
changed = True
continue
except ValueError:
if str is not bytes: # python 3
pass
else:
valid_values.append(element)
continue
return False
elif isinstance(element, (bytes, bytearray)): # assumes bytes are valid
valid_values.append(element)
else:
return False
if changed:
# valid_values = [check_backslash(value) for value in valid_values]
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_uuid_le(input_value):
r"""
Active Directory stores objectGUID in uuid_le format, follows RFC4122 and MS-DTYP:
"{07039e68-4373-264d-a0a7-07039e684373}": string representation big endian, converted to little endian (with or without brace curles)
"689e030773434d26a7a007039e684373": packet representation, already in little endian
"\68\9e\03\07\73\43\4d\26\a7\a0\07\03\9e\68\43\73": bytes representation, already in little endian
byte sequence: already in little endian
"""
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
error = False
if isinstance(element, STRING_TYPES):
if element[0] == '{' and element[-1] == '}':
try:
valid_values.append(UUID(hex=element).bytes_le) # string representation, value in big endian, converts to little endian
changed = True
except ValueError:
error = True
elif '-' in element:
try:
valid_values.append(UUID(hex=element).bytes_le) # string representation, value in big endian, converts to little endian
changed = True
except ValueError:
error = True
elif '\\' in element:
try:
valid_values.append(UUID(bytes_le=ldap_escape_to_bytes(element)).bytes_le) # byte representation, value in little endian
changed = True
except ValueError:
error = True
elif '-' not in element: # value in little endian
try:
valid_values.append(UUID(bytes_le=a2b_hex(element)).bytes_le) # packet representation, value in little endian, converts to little endian
changed = True
except ValueError:
error = True
if error and (str is bytes): # python2 only assume value is bytes and valid
valid_values.append(element) # value is untouched, must be in little endian
elif isinstance(element, (bytes, bytearray)): # assumes bytes are valid uuid
valid_values.append(element) # value is untouched, must be in little endian
else:
return False
if changed:
# valid_values = [check_backslash(value) for value in valid_values]
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True
def validate_sid(input_value):
"""
SID= "S-1-" IdentifierAuthority 1*SubAuthority
IdentifierAuthority= IdentifierAuthorityDec / IdentifierAuthorityHex
; If the identifier authority is < 2^32, the
; identifier authority is represented as a decimal
; number
; If the identifier authority is >= 2^32,
; the identifier authority is represented in
; hexadecimal
IdentifierAuthorityDec = 1*10DIGIT
; IdentifierAuthorityDec, top level authority of a
; security identifier is represented as a decimal number
IdentifierAuthorityHex = "0x" 12HEXDIG
; IdentifierAuthorityHex, the top-level authority of a
; security identifier is represented as a hexadecimal number
SubAuthority= "-" 1*10DIGIT
; Sub-Authority is always represented as a decimal number
; No leading "0" characters are allowed when IdentifierAuthority
; or SubAuthority is represented as a decimal number
; All hexadecimal digits must be output in string format,
; pre-pended by "0x"
Revision (1 byte): An 8-bit unsigned integer that specifies the revision level of the SID. This value MUST be set to 0x01.
SubAuthorityCount (1 byte): An 8-bit unsigned integer that specifies the number of elements in the SubAuthority array. The maximum number of elements allowed is 15.
IdentifierAuthority (6 bytes): A SID_IDENTIFIER_AUTHORITY structure that indicates the authority under which the SID was created. It describes the entity that created the SID. The Identifier Authority value {0,0,0,0,0,5} denotes SIDs created by the NT SID authority.
SubAuthority (variable): A variable length array of unsigned 32-bit integers that uniquely identifies a principal relative to the IdentifierAuthority. Its length is determined by SubAuthorityCount.
If you have a SID like S-a-b-c-d-e-f-g-...
Then the bytes are
a (revision)
N (number of dashes minus two)
bbbbbb (six bytes of "b" treated as a 48-bit number in big-endian format)
cccc (four bytes of "c" treated as a 32-bit number in little-endian format)
dddd (four bytes of "d" treated as a 32-bit number in little-endian format)
eeee (four bytes of "e" treated as a 32-bit number in little-endian format)
ffff (four bytes of "f" treated as a 32-bit number in little-endian format)
"""
if not isinstance(input_value, SEQUENCE_TYPES):
sequence = False
input_value = [input_value]
else:
sequence = True # indicates if a sequence must be returned
valid_values = []
changed = False
for element in input_value:
if isinstance(element, STRING_TYPES):
if element.startswith('S-'):
parts = element.split('-')
sid_bytes = pack('<q', int(parts[1]))[0:1] # revision number
sid_bytes += pack('<q', len(parts[3:]))[0:1] # number of sub authorities
if len(parts[2]) <= 10:
sid_bytes += pack('>q', int(parts[2]))[2:] # authority (in dec)
else:
sid_bytes += pack('>q', int(parts[2], 16))[2:] # authority (in hex)
for sub_auth in parts[3:]:
sid_bytes += pack('<q', int(sub_auth))[0:4] # sub-authorities
valid_values.append(sid_bytes)
changed = True
if changed:
# valid_values = [check_backslash(value) for value in valid_values]
if sequence:
return valid_values
else:
return valid_values[0]
else:
return True

View File

@@ -0,0 +1,142 @@
"""
"""
# Created on 2015.03.27
#
# Author: Giovanni Cannata
#
# Copyright 2015 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
import ctypes
from pyasn1.type.namedtype import NamedTypes, NamedType
from pyasn1.type.tag import Tag, tagClassApplication, tagFormatConstructed
from pyasn1.type.univ import Sequence, OctetString, Integer
from .rfc4511 import ResultCode, LDAPString
from .controls import build_control
class SicilyBindResponse(Sequence):
# SicilyBindResponse ::= [APPLICATION 1] SEQUENCE {
#
# resultCode ENUMERATED {
# success (0),
# protocolError (2),
# adminLimitExceeded (11),
# inappropriateAuthentication (48),
# invalidCredentials (49),
# busy (51),
# unavailable (52),
# unwillingToPerform (53),
# other (80) },
#
# serverCreds OCTET STRING,
# errorMessage LDAPString }
# BindResponse ::= [APPLICATION 1] SEQUENCE {
# COMPONENTS OF LDAPResult,
# serverSaslCreds [7] OCTET STRING OPTIONAL }
tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 1))
componentType = NamedTypes(NamedType('resultCode', ResultCode()),
NamedType('serverCreds', OctetString()),
NamedType('errorMessage', LDAPString())
)
class DirSyncControlRequestValue(Sequence):
# DirSyncRequestValue ::= SEQUENCE {
# Flags integer
# MaxBytes integer
# Cookie OCTET STRING }
componentType = NamedTypes(NamedType('Flags', Integer()),
NamedType('MaxBytes', Integer()),
NamedType('Cookie', OctetString())
)
class DirSyncControlResponseValue(Sequence):
# DirSyncResponseValue ::= SEQUENCE {
# MoreResults INTEGER
# unused INTEGER
# CookieServer OCTET STRING
# }
componentType = NamedTypes(NamedType('MoreResults', Integer()),
NamedType('unused', Integer()),
NamedType('CookieServer', OctetString())
)
class SdFlags(Sequence):
# SDFlagsRequestValue ::= SEQUENCE {
# Flags INTEGER
# }
componentType = NamedTypes(NamedType('Flags', Integer())
)
class ExtendedDN(Sequence):
# A flag value 0 specifies that the GUID and SID values be returned in hexadecimal string
# A flag value of 1 will return the GUID and SID values in standard string format
componentType = NamedTypes(NamedType('option', Integer())
)
def dir_sync_control(criticality, object_security, ancestors_first, public_data_only, incremental_values, max_length, cookie):
control_value = DirSyncControlRequestValue()
flags = 0x0
if object_security:
flags |= 0x00000001
if ancestors_first:
flags |= 0x00000800
if public_data_only:
flags |= 0x00002000
if incremental_values:
flags |= 0x80000000
# converts flags to signed 32 bit (AD expects a 4 bytes long unsigned integer, but ASN.1 Integer type is signed
# so the BER encoder gives back a 5 bytes long signed integer
flags = ctypes.c_long(flags & 0xFFFFFFFF).value
control_value.setComponentByName('Flags', flags)
control_value.setComponentByName('MaxBytes', max_length)
if cookie:
control_value.setComponentByName('Cookie', cookie)
else:
control_value.setComponentByName('Cookie', OctetString(''))
return build_control('1.2.840.113556.1.4.841', criticality, control_value)
def extended_dn_control(criticality=False, hex_format=False):
control_value = ExtendedDN()
control_value.setComponentByName('option', Integer(not hex_format))
return build_control('1.2.840.113556.1.4.529', criticality, control_value)
def show_deleted_control(criticality=False):
return build_control('1.2.840.113556.1.4.417', criticality, value=None)
def security_descriptor_control(criticality=False, sdflags=0x0F):
sdcontrol = SdFlags()
sdcontrol.setComponentByName('Flags', sdflags)
return [build_control('1.2.840.113556.1.4.801', criticality, sdcontrol)]
def persistent_search_control(criticality=False):
return build_control('1.2.840.113556.1.4.528', criticality, value=None)

View File

@@ -0,0 +1,141 @@
"""
"""
# Created on 2014.06.27
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from pyasn1.type.univ import OctetString, Integer, Sequence, SequenceOf
from pyasn1.type.namedtype import NamedType, NamedTypes, OptionalNamedType
from pyasn1.type.tag import Tag, tagFormatSimple, tagClassUniversal, TagSet
NMAS_LDAP_EXT_VERSION = 1
class Identity(OctetString):
encoding = 'utf-8'
class LDAPDN(OctetString):
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 4))
encoding = 'utf-8'
class Password(OctetString):
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 4))
encoding = 'utf-8'
class LDAPOID(OctetString):
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 4))
encoding = 'utf-8'
class GroupCookie(Integer):
tagSet = Integer.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 2))
class NmasVer(Integer):
tagSet = Integer.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 2))
class Error(Integer):
tagSet = Integer.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatSimple, 2))
class NmasGetUniversalPasswordRequestValue(Sequence):
componentType = NamedTypes(NamedType('nmasver', NmasVer()),
NamedType('reqdn', Identity())
)
class NmasGetUniversalPasswordResponseValue(Sequence):
componentType = NamedTypes(NamedType('nmasver', NmasVer()),
NamedType('err', Error()),
OptionalNamedType('passwd', Password())
)
class NmasSetUniversalPasswordRequestValue(Sequence):
componentType = NamedTypes(NamedType('nmasver', NmasVer()),
NamedType('reqdn', Identity()),
NamedType('new_passwd', Password())
)
class NmasSetUniversalPasswordResponseValue(Sequence):
componentType = NamedTypes(NamedType('nmasver', NmasVer()),
NamedType('err', Error())
)
class ReplicaList(SequenceOf):
componentType = OctetString()
class ReplicaInfoRequestValue(Sequence):
tagSet = TagSet()
componentType = NamedTypes(NamedType('server_dn', LDAPDN()),
NamedType('partition_dn', LDAPDN())
)
class ReplicaInfoResponseValue(Sequence):
# tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3))
tagSet = TagSet()
componentType = NamedTypes(NamedType('partition_id', Integer()),
NamedType('replica_state', Integer()),
NamedType('modification_time', Integer()),
NamedType('purge_time', Integer()),
NamedType('local_partition_id', Integer()),
NamedType('partition_dn', LDAPDN()),
NamedType('replica_type', Integer()),
NamedType('flags', Integer())
)
class CreateGroupTypeRequestValue(Sequence):
componentType = NamedTypes(NamedType('createGroupType', LDAPOID()),
OptionalNamedType('createGroupValue', OctetString())
)
class CreateGroupTypeResponseValue(Sequence):
componentType = NamedTypes(NamedType('createGroupCookie', GroupCookie()),
OptionalNamedType('createGroupValue', OctetString())
)
class EndGroupTypeRequestValue(Sequence):
componentType = NamedTypes(NamedType('endGroupCookie', GroupCookie()),
OptionalNamedType('endGroupValue', OctetString())
)
class EndGroupTypeResponseValue(Sequence):
componentType = NamedTypes(OptionalNamedType('endGroupValue', OctetString())
)
class GroupingControlValue(Sequence):
componentType = NamedTypes(NamedType('groupingCookie', GroupCookie()),
OptionalNamedType('groupValue', OctetString())
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
"""
"""
# Created on 2016.07.09
#
# Author: Giovanni Cannata
#
# Copyright 2016 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from pyasn1.type.namedtype import NamedTypes, NamedType, OptionalNamedType
from pyasn1.type.namedval import NamedValues
from pyasn1.type.univ import Sequence, Integer, Boolean, Enumerated
from .rfc4511 import LDAPDN
from .controls import build_control
class PersistentSearchControl(Sequence):
# PersistentSearch ::= SEQUENCE {
# changeTypes INTEGER,
# changesOnly BOOLEAN,
# returnECs BOOLEAN
# }
componentType = NamedTypes(NamedType('changeTypes', Integer()),
NamedType('changesOnly', Boolean()),
NamedType('returnECs', Boolean())
)
class ChangeType(Enumerated):
# changeType ENUMERATED {
# add (1),
# delete (2),
# modify (4),
# modDN (8)
# }
namedValues = NamedValues(('add', 1),
('delete', 2),
('modify', 4),
('modDN', 8))
class EntryChangeNotificationControl(Sequence):
# EntryChangeNotification ::= SEQUENCE {
# changeType ENUMERATED {
# add (1),
# delete (2),
# modify (4),
# modDN (8)
# },
# previousDN LDAPDN OPTIONAL, -- modifyDN ops. only
# changeNumber INTEGER OPTIONAL -- if supported
# }
# tagSet = TagSet()
# tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassUniversal, tagFormatConstructed, 16))
componentType = NamedTypes(NamedType('changeType', ChangeType()),
OptionalNamedType('previousDN', LDAPDN()),
OptionalNamedType('changeNumber', Integer())
)
def persistent_search_control(change_types, changes_only=True, return_ecs=True, criticality=False):
control_value = PersistentSearchControl()
control_value.setComponentByName('changeTypes', Integer(change_types))
control_value.setComponentByName('changesOnly', Boolean(changes_only))
control_value.setComponentByName('returnECs', Boolean(return_ecs))
return build_control('2.16.840.1.113730.3.4.3', criticality, control_value)

View File

@@ -0,0 +1,70 @@
"""
"""
# Created on 2013.10.15
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from pyasn1.type.univ import OctetString, Integer, Sequence
from pyasn1.type.namedtype import NamedTypes, NamedType
from pyasn1.type.constraint import ValueRangeConstraint
from .controls import build_control
# constants
# maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
MAXINT = Integer(2147483647)
# constraints
rangeInt0ToMaxConstraint = ValueRangeConstraint(0, MAXINT)
class Integer0ToMax(Integer):
subtypeSpec = Integer.subtypeSpec + rangeInt0ToMaxConstraint
class Size(Integer0ToMax):
# Size INTEGER (0..maxInt)
pass
class Cookie(OctetString):
# cookie OCTET STRING
pass
class RealSearchControlValue(Sequence):
# realSearchControlValue ::= SEQUENCE {
# size INTEGER (0..maxInt),
# -- requested page size from client
# -- result set size estimate from server
# cookie OCTET STRING
componentType = NamedTypes(NamedType('size', Size()),
NamedType('cookie', Cookie()))
def paged_search_control(criticality=False, size=10, cookie=None):
control_value = RealSearchControlValue()
control_value.setComponentByName('size', Size(size))
control_value.setComponentByName('cookie', Cookie(cookie if cookie else ''))
return build_control('1.2.840.113556.1.4.319', criticality, control_value)

View File

@@ -0,0 +1,295 @@
"""
"""
# Created on 2013.12.08
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from base64 import b64encode
from datetime import datetime
from .. import STRING_TYPES
from ..core.exceptions import LDAPLDIFError, LDAPExtensionError
from ..protocol.persistentSearch import EntryChangeNotificationControl
from ..utils.asn1 import decoder
from ..utils.config import get_config_parameter
# LDIF converter RFC 2849 compliant
conf_ldif_line_length = get_config_parameter('LDIF_LINE_LENGTH')
def safe_ldif_string(bytes_value):
if not bytes_value:
return True
# check SAFE-INIT-CHAR: < 127, not NUL, LF, CR, SPACE, COLON, LESS-THAN
if bytes_value[0] > 127 or bytes_value[0] in [0, 10, 13, 32, 58, 60]:
return False
# check SAFE-CHAR: < 127 not NUL, LF, CR
if 0 in bytes_value or 10 in bytes_value or 13 in bytes_value:
return False
# check last char for SPACE
if bytes_value[-1] == 32:
return False
for byte in bytes_value:
if byte > 127:
return False
return True
def _convert_to_ldif(descriptor, value, base64):
if not value:
value = ''
if isinstance(value, STRING_TYPES):
value = bytearray(value, encoding='utf-8')
if base64 or not safe_ldif_string(value):
try:
encoded = b64encode(value)
except TypeError:
encoded = b64encode(str(value)) # patch for Python 2.6
if not isinstance(encoded, str): # in Python 3 b64encode returns bytes in Python 2 returns str
encoded = str(encoded, encoding='ascii') # Python 3
line = descriptor + ':: ' + encoded
else:
if str is not bytes: # Python 3
value = str(value, encoding='ascii')
else: # Python 2
value = str(value)
line = descriptor + ': ' + value
return line
def add_controls(controls, all_base64):
lines = []
if controls:
for control in controls:
line = 'control: ' + control[0]
line += ' ' + ('true' if control[1] else 'false')
if control[2]:
lines.append(_convert_to_ldif(line, control[2], all_base64))
return lines
def add_attributes(attributes, all_base64):
lines = []
oc_attr = None
# objectclass first, even if this is not specified in the RFC
for attr in attributes:
if attr.lower() == 'objectclass':
for val in attributes[attr]:
lines.append(_convert_to_ldif(attr, val, all_base64))
oc_attr = attr
break
# remaining attributes
for attr in attributes:
if attr != oc_attr and attr in attributes:
for val in attributes[attr]:
lines.append(_convert_to_ldif(attr, val, all_base64))
return lines
def sort_ldif_lines(lines, sort_order):
# sort lines as per custom sort_order
# sort order is a list of descriptors, lines will be sorted following the same sequence
return sorted(lines, key=lambda x: ldif_sort(x, sort_order)) if sort_order else lines
def search_response_to_ldif(entries, all_base64, sort_order=None):
lines = []
if entries:
for entry in entries:
if not entry or entry['type'] != 'searchResEntry':
continue
if 'dn' in entry:
lines.append(_convert_to_ldif('dn', entry['dn'], all_base64))
lines.extend(add_attributes(entry['raw_attributes'], all_base64))
else:
raise LDAPLDIFError('unable to convert to LDIF-CONTENT - missing DN')
if sort_order:
lines = sort_ldif_lines(lines, sort_order)
lines.append('')
if lines:
lines.append('# total number of entries: ' + str(len(entries)))
return lines
def add_request_to_ldif(entry, all_base64, sort_order=None):
lines = []
if 'entry' in entry:
lines.append(_convert_to_ldif('dn', entry['entry'], all_base64))
control_lines = add_controls(entry['controls'], all_base64)
if control_lines:
lines.extend(control_lines)
lines.append('changetype: add')
lines.extend(add_attributes(entry['attributes'], all_base64))
if sort_order:
lines = sort_ldif_lines(lines, sort_order)
else:
raise LDAPLDIFError('unable to convert to LDIF-CHANGE-ADD - missing DN ')
return lines
def delete_request_to_ldif(entry, all_base64, sort_order=None):
lines = []
if 'entry' in entry:
lines.append(_convert_to_ldif('dn', entry['entry'], all_base64))
control_lines = add_controls(entry['controls'], all_base64)
if control_lines:
lines.extend(control_lines)
lines.append('changetype: delete')
if sort_order:
lines = sort_ldif_lines(lines, sort_order)
else:
raise LDAPLDIFError('unable to convert to LDIF-CHANGE-DELETE - missing DN ')
return lines
def modify_request_to_ldif(entry, all_base64, sort_order=None):
lines = []
if 'entry' in entry:
lines.append(_convert_to_ldif('dn', entry['entry'], all_base64))
control_lines = add_controls(entry['controls'], all_base64)
if control_lines:
lines.extend(control_lines)
lines.append('changetype: modify')
if 'changes' in entry:
for change in entry['changes']:
lines.append(['add', 'delete', 'replace', 'increment'][change['operation']] + ': ' + change['attribute']['type'])
for value in change['attribute']['value']:
lines.append(_convert_to_ldif(change['attribute']['type'], value, all_base64))
lines.append('-')
if sort_order:
lines = sort_ldif_lines(lines, sort_order)
return lines
def modify_dn_request_to_ldif(entry, all_base64, sort_order=None):
lines = []
if 'entry' in entry:
lines.append(_convert_to_ldif('dn', entry['entry'], all_base64))
control_lines = add_controls(entry['controls'], all_base64)
if control_lines:
lines.extend(control_lines)
lines.append('changetype: modrdn') if 'newSuperior' in entry and entry['newSuperior'] else lines.append('changetype: moddn')
lines.append(_convert_to_ldif('newrdn', entry['newRdn'], all_base64))
lines.append('deleteoldrdn: ' + ('1' if entry['deleteOldRdn'] else '0'))
if 'newSuperior' in entry and entry['newSuperior']:
lines.append(_convert_to_ldif('newsuperior', entry['newSuperior'], all_base64))
if sort_order:
lines = sort_ldif_lines(lines, sort_order)
else:
raise LDAPLDIFError('unable to convert to LDIF-CHANGE-MODDN - missing DN ')
return lines
def operation_to_ldif(operation_type, entries, all_base64=False, sort_order=None):
if operation_type == 'searchResponse':
lines = search_response_to_ldif(entries, all_base64, sort_order)
elif operation_type == 'addRequest':
lines = add_request_to_ldif(entries, all_base64, sort_order)
elif operation_type == 'delRequest':
lines = delete_request_to_ldif(entries, all_base64, sort_order)
elif operation_type == 'modifyRequest':
lines = modify_request_to_ldif(entries, all_base64, sort_order)
elif operation_type == 'modDNRequest':
lines = modify_dn_request_to_ldif(entries, all_base64, sort_order)
else:
lines = []
ldif_record = []
# check max line length and split as per note 2 of RFC 2849
for line in lines:
if line:
ldif_record.append(line[0:conf_ldif_line_length])
ldif_record.extend([' ' + line[i: i + conf_ldif_line_length - 1] for i in range(conf_ldif_line_length, len(line), conf_ldif_line_length - 1)] if len(line) > conf_ldif_line_length else [])
else:
ldif_record.append('')
return ldif_record
def add_ldif_header(ldif_lines):
if ldif_lines:
ldif_lines.insert(0, 'version: 1')
return ldif_lines
def ldif_sort(line, sort_order):
for i, descriptor in enumerate(sort_order):
if line and line.startswith(descriptor):
return i
return len(sort_order) + 1
def decode_persistent_search_control(change):
if 'controls' in change and '2.16.840.1.113730.3.4.7' in change['controls']:
decoded = dict()
decoded_control, unprocessed = decoder.decode(change['controls']['2.16.840.1.113730.3.4.7']['value'], asn1Spec=EntryChangeNotificationControl())
if unprocessed:
raise LDAPExtensionError('unprocessed value in EntryChangeNotificationControl')
if decoded_control['changeType'] == 1: # add
decoded['changeType'] = 'add'
elif decoded_control['changeType'] == 2: # delete
decoded['changeType'] = 'delete'
elif decoded_control['changeType'] == 4: # modify
decoded['changeType'] = 'modify'
elif decoded_control['changeType'] == 8: # modify_dn
decoded['changeType'] = 'modify dn'
else:
raise LDAPExtensionError('unknown Persistent Search changeType ' + str(decoded_control['changeType']))
decoded['changeNumber'] = decoded_control['changeNumber'] if 'changeNumber' in decoded_control and decoded_control['changeNumber'] is not None and decoded_control['changeNumber'].hasValue() else None
decoded['previousDN'] = decoded_control['previousDN'] if 'previousDN' in decoded_control and decoded_control['previousDN'] is not None and decoded_control['previousDN'].hasValue() else None
return decoded
return None
def persistent_search_response_to_ldif(change):
ldif_lines = ['# ' + datetime.now().isoformat()]
control = decode_persistent_search_control(change)
if control:
if control['changeNumber']:
ldif_lines.append('# change number: ' + str(control['changeNumber']))
ldif_lines.append(control['changeType'])
if control['previousDN']:
ldif_lines.append('# previous dn: ' + str(control['previousDN']))
ldif_lines += operation_to_ldif('searchResponse', [change])
return ldif_lines[:-1] # removes "total number of entries"

View File

@@ -0,0 +1,91 @@
"""
"""
# Created on 2014.04.28
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from pyasn1.type.univ import OctetString, Sequence
from pyasn1.type.namedtype import NamedTypes, OptionalNamedType
from pyasn1.type.tag import Tag, tagClassContext, tagFormatSimple
# Modify password extended operation
# passwdModifyOID OBJECT IDENTIFIER ::= 1.3.6.1.4.1.4203.1.11.1
# PasswdModifyRequestValue ::= SEQUENCE {
# userIdentity [0] OCTET STRING OPTIONAL
# oldPasswd [1] OCTET STRING OPTIONAL
# newPasswd [2] OCTET STRING OPTIONAL }
#
# PasswdModifyResponseValue ::= SEQUENCE {
# genPasswd [0] OCTET STRING OPTIONAL }
class UserIdentity(OctetString):
"""
userIdentity [0] OCTET STRING OPTIONAL
"""
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
encoding = 'utf-8'
class OldPasswd(OctetString):
"""
oldPasswd [1] OCTET STRING OPTIONAL
"""
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1))
encoding = 'utf-8'
class NewPasswd(OctetString):
"""
newPasswd [2] OCTET STRING OPTIONAL
"""
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 2))
encoding = 'utf-8'
class GenPasswd(OctetString):
"""
newPasswd [2] OCTET STRING OPTIONAL
"""
tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
encoding = 'utf-8'
class PasswdModifyRequestValue(Sequence):
"""
PasswdModifyRequestValue ::= SEQUENCE {
userIdentity [0] OCTET STRING OPTIONAL
oldPasswd [1] OCTET STRING OPTIONAL
newPasswd [2] OCTET STRING OPTIONAL }
"""
componentType = NamedTypes(OptionalNamedType('userIdentity', UserIdentity()),
OptionalNamedType('oldPasswd', OldPasswd()),
OptionalNamedType('newPasswd', NewPasswd()))
class PasswdModifyResponseValue(Sequence):
"""
PasswdModifyResponseValue ::= SEQUENCE {
genPasswd [0] OCTET STRING OPTIONAL }
"""
componentType = NamedTypes(OptionalNamedType('genPasswd', GenPasswd()))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,850 @@
"""
"""
# Created on 2013.09.11
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from os import linesep
import re
import json
from .oid import CLASS_ABSTRACT, CLASS_STRUCTURAL, CLASS_AUXILIARY, ATTRIBUTE_USER_APPLICATION, \
ATTRIBUTE_DIRECTORY_OPERATION, ATTRIBUTE_DISTRIBUTED_OPERATION, ATTRIBUTE_DSA_OPERATION
from .. import SEQUENCE_TYPES, STRING_TYPES, get_config_parameter
from ..utils.conv import escape_bytes, json_hook, check_json_dict, format_json, to_unicode
from ..utils.ciDict import CaseInsensitiveWithAliasDict
from ..protocol.formatters.standard import format_attribute_values
from .oid import Oids, decode_oids, decode_syntax, oid_to_string
from ..core.exceptions import LDAPSchemaError, LDAPDefinitionError
def constant_to_class_kind(value):
if value == CLASS_STRUCTURAL:
return 'Structural'
elif value == CLASS_ABSTRACT:
return 'Abstract'
elif value == CLASS_AUXILIARY:
return 'Auxiliary'
else:
return '<unknown>'
def constant_to_attribute_usage(value):
if value == ATTRIBUTE_USER_APPLICATION:
return 'User Application'
elif value == ATTRIBUTE_DIRECTORY_OPERATION:
return "Directory operation"
elif value == ATTRIBUTE_DISTRIBUTED_OPERATION:
return 'Distributed operation'
elif value == ATTRIBUTE_DSA_OPERATION:
return 'DSA operation'
else:
return 'unknown'
def attribute_usage_to_constant(value):
if value == 'userApplications':
return ATTRIBUTE_USER_APPLICATION
elif value == 'directoryOperation':
return ATTRIBUTE_DIRECTORY_OPERATION
elif value == 'distributedOperation':
return ATTRIBUTE_DISTRIBUTED_OPERATION
elif value == 'dSAOperation':
return ATTRIBUTE_DSA_OPERATION
else:
return 'unknown'
def quoted_string_to_list(quoted_string):
string = quoted_string.strip()
if not string:
return list()
if string[0] == '(' and string[-1] == ')':
string = string[1:-1]
elements = string.split("'")
# return [check_escape(element.strip("'").strip()) for element in elements if element.strip()]
return [element.strip("'").strip() for element in elements if element.strip()]
def oids_string_to_list(oid_string):
string = oid_string.strip()
if string[0] == '(' and string[-1] == ')':
string = string[1:-1]
elements = string.split('$')
return [element.strip() for element in elements if element.strip()]
def extension_to_tuple(extension_string):
string = extension_string.strip()
name, _, values = string.partition(' ')
return name, quoted_string_to_list(values)
def list_to_string(list_object):
if not isinstance(list_object, SEQUENCE_TYPES):
return list_object
r = ''
for element in list_object:
r += (list_to_string(element) if isinstance(element, SEQUENCE_TYPES) else str(element)) + ', '
return r[:-2] if r else ''
class BaseServerInfo(object):
def __init__(self, raw_attributes):
self.raw = dict(raw_attributes)
@classmethod
def from_json(cls, json_definition, schema=None, custom_formatter=None):
conf_case_insensitive_schema = get_config_parameter('CASE_INSENSITIVE_SCHEMA_NAMES')
definition = json.loads(json_definition, object_hook=json_hook)
if 'raw' not in definition or 'type' not in definition:
raise LDAPDefinitionError('invalid JSON definition')
if conf_case_insensitive_schema:
attributes = CaseInsensitiveWithAliasDict()
else:
attributes = dict()
if schema:
for attribute in definition['raw']:
# attributes[attribute] = format_attribute_values(schema, check_escape(attribute), [check_escape(value) for value in definition['raw'][attribute]], custom_formatter)
attributes[attribute] = format_attribute_values(schema, attribute, [value for value in definition['raw'][attribute]], custom_formatter)
else:
for attribute in definition['raw']:
# attributes[attribute] = [check_escape(value) for value in definition['raw'][attribute]]
attributes[attribute] = [value for value in definition['raw'][attribute]]
if cls.__name__ != definition['type']:
raise LDAPDefinitionError('JSON info not of type ' + cls.__name__)
if definition['type'] == 'DsaInfo':
return DsaInfo(attributes, definition['raw'])
elif definition['type'] == 'SchemaInfo':
if 'schema_entry' not in definition:
raise LDAPDefinitionError('invalid schema in JSON')
return SchemaInfo(definition['schema_entry'], attributes, definition['raw'])
raise LDAPDefinitionError('invalid Info type ' + str(definition['type']) + ' in JSON definition')
@classmethod
def from_file(cls, target, schema=None, custom_formatter=None):
if isinstance(target, STRING_TYPES):
target = open(target, 'r')
new = cls.from_json(target.read(), schema=schema, custom_formatter=custom_formatter)
target.close()
return new
def to_file(self,
target,
indent=4,
sort=True):
if isinstance(target, STRING_TYPES):
target = open(target, 'w+')
target.writelines(self.to_json(indent=indent, sort=sort))
target.close()
def __str__(self):
return self.__repr__()
def to_json(self,
indent=4,
sort=True):
json_dict = dict()
json_dict['type'] = self.__class__.__name__
json_dict['raw'] = self.raw
if isinstance(self, SchemaInfo):
json_dict['schema_entry'] = self.schema_entry
elif isinstance(self, DsaInfo):
pass
else:
raise LDAPDefinitionError('unable to convert ' + str(self) + ' to JSON')
if str is bytes: # Python 2
check_json_dict(json_dict)
return json.dumps(json_dict, ensure_ascii=False, sort_keys=sort, indent=indent, check_circular=True, default=format_json, separators=(',', ': '))
class DsaInfo(BaseServerInfo):
"""
This class contains info about the ldap server (DSA) read from DSE
as defined in RFC4512 and RFC3045. Unknown attributes are stored in the "other" dict
"""
def __init__(self, attributes, raw_attributes):
BaseServerInfo.__init__(self, raw_attributes)
self.alt_servers = attributes.pop('altServer', None)
self.naming_contexts = attributes.pop('namingContexts', None)
self.supported_controls = decode_oids(attributes.pop('supportedControl', None))
self.supported_extensions = decode_oids(attributes.pop('supportedExtension', None))
self.supported_features = decode_oids(attributes.pop('supportedFeatures', None)) + decode_oids(attributes.pop('supportedCapabilities', None))
self.supported_ldap_versions = attributes.pop('supportedLDAPVersion', None)
self.supported_sasl_mechanisms = attributes.pop('supportedSASLMechanisms', None)
self.vendor_name = attributes.pop('vendorName', None)
self.vendor_version = attributes.pop('vendorVersion', None)
self.schema_entry = attributes.pop('subschemaSubentry', None)
self.other = attributes # remaining schema definition attributes not in RFC4512
def __repr__(self):
r = 'DSA info (from DSE):' + linesep
if self.supported_ldap_versions:
if isinstance(self.supported_ldap_versions, SEQUENCE_TYPES):
r += (' Supported LDAP versions: ' + ', '.join([str(s) for s in self.supported_ldap_versions])) if self.supported_ldap_versions else ''
else:
r += (' Supported LDAP versions: ' + str(self.supported_ldap_versions))
r += linesep
if self.naming_contexts:
if isinstance(self.naming_contexts, SEQUENCE_TYPES):
r += (' Naming contexts: ' + linesep + linesep.join([' ' + str(s) for s in self.naming_contexts])) if self.naming_contexts else ''
else:
r += (' Naming contexts: ' + str(self.naming_contexts))
r += linesep
if self.alt_servers:
if isinstance(self.alt_servers, SEQUENCE_TYPES):
r += (' Alternative servers: ' + linesep + linesep.join([' ' + str(s) for s in self.alt_servers])) if self.alt_servers else ''
else:
r += (' Alternative servers: ' + str(self.alt_servers))
r += linesep
if self.supported_controls:
if isinstance(self.supported_controls, SEQUENCE_TYPES):
r += (' Supported controls: ' + linesep + linesep.join([' ' + oid_to_string(s) for s in self.supported_controls])) if self.supported_controls else ''
else:
r += (' Supported controls: ' + str(self.supported_controls))
r += linesep
if self.supported_extensions:
if isinstance(self.supported_extensions, SEQUENCE_TYPES):
r += (' Supported extensions: ' + linesep + linesep.join([' ' + oid_to_string(s) for s in self.supported_extensions])) if self.supported_extensions else ''
else:
r += (' Supported extensions: ' + str(self.supported_extensions))
r += linesep
if self.supported_features:
if self.supported_features:
if isinstance(self.supported_features, SEQUENCE_TYPES):
r += (' Supported features: ' + linesep + linesep.join([' ' + oid_to_string(s) for s in self.supported_features])) if self.supported_features else ''
else:
r += (' Supported features: ' + str(self.supported_features))
r += linesep
if self.supported_sasl_mechanisms:
if isinstance(self.supported_sasl_mechanisms, SEQUENCE_TYPES):
r += (' Supported SASL mechanisms: ' + linesep + ' ' + ', '.join([str(s) for s in self.supported_sasl_mechanisms])) if self.supported_sasl_mechanisms else ''
else:
r += (' Supported SASL mechanisms: ' + str(self.supported_sasl_mechanisms))
r += linesep
if self.schema_entry:
if isinstance(self.schema_entry, SEQUENCE_TYPES):
r += (' Schema entry: ' + linesep + linesep.join([' ' + str(s) for s in self.schema_entry])) if self.schema_entry else ''
else:
r += (' Schema entry: ' + str(self.schema_entry))
r += linesep
if self.vendor_name:
if isinstance(self.vendor_name, SEQUENCE_TYPES) and len(self.vendor_name) == 1:
r += 'Vendor name: ' + self.vendor_name[0]
else:
r += 'Vendor name: ' + str(self.vendor_name)
r += linesep
if self.vendor_version:
if isinstance(self.vendor_version, SEQUENCE_TYPES) and len(self.vendor_version) == 1:
r += 'Vendor version: ' + self.vendor_version[0]
else:
r += 'Vendor version: ' + str(self.vendor_version)
r += linesep
r += 'Other:' + linesep
for k, v in self.other.items():
r += ' ' + str(k) + ': ' + linesep
try:
r += (linesep.join([' ' + str(s) for s in v])) if isinstance(v, SEQUENCE_TYPES) else str(v)
except UnicodeDecodeError:
r += (linesep.join([' ' + str(escape_bytes(s)) for s in v])) if isinstance(v, SEQUENCE_TYPES) else str(escape_bytes(v))
r += linesep
return r
class SchemaInfo(BaseServerInfo):
"""
This class contains info about the ldap server schema read from an entry (default entry is DSE)
as defined in RFC4512. Unknown attributes are stored in the "other" dict
"""
def __init__(self, schema_entry, attributes, raw_attributes):
BaseServerInfo.__init__(self, raw_attributes)
self.schema_entry = schema_entry
self.create_time_stamp = attributes.pop('createTimestamp', None)
self.modify_time_stamp = attributes.pop('modifyTimestamp', None)
self.attribute_types = AttributeTypeInfo.from_definition(attributes.pop('attributeTypes', []))
self.object_classes = ObjectClassInfo.from_definition(attributes.pop('objectClasses', []))
self.matching_rules = MatchingRuleInfo.from_definition(attributes.pop('matchingRules', []))
self.matching_rule_uses = MatchingRuleUseInfo.from_definition(attributes.pop('matchingRuleUse', []))
self.dit_content_rules = DitContentRuleInfo.from_definition(attributes.pop('dITContentRules', []))
self.dit_structure_rules = DitStructureRuleInfo.from_definition(attributes.pop('dITStructureRules', []))
self.name_forms = NameFormInfo.from_definition(attributes.pop('nameForms', []))
self.ldap_syntaxes = LdapSyntaxInfo.from_definition(attributes.pop('ldapSyntaxes', []))
self.other = attributes # remaining schema definition attributes not in RFC4512
# links attributes to class objects
if self.object_classes and self.attribute_types:
for object_class in self.object_classes: # CaseInsensitiveDict return keys while iterating
for attribute in self.object_classes[object_class].must_contain:
try:
self.attribute_types[attribute].mandatory_in.append(object_class)
except KeyError:
pass
for attribute in self.object_classes[object_class].may_contain:
try:
self.attribute_types[attribute].optional_in.append(object_class)
except KeyError:
pass
def is_valid(self):
if self.object_classes or self.attribute_types or self.matching_rules or self.matching_rule_uses or self.dit_content_rules or self.dit_structure_rules or self.name_forms or self.ldap_syntaxes:
return True
return False
def __repr__(self):
r = 'DSA Schema from: ' + self.schema_entry
r += linesep
if isinstance(self.attribute_types, SEQUENCE_TYPES):
r += (' Attribute types:' + linesep + ' ' + ', '.join([str(self.attribute_types[s]) for s in self.attribute_types])) if self.attribute_types else ''
else:
r += (' Attribute types:' + str(self.attribute_types))
r += linesep
if isinstance(self.object_classes, SEQUENCE_TYPES):
r += (' Object classes:' + linesep + ' ' + ', '.join([str(self.object_classes[s]) for s in self.object_classes])) if self.object_classes else ''
else:
r += (' Object classes:' + str(self.object_classes))
r += linesep
if isinstance(self.matching_rules, SEQUENCE_TYPES):
r += (' Matching rules:' + linesep + ' ' + ', '.join([str(self.matching_rules[s]) for s in self.matching_rules])) if self.matching_rules else ''
else:
r += (' Matching rules:' + str(self.matching_rules))
r += linesep
if isinstance(self.matching_rule_uses, SEQUENCE_TYPES):
r += (' Matching rule uses:' + linesep + ' ' + ', '.join([str(self.matching_rule_uses[s]) for s in self.matching_rule_uses])) if self.matching_rule_uses else ''
else:
r += (' Matching rule uses:' + str(self.matching_rule_uses))
r += linesep
if isinstance(self.dit_content_rules, SEQUENCE_TYPES):
r += (' DIT content rules:' + linesep + ' ' + ', '.join([str(self.dit_content_rules[s]) for s in self.dit_content_rules])) if self.dit_content_rules else ''
else:
r += (' DIT content rules:' + str(self.dit_content_rules))
r += linesep
if isinstance(self.dit_structure_rules, SEQUENCE_TYPES):
r += (' DIT structure rules:' + linesep + ' ' + ', '.join([str(self.dit_structure_rules[s]) for s in self.dit_structure_rules])) if self.dit_structure_rules else ''
else:
r += (' DIT structure rules:' + str(self.dit_structure_rules))
r += linesep
if isinstance(self.name_forms, SEQUENCE_TYPES):
r += (' Name forms:' + linesep + ' ' + ', '.join([str(self.name_forms[s]) for s in self.name_forms])) if self.name_forms else ''
else:
r += (' Name forms:' + str(self.name_forms))
r += linesep
if isinstance(self.ldap_syntaxes, SEQUENCE_TYPES):
r += (' LDAP syntaxes:' + linesep + ' ' + ', '.join([str(self.ldap_syntaxes[s]) for s in self.ldap_syntaxes])) if self.ldap_syntaxes else ''
else:
r += (' LDAP syntaxes:' + str(self.ldap_syntaxes))
r += linesep
r += 'Other:' + linesep
for k, v in self.other.items():
r += ' ' + str(k) + ': ' + linesep
try:
r += (linesep.join([' ' + str(s) for s in v])) if isinstance(v, SEQUENCE_TYPES) else str(v)
except UnicodeDecodeError:
r += (linesep.join([' ' + str(escape_bytes(s)) for s in v])) if isinstance(v, SEQUENCE_TYPES) else str(escape_bytes(v))
r += linesep
return r
class BaseObjectInfo(object):
"""
Base class for objects defined in the schema as per RFC4512
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
extensions=None,
experimental=None,
definition=None):
self.oid = oid
self.name = name
self.description = description
self.obsolete = obsolete
self.extensions = extensions
self.experimental = experimental
self.raw_definition = definition
self._oid_info = None
@property
def oid_info(self):
if self._oid_info is None and self.oid:
self._oid_info = Oids.get(self.oid, '')
return self._oid_info if self._oid_info else None
def __str__(self):
return self.__repr__()
def __repr__(self):
r = ': ' + self.oid
r += ' [OBSOLETE]' if self.obsolete else ''
r += (linesep + ' Short name: ' + list_to_string(self.name)) if self.name else ''
r += (linesep + ' Description: ' + self.description) if self.description else ''
r += '<__desc__>'
r += (linesep + ' Extensions:' + linesep + linesep.join([' ' + s[0] + ': ' + list_to_string(s[1]) for s in self.extensions])) if self.extensions else ''
r += (linesep + ' Experimental:' + linesep + linesep.join([' ' + s[0] + ': ' + list_to_string(s[1]) for s in self.experimental])) if self.experimental else ''
r += (linesep + ' OidInfo: ' + str(self.oid_info)) if self.oid_info else ''
r += linesep
return r
@classmethod
def from_definition(cls, definitions):
conf_case_insensitive_schema = get_config_parameter('CASE_INSENSITIVE_SCHEMA_NAMES')
conf_ignore_malformed_schema = get_config_parameter('IGNORE_MALFORMED_SCHEMA')
ret_dict = CaseInsensitiveWithAliasDict() if conf_case_insensitive_schema else dict()
if not definitions:
return ret_dict
for object_definition in definitions:
object_definition = to_unicode(object_definition.strip(), from_server=True)
if object_definition[0] == '(' and object_definition[-1] == ')':
if cls is MatchingRuleInfo:
pattern = '| SYNTAX '
elif cls is ObjectClassInfo:
pattern = '| SUP | ABSTRACT| STRUCTURAL| AUXILIARY| MUST | MAY '
elif cls is AttributeTypeInfo:
pattern = '| SUP | EQUALITY | ORDERING | SUBSTR | SYNTAX | SINGLE-VALUE| COLLECTIVE| NO-USER-MODIFICATION| USAGE '
elif cls is MatchingRuleUseInfo:
pattern = '| APPLIES '
elif cls is LdapSyntaxInfo:
pattern = ''
elif cls is DitContentRuleInfo:
pattern = '| AUX | MUST | MAY | NOT '
elif cls is DitStructureRuleInfo:
pattern = '| FORM | SUP '
elif cls is NameFormInfo:
pattern = '| OC | MUST | MAY '
else:
raise LDAPSchemaError('unknown schema definition class')
splitted = re.split('( NAME | DESC | OBSOLETE| X-| E-' + pattern + ')', object_definition[1:-1])
values = splitted[::2]
separators = splitted[1::2]
separators.insert(0, 'OID')
defs = list(zip(separators, values))
object_def = cls()
for d in defs:
key = d[0].strip()
value = d[1].strip()
if key == 'OID':
object_def.oid = value
elif key == 'NAME':
object_def.name = quoted_string_to_list(value)
elif key == 'DESC':
object_def.description = value.strip("'")
elif key == 'OBSOLETE':
object_def.obsolete = True
elif key == 'SYNTAX':
object_def.syntax = oids_string_to_list(value)
elif key == 'SUP':
object_def.superior = oids_string_to_list(value)
elif key == 'ABSTRACT':
object_def.kind = CLASS_ABSTRACT
elif key == 'STRUCTURAL':
object_def.kind = CLASS_STRUCTURAL
elif key == 'AUXILIARY':
object_def.kind = CLASS_AUXILIARY
elif key == 'MUST':
object_def.must_contain = oids_string_to_list(value)
elif key == 'MAY':
object_def.may_contain = oids_string_to_list(value)
elif key == 'EQUALITY':
object_def.equality = oids_string_to_list(value)
elif key == 'ORDERING':
object_def.ordering = oids_string_to_list(value)
elif key == 'SUBSTR':
object_def.substr = oids_string_to_list(value)
elif key == 'SINGLE-VALUE':
object_def.single_value = True
elif key == 'COLLECTIVE':
object_def.collective = True
elif key == 'NO-USER-MODIFICATION':
object_def.no_user_modification = True
elif key == 'USAGE':
object_def.usage = attribute_usage_to_constant(value)
elif key == 'APPLIES':
object_def.apply_to = oids_string_to_list(value)
elif key == 'AUX':
object_def.auxiliary_classes = oids_string_to_list(value)
elif key == 'FORM':
object_def.name_form = oids_string_to_list(value)
elif key == 'OC':
object_def.object_class = oids_string_to_list(value)
elif key == 'NOT':
object_def.not_contains = oids_string_to_list(value)
elif key == 'X-':
if not object_def.extensions:
object_def.extensions = []
object_def.extensions.append(extension_to_tuple('X-' + value))
elif key == 'E-':
if not object_def.experimental:
object_def.experimental = []
object_def.experimental.append(extension_to_tuple('E-' + value))
else:
if not conf_ignore_malformed_schema:
raise LDAPSchemaError('malformed schema definition key:' + key + ' - use get_info=NONE in Server definition')
else:
return CaseInsensitiveWithAliasDict() if conf_case_insensitive_schema else dict()
object_def.raw_definition = object_definition
if hasattr(object_def, 'syntax') and object_def.syntax and len(object_def.syntax) == 1:
object_def.min_length = None
if object_def.syntax[0].endswith('}'):
try:
object_def.min_length = int(object_def.syntax[0][object_def.syntax[0].index('{') + 1:-1])
object_def.syntax[0] = object_def.syntax[0][:object_def.syntax[0].index('{')]
except Exception:
pass
else:
object_def.min_length = None
object_def.syntax[0] = object_def.syntax[0].strip("'")
object_def.syntax = object_def.syntax[0]
if hasattr(object_def, 'name') and object_def.name:
if conf_case_insensitive_schema:
ret_dict[object_def.name[0]] = object_def
ret_dict.set_alias(object_def.name[0], object_def.name[1:] + [object_def.oid], ignore_duplicates=True)
else:
for name in object_def.name:
ret_dict[name] = object_def
else:
ret_dict[object_def.oid] = object_def
else:
if not conf_ignore_malformed_schema:
raise LDAPSchemaError('malformed schema definition, use get_info=NONE in Server definition')
else:
return CaseInsensitiveWithAliasDict() if conf_case_insensitive_schema else dict()
return ret_dict
class MatchingRuleInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.3)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
syntax=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.syntax = syntax
def __repr__(self):
r = (linesep + ' Syntax: ' + list_to_string(self.syntax)) if self.syntax else ''
return 'Matching rule' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class MatchingRuleUseInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.4)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
apply_to=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.apply_to = apply_to
def __repr__(self):
r = (linesep + ' Apply to: ' + list_to_string(self.apply_to)) if self.apply_to else ''
return 'Matching rule use' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class ObjectClassInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.1)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
superior=None,
kind=None,
must_contain=None,
may_contain=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.superior = superior
self.kind = kind
self.must_contain = must_contain or []
self.may_contain = may_contain or []
def __repr__(self):
r = ''
r += (linesep + ' Type: ' + constant_to_class_kind(self.kind)) if self.kind else ''
r += (linesep + ' Superior: ' + list_to_string(self.superior)) if self.superior else ''
r += (linesep + ' Must contain attributes: ' + list_to_string(self.must_contain)) if self.must_contain else ''
r += (linesep + ' May contain attributes: ' + list_to_string(self.may_contain)) if self.may_contain else ''
return 'Object class' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class AttributeTypeInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.2)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
superior=None,
equality=None,
ordering=None,
substring=None,
syntax=None,
min_length=None,
single_value=False,
collective=False,
no_user_modification=False,
usage=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.superior = superior
self.equality = equality
self.ordering = ordering
self.substring = substring
self.syntax = syntax
self.min_length = min_length
self.single_value = single_value
self.collective = collective
self.no_user_modification = no_user_modification
self.usage = usage
self.mandatory_in = []
self.optional_in = []
def __repr__(self):
r = ''
r += linesep + ' Single value: ' + str(self.single_value)
r += linesep + ' Collective: True' if self.collective else ''
r += (linesep + ' Superior: ' + list_to_string(self.superior)) if self.superior else ''
r += linesep + ' No user modification: True' if self.no_user_modification else ''
r += (linesep + ' Usage: ' + constant_to_attribute_usage(self.usage)) if self.usage else ''
r += (linesep + ' Equality rule: ' + list_to_string(self.equality)) if self.equality else ''
r += (linesep + ' Ordering rule: ' + list_to_string(self.ordering)) if self.ordering else ''
r += (linesep + ' Substring rule: ' + list_to_string(self.substring)) if self.substring else ''
r += (linesep + ' Syntax: ' + (self.syntax + (' [' + str(decode_syntax(self.syntax)))) + ']') if self.syntax else ''
r += (linesep + ' Minimum length: ' + str(self.min_length)) if isinstance(self.min_length, int) else ''
r += linesep + ' Mandatory in: ' + list_to_string(self.mandatory_in) if self.mandatory_in else ''
r += linesep + ' Optional in: ' + list_to_string(self.optional_in) if self.optional_in else ''
return 'Attribute type' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class LdapSyntaxInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.5)
"""
def __init__(self,
oid=None,
description=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=None,
description=description,
obsolete=False,
extensions=extensions,
experimental=experimental,
definition=definition)
def __repr__(self):
return 'LDAP syntax' + BaseObjectInfo.__repr__(self).replace('<__desc__>', '')
class DitContentRuleInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.6)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
auxiliary_classes=None,
must_contain=None,
may_contain=None,
not_contains=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.auxiliary_classes = auxiliary_classes
self.must_contain = must_contain
self.may_contain = may_contain
self.not_contains = not_contains
def __repr__(self):
r = (linesep + ' Auxiliary classes: ' + list_to_string(self.auxiliary_classes)) if self.auxiliary_classes else ''
r += (linesep + ' Must contain: ' + list_to_string(self.must_contain)) if self.must_contain else ''
r += (linesep + ' May contain: ' + list_to_string(self.may_contain)) if self.may_contain else ''
r += (linesep + ' Not contains: ' + list_to_string(self.not_contains)) if self.not_contains else ''
return 'DIT content rule' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class DitStructureRuleInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.7.1)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
name_form=None,
superior=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.superior = superior
self.name_form = name_form
def __repr__(self):
r = (linesep + ' Superior rules: ' + list_to_string(self.superior)) if self.superior else ''
r += (linesep + ' Name form: ' + list_to_string(self.name_form)) if self.name_form else ''
return 'DIT content rule' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)
class NameFormInfo(BaseObjectInfo):
"""
As per RFC 4512 (4.1.7.2)
"""
def __init__(self,
oid=None,
name=None,
description=None,
obsolete=False,
object_class=None,
must_contain=None,
may_contain=None,
extensions=None,
experimental=None,
definition=None):
BaseObjectInfo.__init__(self,
oid=oid,
name=name,
description=description,
obsolete=obsolete,
extensions=extensions,
experimental=experimental,
definition=definition)
self.object_class = object_class
self.must_contain = must_contain
self.may_contain = may_contain
def __repr__(self):
r = (linesep + ' Object class: ' + list_to_string(self.object_class)) if self.object_class else ''
r += (linesep + ' Must contain: ' + list_to_string(self.must_contain)) if self.must_contain else ''
r += (linesep + ' May contain: ' + list_to_string(self.may_contain)) if self.may_contain else ''
return 'DIT content rule' + BaseObjectInfo.__repr__(self).replace('<__desc__>', r)

View File

@@ -0,0 +1,57 @@
"""
"""
# Created on 2016.12.23
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from .. import NO_ATTRIBUTES, ALL_ATTRIBUTES, STRING_TYPES
from ..operation.search import build_attribute_selection
from .controls import build_control
def _read_control(oid, attributes, criticality=False):
if not attributes:
attributes = [NO_ATTRIBUTES]
elif attributes == ALL_ATTRIBUTES:
attributes = [ALL_ATTRIBUTES]
if isinstance(attributes, STRING_TYPES):
attributes = [attributes]
value = build_attribute_selection(attributes, None)
return build_control(oid, criticality, value)
def pre_read_control(attributes, criticality=False):
"""Create a pre-read control for a request.
When passed as a control to the controls parameter of an operation, it will
return the value in `Connection.result` before the operation took place.
"""
return _read_control('1.3.6.1.1.13.1', attributes, criticality)
def post_read_control(attributes, criticality=False):
"""Create a post-read control for a request.
When passed as a control to the controls parameter of an operation, it will
return the value in `Connection.result` after the operation took place.
"""
return _read_control('1.3.6.1.1.13.2', attributes, criticality)

View File

@@ -0,0 +1,159 @@
"""
"""
# Created on 2014.01.04
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify
import hashlib
import hmac
from ... import SEQUENCE_TYPES
from ...protocol.sasl.sasl import abort_sasl_negotiation, send_sasl_negotiation, random_hex_string
STATE_KEY = 0
STATE_VALUE = 1
def md5_h(value):
if not isinstance(value, bytes):
value = value.encode()
return hashlib.md5(value).digest()
def md5_kd(k, s):
if not isinstance(k, bytes):
k = k.encode()
if not isinstance(s, bytes):
s = s.encode()
return md5_h(k + b':' + s)
def md5_hex(value):
if not isinstance(value, bytes):
value = value.encode()
return hexlify(value)
def md5_hmac(k, s):
if not isinstance(k, bytes):
k = k.encode()
if not isinstance(s, bytes):
s = s.encode()
return hmac.new(k, s, digestmod=hashlib.md5).hexdigest()
def sasl_digest_md5(connection, controls):
# sasl_credential must be a tuple made up of the following elements: (realm, user, password, authorization_id) or (realm, user, password, authorization_id, enable_signing)
# if realm is None will be used the realm received from the server, if available
if not isinstance(connection.sasl_credentials, SEQUENCE_TYPES) or not len(connection.sasl_credentials) in (4, 5):
return None
# step One of RFC2831
result = send_sasl_negotiation(connection, controls, None)
if 'saslCreds' in result and result['saslCreds'] is not None:
server_directives = decode_directives(result['saslCreds'])
else:
return None
if 'realm' not in server_directives or 'nonce' not in server_directives or 'algorithm' not in server_directives: # mandatory directives, as per RFC2831
abort_sasl_negotiation(connection, controls)
return None
# step Two of RFC2831
charset = server_directives['charset'] if 'charset' in server_directives and server_directives['charset'].lower() == 'utf-8' else 'iso8859-1'
user = connection.sasl_credentials[1].encode(charset)
realm = (connection.sasl_credentials[0] if connection.sasl_credentials[0] else (server_directives['realm'] if 'realm' in server_directives else '')).encode(charset)
password = connection.sasl_credentials[2].encode(charset)
authz_id = connection.sasl_credentials[3].encode(charset) if connection.sasl_credentials[3] else b''
nonce = server_directives['nonce'].encode(charset)
cnonce = random_hex_string(16).encode(charset)
uri = b'ldap/' + connection.server.host.encode(charset)
qop = b'auth'
if len(connection.sasl_credentials) == 5 and connection.sasl_credentials[4] == 'sign' and not connection.server.ssl:
qop = b'auth-int'
connection._digest_md5_sec_num = 0
digest_response = b'username="' + user + b'",'
digest_response += b'realm="' + realm + b'",'
digest_response += (b'authzid="' + authz_id + b'",') if authz_id else b''
digest_response += b'nonce="' + nonce + b'",'
digest_response += b'cnonce="' + cnonce + b'",'
digest_response += b'digest-uri="' + uri + b'",'
digest_response += b'qop=' + qop + b','
digest_response += b'nc=00000001' + b','
if charset == 'utf-8':
digest_response += b'charset="utf-8",'
a0 = md5_h(b':'.join([user, realm, password]))
a1 = b':'.join([a0, nonce, cnonce, authz_id]) if authz_id else b':'.join([a0, nonce, cnonce])
a2 = b'AUTHENTICATE:' + uri + (b':00000000000000000000000000000000' if qop in [b'auth-int', b'auth-conf'] else b'')
if qop == b'auth-int':
connection._digest_md5_kis = md5_h(md5_h(a1) + b"Digest session key to server-to-client signing key magic constant")
connection._digest_md5_kic = md5_h(md5_h(a1) + b"Digest session key to client-to-server signing key magic constant")
digest_response += b'response="' + md5_hex(md5_kd(md5_hex(md5_h(a1)), b':'.join([nonce, b'00000001', cnonce, qop, md5_hex(md5_h(a2))]))) + b'"'
result = send_sasl_negotiation(connection, controls, digest_response)
return result
def decode_directives(directives_string):
"""
converts directives to dict, unquote values
"""
# old_directives = dict((attr[0], attr[1].strip('"')) for attr in [line.split('=') for line in directives_string.split(',')])
state = STATE_KEY
tmp_buffer = ''
quoting = False
key = ''
directives = dict()
for c in directives_string.decode('utf-8'):
if state == STATE_KEY and c == '=':
key = tmp_buffer
tmp_buffer = ''
state = STATE_VALUE
elif state == STATE_VALUE and c == '"' and not quoting and not tmp_buffer:
quoting = True
elif state == STATE_VALUE and c == '"' and quoting:
quoting = False
elif state == STATE_VALUE and c == ',' and not quoting:
directives[key] = tmp_buffer
tmp_buffer = ''
key = ''
state = STATE_KEY
else:
tmp_buffer += c
if key and tmp_buffer:
directives[key] = tmp_buffer
return directives

View File

@@ -0,0 +1,32 @@
"""
"""
# Created on 2014.01.04
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from ...protocol.sasl.sasl import send_sasl_negotiation
def sasl_external(connection, controls):
result = send_sasl_negotiation(connection, controls, connection.sasl_credentials)
return result

View File

@@ -0,0 +1,302 @@
"""
"""
# Created on 2015.04.08
#
# Author: Giovanni Cannata
#
# Copyright 2015 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
# original code by Hugh Cole-Baker, modified by Peter Foley, modified again by Azaria Zornberg
# it needs the gssapi package
import base64
import socket
from ...core.exceptions import LDAPPackageUnavailableError, LDAPCommunicationError
from ...core.rdns import ReverseDnsSetting, get_hostname_by_addr, is_ip_addr
posix_gssapi_unavailable = True
try:
# noinspection PyPackageRequirements,PyUnresolvedReferences
import gssapi
from gssapi.raw import ChannelBindings
posix_gssapi_unavailable = False
except ImportError:
pass
windows_gssapi_unavailable = True
# only attempt to import winkerberos if gssapi is unavailable
if posix_gssapi_unavailable:
try:
import winkerberos
windows_gssapi_unavailable = False
except ImportError:
raise LDAPPackageUnavailableError('package gssapi (or winkerberos) missing')
from .sasl import send_sasl_negotiation, abort_sasl_negotiation
NO_SECURITY_LAYER = 1
INTEGRITY_PROTECTION = 2
CONFIDENTIALITY_PROTECTION = 4
def get_channel_bindings(ssl_socket):
try:
server_certificate = ssl_socket.getpeercert(True)
except:
# it is not SSL socket
return None
try:
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
except ImportError:
raise LDAPPackageUnavailableError('package cryptography missing')
cert = x509.load_der_x509_certificate(server_certificate, default_backend())
hash_algorithm = cert.signature_hash_algorithm
# According to https://tools.ietf.org/html/rfc5929#section-4.1, we have to convert the the hash function for md5 and sha1
if hash_algorithm.name in ('md5', 'sha1'):
digest = hashes.Hash(hashes.SHA256(), default_backend())
else:
digest = hashes.Hash(hash_algorithm, default_backend())
digest.update(server_certificate)
application_data = b'tls-server-end-point:' + digest.finalize()
# posix gssapi and windows winkerberos use different channel bindings classes
if not posix_gssapi_unavailable:
return ChannelBindings(application_data=application_data)
else:
return winkerberos.channelBindings(application_data=application_data)
def sasl_gssapi(connection, controls):
"""
Performs a bind using the Kerberos v5 ("GSSAPI") SASL mechanism
from RFC 4752. Does not support any security layers, only authentication!
sasl_credentials can be empty or a tuple with one or two elements.
The first element determines which service principal to request a ticket for and can be one of the following:
- None or False, to use the hostname from the Server object
- True to perform a reverse DNS lookup to retrieve the canonical hostname for the hosts IP address
- A string containing the hostname
The optional second element is what authorization ID to request.
- If omitted or None, the authentication ID is used as the authorization ID
- If a string, the authorization ID to use. Should start with "dn:" or "user:".
The optional third element is a raw gssapi credentials structure which can be used over
the implicit use of a krb ccache.
"""
if not posix_gssapi_unavailable:
return _posix_sasl_gssapi(connection, controls)
else:
return _windows_sasl_gssapi(connection, controls)
def _common_determine_target_name(connection):
""" Common logic for determining our target name for kerberos negotiation, regardless of whether we are using
gssapi on a posix system or winkerberos on windows.
Returns a string in the form "ldap@" + a target hostname.
The hostname can either be user specified, come from the connection, or resolved using reverse DNS based
on parameters set in sasl_credentials.
The default if no sasl_credentials are specified is to use the host in the connection server object.
"""
# if we don't have any sasl_credentials specified, or the first entry is False (which is the legacy equivalent
# to ReverseDnsSetting.OFF that has value 0) then our gssapi name is just
if (not connection.sasl_credentials or len(connection.sasl_credentials) == 0
or not connection.sasl_credentials[0]):
return 'ldap@' + connection.server.host
# older code will still be using a boolean True for the equivalent of
# ReverseDnsSetting.REQUIRE_RESOLVE_ALL_ADDRESSES
if connection.sasl_credentials[0] is True:
hostname = get_hostname_by_addr(connection.socket.getpeername()[0])
target_name = 'ldap@' + hostname
elif connection.sasl_credentials[0] in ReverseDnsSetting.SUPPORTED_VALUES:
rdns_setting = connection.sasl_credentials[0]
# if the rdns_setting is OFF then we won't enter any branch here and will leave hostname as server host,
# so we'll just use the server host, whatever it is
peer_ip = connection.socket.getpeername()[0]
hostname = connection.server.host
if rdns_setting == ReverseDnsSetting.REQUIRE_RESOLVE_ALL_ADDRESSES:
# resolve our peer ip and use it as our target name
hostname = get_hostname_by_addr(peer_ip)
elif rdns_setting == ReverseDnsSetting.REQUIRE_RESOLVE_IP_ADDRESSES_ONLY:
# resolve our peer ip (if the server host is an ip address) and use it as our target name
if is_ip_addr(hostname):
hostname = get_hostname_by_addr(peer_ip)
elif rdns_setting == ReverseDnsSetting.OPTIONAL_RESOLVE_ALL_ADDRESSES:
# try to resolve our peer ip in dns and if we can, use it as our target name.
# if not, just use the server host
resolved_hostname = get_hostname_by_addr(peer_ip, success_required=False)
if resolved_hostname is not None:
hostname = resolved_hostname
elif rdns_setting == ReverseDnsSetting.OPTIONAL_RESOLVE_IP_ADDRESSES_ONLY:
# try to resolve our peer ip in dns if our server host is an ip. if we can, use it as our target
# name. if not, just use the server host
if is_ip_addr(hostname):
resolved_hostname = get_hostname_by_addr(peer_ip, success_required=False)
if resolved_hostname is not None:
hostname = resolved_hostname
# construct our target name
target_name = 'ldap@' + hostname
else: # string hostname directly provided
target_name = 'ldap@' + connection.sasl_credentials[0]
return target_name
def _common_determine_authz_id_and_creds(connection):
""" Given our connection, figure out the authorization id (i.e. the kerberos principal) and kerberos credentials
being used for our SASL bind.
On posix systems, we can actively negotiate with raw credentials and receive a kerberos client ticket during our
SASL bind. So credentials can be specified.
However, on windows systems, winkerberos expects to use the credentials cached by the system because windows
machines are generally domain-joined. So no initiation is supported, as the TGT must already be valid prior
to beginning the SASL bind, and the windows system credentials will be used as needed with that.
"""
authz_id = b""
creds = None
# the default value for credentials is only something we should instantiate on systems using the
# posix GSSAPI, as windows kerberos expects that a tgt already exists (i.e. the machine is domain-joined)
# and does not support initiation from raw credentials
if not posix_gssapi_unavailable:
creds = gssapi.Credentials(name=gssapi.Name(connection.user), usage='initiate', store=connection.cred_store) if connection.user else None
if connection.sasl_credentials:
if len(connection.sasl_credentials) >= 2 and connection.sasl_credentials[1]:
authz_id = connection.sasl_credentials[1].encode("utf-8")
if len(connection.sasl_credentials) >= 3 and connection.sasl_credentials[2]:
if posix_gssapi_unavailable:
raise LDAPPackageUnavailableError('The winkerberos package does not support specifying raw credentials'
'to initiate GSSAPI Kerberos communication. A ticket granting ticket '
'must have already been obtained for the user before beginning a '
'SASL bind.')
raw_creds = connection.sasl_credentials[2]
creds = gssapi.Credentials(base=raw_creds, usage='initiate', store=connection.cred_store)
return authz_id, creds
def _common_process_end_token_get_security_layers(negotiated_token):
""" Process the response we got at the end of our SASL negotiation wherein the server told us what
minimum security layers we need, and return a bytearray for the client security layers we want.
This function throws an error on a malformed token from the server.
The ldap3 library does not support security layers, and only supports authentication with kerberos,
so an error will be thrown for any tokens that indicate a security layer requirement.
"""
if len(negotiated_token) != 4:
raise LDAPCommunicationError("Incorrect response from server")
server_security_layers = negotiated_token[0]
if not isinstance(server_security_layers, int):
server_security_layers = ord(server_security_layers)
if server_security_layers in (0, NO_SECURITY_LAYER):
if negotiated_token[1:] != '\x00\x00\x00':
raise LDAPCommunicationError("Server max buffer size must be 0 if no security layer")
if not (server_security_layers & NO_SECURITY_LAYER):
raise LDAPCommunicationError("Server requires a security layer, but this is not implemented")
# this is here to encourage anyone implementing client security layers to do it
# for both windows and posix
client_security_layers = bytearray([NO_SECURITY_LAYER, 0, 0, 0])
return client_security_layers
def _posix_sasl_gssapi(connection, controls):
""" Performs a bind using the Kerberos v5 ("GSSAPI") SASL mechanism
from RFC 4752 using the gssapi package that works natively on most
posix operating systems.
"""
target_name = gssapi.Name(_common_determine_target_name(connection), gssapi.NameType.hostbased_service)
authz_id, creds = _common_determine_authz_id_and_creds(connection)
ctx = gssapi.SecurityContext(name=target_name, mech=gssapi.MechType.kerberos, creds=creds,
channel_bindings=get_channel_bindings(connection.socket))
in_token = None
try:
while True:
out_token = ctx.step(in_token)
if out_token is None:
out_token = ''
result = send_sasl_negotiation(connection, controls, out_token)
in_token = result['saslCreds']
try:
# This raised an exception in gssapi<1.1.2 if the context was
# incomplete, but was fixed in
# https://github.com/pythongssapi/python-gssapi/pull/70
if ctx.complete:
break
except gssapi.exceptions.MissingContextError:
pass
unwrapped_token = ctx.unwrap(in_token)
client_security_layers = _common_process_end_token_get_security_layers(unwrapped_token.message)
out_token = ctx.wrap(bytes(client_security_layers)+authz_id, False)
return send_sasl_negotiation(connection, controls, out_token.message)
except (gssapi.exceptions.GSSError, LDAPCommunicationError):
abort_sasl_negotiation(connection, controls)
raise
def _windows_sasl_gssapi(connection, controls):
""" Performs a bind using the Kerberos v5 ("GSSAPI") SASL mechanism
from RFC 4752 using the winkerberos package that works natively on most
windows operating systems.
"""
target_name = _common_determine_target_name(connection)
# initiation happens before beginning the SASL bind when using windows kerberos
authz_id, _ = _common_determine_authz_id_and_creds(connection)
gssflags = (
winkerberos.GSS_C_MUTUAL_FLAG |
winkerberos.GSS_C_SEQUENCE_FLAG |
winkerberos.GSS_C_INTEG_FLAG |
winkerberos.GSS_C_CONF_FLAG
)
_, ctx = winkerberos.authGSSClientInit(target_name, gssflags=gssflags)
in_token = b''
try:
negotiation_complete = False
while not negotiation_complete:
# GSSAPI is a "client goes first" SASL mechanism. Send the first "response" to the server and
# recieve its first challenge.
# Despite this, we can get channel binding, which includes CBTs for windows environments computed from
# the peer certificate, before starting.
status = winkerberos.authGSSClientStep(ctx, base64.b64encode(in_token).decode('utf-8'),
channel_bindings=get_channel_bindings(connection.socket))
# figure out if we're done with our sasl negotiation
negotiation_complete = (status == winkerberos.AUTH_GSS_COMPLETE)
out_token = winkerberos.authGSSClientResponse(ctx) or ''
out_token_bytes = base64.b64decode(out_token)
result = send_sasl_negotiation(connection, controls, out_token_bytes)
in_token = result['saslCreds'] or b''
winkerberos.authGSSClientUnwrap( ctx,base64.b64encode(in_token).decode('utf-8'))
negotiated_token = ''
if winkerberos.authGSSClientResponse(ctx):
negotiated_token = base64.standard_b64decode(winkerberos.authGSSClientResponse(ctx))
client_security_layers = _common_process_end_token_get_security_layers(negotiated_token)
# manually construct a message indicating use of authorization-only layer
# see winkerberos example: https://github.com/mongodb/winkerberos/blob/master/test/test_winkerberos.py
authz_only_msg = base64.b64encode(bytes(client_security_layers) + authz_id).decode('utf-8')
winkerberos.authGSSClientWrap(ctx, authz_only_msg)
out_token = winkerberos.authGSSClientResponse(ctx) or ''
return send_sasl_negotiation(connection, controls, base64.b64decode(out_token))
except (winkerberos.GSSError, LDAPCommunicationError):
abort_sasl_negotiation(connection, controls)
raise

View File

@@ -0,0 +1,70 @@
"""
"""
# Created on 2014.01.04
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
# payload for PLAIN mechanism
# message = [authzid] UTF8NUL authcid UTF8NUL passwd
# authcid = 1*SAFE ; MUST accept up to 255 octets
# authzid = 1*SAFE ; MUST accept up to 255 octets
# passwd = 1*SAFE ; MUST accept up to 255 octets
# UTF8NUL = %x00 ; UTF-8 encoded NUL character
#
# SAFE = UTF1 / UTF2 / UTF3 / UTF4
# ;; any UTF-8 encoded Unicode character except NUL
#
# UTF1 = %x01-7F ;; except NUL
# UTF2 = %xC2-DF UTF0
# UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
# %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
# UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
# %xF4 %x80-8F 2(UTF0)
# UTF0 = %x80-BF
from ...protocol.sasl.sasl import send_sasl_negotiation
from .sasl import sasl_prep
from ...utils.conv import to_raw, to_unicode
def sasl_plain(connection, controls):
authzid = connection.sasl_credentials[0]
authcid = connection.sasl_credentials[1]
passwd = connection.sasl_credentials[2]
payload = b''
if authzid:
payload += to_raw(sasl_prep(to_unicode(authzid)))
payload += b'\0'
if authcid:
payload += to_raw(sasl_prep(to_unicode(authcid)))
payload += b'\0'
if passwd:
payload += to_raw(sasl_prep(to_unicode(passwd)))
result = send_sasl_negotiation(connection, controls, payload)
return result

View File

@@ -0,0 +1,171 @@
"""
"""
# Created on 2013.09.11
#
# Author: Giovanni Cannata
#
# Copyright 2013 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
import stringprep
from unicodedata import ucd_3_2_0 as unicode32
from os import urandom
from binascii import hexlify
from ... import SASL
from ...core.results import RESULT_AUTH_METHOD_NOT_SUPPORTED
from ...core.exceptions import LDAPSASLPrepError, LDAPPasswordIsMandatoryError
def sasl_prep(data):
"""
implement SASLPrep profile as per RFC4013:
it defines the "SASLprep" profile of the "stringprep" algorithm [StringPrep].
The profile is designed for use in Simple Authentication and Security
Layer ([SASL]) mechanisms, such as [PLAIN], [CRAM-MD5], and
[DIGEST-MD5]. It may be applicable where simple user names and
passwords are used. This profile is not intended for use in
preparing identity strings that are not simple user names (e.g.,
email addresses, domain names, distinguished names), or where
identity or password strings that are not character data, or require
different handling (e.g., case folding).
"""
# mapping
prepared_data = ''
for c in data:
if stringprep.in_table_c12(c):
# non-ASCII space characters [StringPrep, C.1.2] that can be mapped to SPACE (U+0020)
prepared_data += ' '
elif stringprep.in_table_b1(c):
# the "commonly mapped to nothing" characters [StringPrep, B.1] that can be mapped to nothing.
pass
else:
prepared_data += c
# normalizing
# This profile specifies using Unicode normalization form KC
# The repertoire is Unicode 3.2 as per RFC 4013 (2)
prepared_data = unicode32.normalize('NFKC', prepared_data)
if not prepared_data:
raise LDAPSASLPrepError('SASLprep error: unable to normalize string')
# prohibit
for c in prepared_data:
if stringprep.in_table_c12(c):
# Non-ASCII space characters [StringPrep, C.1.2]
raise LDAPSASLPrepError('SASLprep error: non-ASCII space character present')
elif stringprep.in_table_c21(c):
# ASCII control characters [StringPrep, C.2.1]
raise LDAPSASLPrepError('SASLprep error: ASCII control character present')
elif stringprep.in_table_c22(c):
# Non-ASCII control characters [StringPrep, C.2.2]
raise LDAPSASLPrepError('SASLprep error: non-ASCII control character present')
elif stringprep.in_table_c3(c):
# Private Use characters [StringPrep, C.3]
raise LDAPSASLPrepError('SASLprep error: private character present')
elif stringprep.in_table_c4(c):
# Non-character code points [StringPrep, C.4]
raise LDAPSASLPrepError('SASLprep error: non-character code point present')
elif stringprep.in_table_c5(c):
# Surrogate code points [StringPrep, C.5]
raise LDAPSASLPrepError('SASLprep error: surrogate code point present')
elif stringprep.in_table_c6(c):
# Inappropriate for plain text characters [StringPrep, C.6]
raise LDAPSASLPrepError('SASLprep error: inappropriate for plain text character present')
elif stringprep.in_table_c7(c):
# Inappropriate for canonical representation characters [StringPrep, C.7]
raise LDAPSASLPrepError('SASLprep error: inappropriate for canonical representation character present')
elif stringprep.in_table_c8(c):
# Change display properties or deprecated characters [StringPrep, C.8]
raise LDAPSASLPrepError('SASLprep error: change display property or deprecated character present')
elif stringprep.in_table_c9(c):
# Tagging characters [StringPrep, C.9]
raise LDAPSASLPrepError('SASLprep error: tagging character present')
# check bidi
# if a string contains any r_and_al_cat character, the string MUST NOT contain any l_cat character.
flag_r_and_al_cat = False
flag_l_cat = False
for c in prepared_data:
if stringprep.in_table_d1(c):
flag_r_and_al_cat = True
elif stringprep.in_table_d2(c):
flag_l_cat = True
if flag_r_and_al_cat and flag_l_cat:
raise LDAPSASLPrepError('SASLprep error: string cannot contain (R or AL) and L bidirectional chars')
# If a string contains any r_and_al_cat character, a r_and_al_cat character MUST be the first character of the string
# and a r_and_al_cat character MUST be the last character of the string.
if flag_r_and_al_cat and not stringprep.in_table_d1(prepared_data[0]) and not stringprep.in_table_d2(prepared_data[-1]):
raise LDAPSASLPrepError('r_and_al_cat character present, must be first and last character of the string')
return prepared_data
def validate_simple_password(password, accept_empty=False):
"""
validate simple password as per RFC4013 using sasl_prep:
"""
if accept_empty and not password:
return password
elif not password:
raise LDAPPasswordIsMandatoryError("simple password can't be empty")
if not isinstance(password, bytes): # bytes are returned raw, as per RFC (4.2)
password = sasl_prep(password)
if not isinstance(password, bytes):
password = password.encode('utf-8')
return password
def abort_sasl_negotiation(connection, controls):
from ...operation.bind import bind_operation
request = bind_operation(connection.version, SASL, None, None, '', None)
response = connection.post_send_single_response(connection.send('bindRequest', request, controls))
if connection.strategy.sync:
result = connection.result
else:
result = connection.get_response(response)[0][0]
return True if result['result'] == RESULT_AUTH_METHOD_NOT_SUPPORTED else False
def send_sasl_negotiation(connection, controls, payload):
from ...operation.bind import bind_operation
request = bind_operation(connection.version, SASL, None, None, connection.sasl_mechanism, payload)
response = connection.post_send_single_response(connection.send('bindRequest', request, controls))
if connection.strategy.sync:
result = connection.result
else:
_, result = connection.get_response(response)
return result
def random_hex_string(size):
return str(hexlify(urandom(size)).decode('ascii')) # str fix for Python 2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,758 @@
"""
"""
# Created on 2014.10.21
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2020 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
slapd_2_4_schema = """
{
"raw": {
"attributeTypes": [
"( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
"( 2.5.21.9 NAME 'structuralObjectClass' DESC 'RFC4512: structural object class of entry' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.1 NAME 'createTimestamp' DESC 'RFC4512: time which object was created' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.2 NAME 'modifyTimestamp' DESC 'RFC4512: time which object was last modified' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.3 NAME 'creatorsName' DESC 'RFC4512: name of creator' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.4 NAME 'modifiersName' DESC 'RFC4512: name of last modifier' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.9 NAME 'hasSubordinates' DESC 'X.501: entry has children' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 2.5.18.10 NAME 'subschemaSubentry' DESC 'RFC4512: name of controlling subschema entry' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.1.20 NAME 'entryDN' DESC 'DN of the entry' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.1.16.4 NAME 'entryUUID' DESC 'UUID of the entry' EQUALITY UUIDMatch ORDERING UUIDOrderingMatch SYNTAX 1.3.6.1.1.16.1 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' DESC 'RFC4512: alternative servers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' DESC 'RFC4512: naming contexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl' DESC 'RFC4512: supported controls' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension' DESC 'RFC4512: supported extended operations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion' DESC 'RFC4512: supported LDAP versions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms' DESC 'RFC4512: supported SASL mechanisms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )",
"( 1.3.6.1.4.1.4203.1.3.5 NAME 'supportedFeatures' DESC 'RFC4512: features supported by the server' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
"( 1.3.6.1.1.4 NAME 'vendorName' DESC 'RFC3045: name of implementation vendor' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
"( 1.3.6.1.1.5 NAME 'vendorVersion' DESC 'RFC3045: version of implementation' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
"( 2.5.21.4 NAME 'matchingRules' DESC 'RFC4512: matching rules' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )",
"( 2.5.21.5 NAME 'attributeTypes' DESC 'RFC4512: attribute types' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )",
"( 2.5.21.6 NAME 'objectClasses' DESC 'RFC4512: object classes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )",
"( 2.5.21.8 NAME 'matchingRuleUse' DESC 'RFC4512: matching rule uses' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
"( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' DESC 'RFC4512: LDAP syntaxes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )",
"( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' ) DESC 'RFC4512: name of aliased object' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'RFC3296: subordinate referral URL' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )",
"( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' DESC 'RFC2589: entry time-to-live' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
"( 1.3.6.1.4.1.1466.101.119.4 NAME 'dynamicSubtrees' DESC 'RFC2589: dynamic subtrees' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE dSAOperation )",
"( 2.5.4.49 NAME 'distinguishedName' DESC 'RFC4519: common supertype of DN attributes' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )",
"( 2.5.4.3 NAME ( 'cn' 'commonName' ) DESC 'RFC4519: common name(s) for which the entity is known by' SUP name )",
"( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) DESC 'RFC4519: user identifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 1.3.6.1.1.1.1.0 NAME 'uidNumber' DESC 'RFC2307: An integer uniquely identifying a user in an administrative domain' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.1 NAME 'gidNumber' DESC 'RFC2307: An integer uniquely identifying a group in an administrative domain' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 2.5.4.35 NAME 'userPassword' DESC 'RFC4519/2307: password of user' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )",
"( 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 )",
"( 2.5.4.13 NAME 'description' DESC 'RFC4519: descriptive information' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )",
"( 2.5.4.34 NAME 'seeAlso' DESC 'RFC4519: DN of related object' SUP distinguishedName )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.78 NAME 'olcConfigFile' DESC 'File for slapd configuration directives' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.79 NAME 'olcConfigDir' DESC 'Directory for slapd configuration backend' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.1 NAME 'olcAccess' DESC 'Access Control List' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.86 NAME 'olcAddContentAcl' DESC 'Check ACLs against content of Add ops' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.2 NAME 'olcAllows' DESC 'Allowed set of deprecated features' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.3 NAME 'olcArgsFile' DESC 'File for slapd command line options' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.5 NAME 'olcAttributeOptions' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.4 NAME 'olcAttributeTypes' DESC 'OpenLDAP attributeTypes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.6 NAME 'olcAuthIDRewrite' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.7 NAME 'olcAuthzPolicy' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.8 NAME 'olcAuthzRegexp' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.9 NAME 'olcBackend' DESC 'A type of backend' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORDERED 'SIBLINGS' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.10 NAME 'olcConcurrency' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.11 NAME 'olcConnMaxPending' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.12 NAME 'olcConnMaxPendingAuth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.13 NAME 'olcDatabase' DESC 'The backend type for a database instance' SUP olcBackend SINGLE-VALUE X-ORDERED 'SIBLINGS' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.14 NAME 'olcDefaultSearchBase' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.15 NAME 'olcDisallows' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.16 NAME 'olcDitContentRules' DESC 'OpenLDAP DIT content rules' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.20 NAME 'olcExtraAttrs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.17 NAME 'olcGentleHUP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.17 NAME 'olcHidden' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.18 NAME 'olcIdleTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.19 NAME 'olcInclude' SUP labeledURI )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.20 NAME 'olcIndexSubstrIfMinLen' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.21 NAME 'olcIndexSubstrIfMaxLen' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.22 NAME 'olcIndexSubstrAnyLen' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.23 NAME 'olcIndexSubstrAnyStep' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.84 NAME 'olcIndexIntLen' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.4 NAME 'olcLastMod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.85 NAME 'olcLdapSyntaxes' DESC 'OpenLDAP ldapSyntax' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.5 NAME 'olcLimits' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.93 NAME 'olcListenerThreads' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.26 NAME 'olcLocalSSF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.27 NAME 'olcLogFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.28 NAME 'olcLogLevel' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.6 NAME 'olcMaxDerefDepth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.16 NAME 'olcMirrorMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.30 NAME 'olcModuleLoad' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.31 NAME 'olcModulePath' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.18 NAME 'olcMonitoring' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.32 NAME 'olcObjectClasses' DESC 'OpenLDAP object classes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.33 NAME 'olcObjectIdentifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.34 NAME 'olcOverlay' SUP olcDatabase SINGLE-VALUE X-ORDERED 'SIBLINGS' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.35 NAME 'olcPasswordCryptSaltFormat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.36 NAME 'olcPasswordHash' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.37 NAME 'olcPidFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.38 NAME 'olcPlugin' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.39 NAME 'olcPluginLogFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.40 NAME 'olcReadOnly' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.41 NAME 'olcReferral' SUP labeledURI SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.7 NAME 'olcReplica' SUP labeledURI EQUALITY caseIgnoreMatch X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.43 NAME 'olcReplicaArgsFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.44 NAME 'olcReplicaPidFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.45 NAME 'olcReplicationInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.46 NAME 'olcReplogFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.47 NAME 'olcRequires' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.48 NAME 'olcRestrict' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.49 NAME 'olcReverseLookup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.8 NAME 'olcRootDN' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.51 NAME 'olcRootDSE' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.9 NAME 'olcRootPW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.89 NAME 'olcSaslAuxprops' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.53 NAME 'olcSaslHost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.54 NAME 'olcSaslRealm' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.56 NAME 'olcSaslSecProps' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.58 NAME 'olcSchemaDN' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.59 NAME 'olcSecurity' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.81 NAME 'olcServerID' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.60 NAME 'olcSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.61 NAME 'olcSockbufMaxIncoming' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.62 NAME 'olcSockbufMaxIncomingAuth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.83 NAME 'olcSortVals' DESC 'Attributes whose values will always be sorted' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.15 NAME 'olcSubordinate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.10 NAME 'olcSuffix' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.19 NAME 'olcSyncUseSubentry' DESC 'Store sync context in a subentry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.11 NAME 'olcSyncrepl' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.90 NAME 'olcTCPBuffer' DESC 'Custom TCP buffer size' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.66 NAME 'olcThreads' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.67 NAME 'olcTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.68 NAME 'olcTLSCACertificateFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.69 NAME 'olcTLSCACertificatePath' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.70 NAME 'olcTLSCertificateFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.71 NAME 'olcTLSCertificateKeyFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.72 NAME 'olcTLSCipherSuite' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.73 NAME 'olcTLSCRLCheck' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.82 NAME 'olcTLSCRLFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.74 NAME 'olcTLSRandFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.75 NAME 'olcTLSVerifyClient' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.77 NAME 'olcTLSDHParamFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.87 NAME 'olcTLSProtocolMin' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.80 NAME 'olcToolThreads' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.12 NAME 'olcUpdateDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.13 NAME 'olcUpdateRef' SUP labeledURI EQUALITY caseIgnoreMatch )",
"( 1.3.6.1.4.1.4203.1.12.2.3.0.88 NAME 'olcWriteTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.1 NAME 'olcDbDirectory' DESC 'Directory for database content' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.11 NAME 'olcDbCacheFree' DESC 'Number of extra entries to free when max is reached' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.1 NAME 'olcDbCacheSize' DESC 'Entry cache size in entries' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.2 NAME 'olcDbCheckpoint' DESC 'Database checkpoint interval in kbytes and minutes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.16 NAME 'olcDbChecksum' DESC 'Enable database checksum validation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.13 NAME 'olcDbCryptFile' DESC 'Pathname of file containing the DB encryption key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.14 NAME 'olcDbCryptKey' DESC 'DB encryption key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.3 NAME 'olcDbConfig' DESC 'BerkeleyDB DB_CONFIG configuration directives' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.4 NAME 'olcDbNoSync' DESC 'Disable synchronous database writes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.15 NAME 'olcDbPageSize' DESC 'Page size of specified DB, in Kbytes' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.5 NAME 'olcDbDirtyRead' DESC 'Allow reads of uncommitted data' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.12 NAME 'olcDbDNcacheSize' DESC 'DN cache size' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.6 NAME 'olcDbIDLcacheSize' DESC 'IDL cache size in IDLs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.2 NAME 'olcDbIndex' DESC 'Attribute index parameters' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.7 NAME 'olcDbLinearIndex' DESC 'Index attributes one at a time' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.8 NAME 'olcDbLockDetect' DESC 'Deadlock detection algorithm' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.3 NAME 'olcDbMode' DESC 'Unix permissions of database files' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.9 NAME 'olcDbSearchStack' DESC 'Depth of search stack in IDLs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.1.10 NAME 'olcDbShmKey' DESC 'Key for shared memory region' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.0.14 NAME 'olcDbURI' DESC 'URI (list) for remote DSA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.1 NAME 'olcDbStartTLS' DESC 'StartTLS' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.2 NAME 'olcDbACLAuthcDn' DESC 'Remote ACL administrative identity' OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.3 NAME 'olcDbACLPasswd' DESC 'Remote ACL administrative identity credentials' OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.4 NAME 'olcDbACLBind' DESC 'Remote ACL administrative identity auth bind configuration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.5 NAME 'olcDbIDAssertAuthcDn' DESC 'Remote Identity Assertion administrative identity' OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.6 NAME 'olcDbIDAssertPasswd' DESC 'Remote Identity Assertion administrative identity credentials' OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.7 NAME 'olcDbIDAssertBind' DESC 'Remote Identity Assertion administrative identity auth bind configuration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.8 NAME 'olcDbIDAssertMode' DESC 'Remote Identity Assertion mode' OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.9 NAME 'olcDbIDAssertAuthzFrom' DESC 'Remote Identity Assertion authz rules' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.10 NAME 'olcDbRebindAsUser' DESC 'Rebind as user' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.11 NAME 'olcDbChaseReferrals' DESC 'Chase referrals' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.12 NAME 'olcDbTFSupport' DESC 'Absolute filters support' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.13 NAME 'olcDbProxyWhoAmI' DESC 'Proxy whoAmI exop' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.14 NAME 'olcDbTimeout' DESC 'Per-operation timeouts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.15 NAME 'olcDbIdleTimeout' DESC 'connection idle timeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.16 NAME 'olcDbConnTtl' DESC 'connection ttl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.17 NAME 'olcDbNetworkTimeout' DESC 'connection network timeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.18 NAME 'olcDbProtocolVersion' DESC 'protocol version' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.19 NAME 'olcDbSingleConn' DESC 'cache a single connection per identity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.20 NAME 'olcDbCancel' DESC 'abandon/ignore/exop operations when appropriate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.21 NAME 'olcDbQuarantine' DESC 'Quarantine database if connection fails and retry according to rule' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.22 NAME 'olcDbUseTemporaryConn' DESC 'Use temporary connections if the cached one is busy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.23 NAME 'olcDbConnectionPoolMax' DESC 'Max size of privileged connections pool' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.25 NAME 'olcDbNoRefs' DESC 'Do not return search reference responses' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.26 NAME 'olcDbNoUndefFilter' DESC 'Do not propagate undefined search filters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.3.27 NAME 'olcDbIDAssertPassThru' DESC 'Remote Identity Assertion passthru rules' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.3.1 NAME 'olcChainingBehavior' DESC 'Chaining behavior control parameters (draft-sermersheim-ldap-chaining)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.3.2 NAME 'olcChainCacheURI' DESC 'Enables caching of URIs not present in configuration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.3.3 NAME 'olcChainMaxReferralDepth' DESC 'max referral depth' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.3.4 NAME 'olcChainReturnError' DESC 'Errors are returned instead of the original referral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.2.5.1 NAME 'olcRelay' DESC 'Relay DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.1 NAME 'olcAccessLogDB' DESC 'Suffix of database for log content' SUP distinguishedName SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.2 NAME 'olcAccessLogOps' DESC 'Operation types to log' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.3 NAME 'olcAccessLogPurge' DESC 'Log cleanup parameters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.4 NAME 'olcAccessLogSuccess' DESC 'Log successful ops only' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.5 NAME 'olcAccessLogOld' DESC 'Log old values when modifying entries matching the filter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.6 NAME 'olcAccessLogOldAttr' DESC 'Log old values of these attributes even if unmodified' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.4.7 NAME 'olcAccessLogBase' DESC 'Operation types to log under a specific branch' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.15.1 NAME 'olcAuditlogFile' DESC 'Filename for auditlogging' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.19.1 NAME 'olcCollectInfo' DESC 'DN of entry and attribute to distribute' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.13.1 NAME 'olcConstraintAttribute' DESC 'constraint for list of attributes' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.1 NAME 'olcDDSstate' DESC 'RFC2589 Dynamic directory services state' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.2 NAME 'olcDDSmaxTtl' DESC 'RFC2589 Dynamic directory services max TTL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.3 NAME 'olcDDSminTtl' DESC 'RFC2589 Dynamic directory services min TTL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.4 NAME 'olcDDSdefaultTtl' DESC 'RFC2589 Dynamic directory services default TTL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.5 NAME 'olcDDSinterval' DESC 'RFC2589 Dynamic directory services expiration task run interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.6 NAME 'olcDDStolerance' DESC 'RFC2589 Dynamic directory services additional TTL in expiration scheduling' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.9.7 NAME 'olcDDSmaxDynamicObjects' DESC 'RFC2589 Dynamic directory services max number of dynamic objects' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.17.1 NAME 'olcDGAttrPair' DESC 'Member and MemberURL attribute pair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.8.1 NAME 'olcDlAttrSet' DESC 'Dynamic list: <group objectClass>, <URL attributeDescription>, <member attributeDescription>' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.2.840.113556.1.2.102 NAME 'memberOf' DESC 'Group that the entry belongs to' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'iPlanet Delegated Administrator' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.0 NAME 'olcMemberOfDN' DESC 'DN to be used as modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.1 NAME 'olcMemberOfDangling' DESC 'Behavior with respect to dangling members, constrained to ignore, drop, error' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.2 NAME 'olcMemberOfRefInt' DESC 'Take care of referential integrity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.3 NAME 'olcMemberOfGroupOC' DESC 'Group objectClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.4 NAME 'olcMemberOfMemberAD' DESC 'member attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.5 NAME 'olcMemberOfMemberOfAD' DESC 'memberOf attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.18.7 NAME 'olcMemberOfDanglingError' DESC 'Error code returned in case of dangling back reference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.42.2.27.8.1.16 NAME 'pwdChangedTime' DESC 'The time the password was last changed' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.17 NAME 'pwdAccountLockedTime' DESC 'The time an user account was locked' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.19 NAME 'pwdFailureTime' DESC 'The timestamps of the last consecutive authentication failures' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.20 NAME 'pwdHistory' DESC 'The history of users passwords' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.21 NAME 'pwdGraceUseTime' DESC 'The timestamps of the grace login once the password has expired' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 NO-USER-MODIFICATION USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.22 NAME 'pwdReset' DESC 'The indication that the password has been reset' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE USAGE directoryOperation )",
"( 1.3.6.1.4.1.42.2.27.8.1.23 NAME 'pwdPolicySubentry' DESC 'The pwdPolicy subentry in effect for this object' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.12.1 NAME 'olcPPolicyDefault' DESC 'DN of a pwdPolicy object for uncustomized objects' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.12.2 NAME 'olcPPolicyHashCleartext' DESC 'Hash passwords on add or modify' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.12.4 NAME 'olcPPolicyForwardUpdates' DESC 'Allow policy state updates to be forwarded via updateref' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.12.3 NAME 'olcPPolicyUseLockout' DESC 'Warn clients with AccountLocked' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.1 NAME ( 'olcPcache' 'olcProxyCache' ) DESC 'Proxy Cache basic parameters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.2 NAME ( 'olcPcacheAttrset' 'olcProxyAttrset' ) DESC 'A set of attributes to cache' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.3 NAME ( 'olcPcacheTemplate' 'olcProxyCacheTemplate' ) DESC 'Filter template, attrset, cache TTL, optional negative TTL, optional sizelimit TTL, optional TTR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.4 NAME 'olcPcachePosition' DESC 'Response callback position in overlay stack' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.5 NAME ( 'olcPcacheMaxQueries' 'olcProxyCacheQueries' ) DESC 'Maximum number of queries to cache' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.6 NAME ( 'olcPcachePersist' 'olcProxySaveQueries' ) DESC 'Save cached queries for hot restart' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.7 NAME ( 'olcPcacheValidate' 'olcProxyCheckCacheability' ) DESC 'Check whether the results of a query are cacheable, e.g. for schema issues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.8 NAME 'olcPcacheOffline' DESC 'Set cache to offline mode and disable expiration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.2.9 NAME 'olcPcacheBind' DESC 'Parameters for caching Binds' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.11.1 NAME 'olcRefintAttribute' DESC 'Attributes for referential integrity' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.11.2 NAME 'olcRefintNothing' DESC 'Replacement DN to supply when needed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.11.3 NAME 'olcRefintModifiersName' DESC 'The DN to use as modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.20.1 NAME 'olcRetcodeParent' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.20.2 NAME 'olcRetcodeItem' DESC '' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.20.3 NAME 'olcRetcodeInDir' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.20.4 NAME 'olcRetcodeSleep' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.16.1 NAME 'olcRwmRewrite' DESC 'Rewrites strings' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.16.2 NAME 'olcRwmTFSupport' DESC 'Absolute filters support' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.16.3 NAME 'olcRwmMap' DESC 'maps attributes/objectClasses' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORDERED 'VALUES' )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.16.4 NAME 'olcRwmNormalizeMapped' DESC 'Normalize mapped attributes/objectClasses' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.16.5 NAME 'olcRwmDropUnrequested' DESC 'Drop unrequested attributes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.21.1 NAME 'olcSssVlvMax' DESC 'Maximum number of concurrent Sort requests' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.21.2 NAME 'olcSssVlvMaxKeys' DESC 'Maximum number of Keys in a Sort request' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.21.3 NAME 'olcSssVlvMaxPerConn' DESC 'Maximum number of concurrent paged search requests per connection' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.1.1 NAME 'olcSpCheckpoint' DESC 'ContextCSN checkpoint interval in ops and minutes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.1.2 NAME 'olcSpSessionlog' DESC 'Session log size in ops' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.1.3 NAME 'olcSpNoPresent' DESC 'Omit Present phase processing' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.1.4 NAME 'olcSpReloadHint' DESC 'Observe Reload Hint in Request control' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.1 NAME 'olcTranslucentStrict' DESC 'Reveal attribute deletion constraint violations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.2 NAME 'olcTranslucentNoGlue' DESC 'Disable automatic glue records for ADD and MODRDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.3 NAME 'olcTranslucentLocal' DESC 'Attributes to use in local search filter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.4 NAME 'olcTranslucentRemote' DESC 'Attributes to use in remote search filter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.5 NAME 'olcTranslucentBindLocal' DESC 'Enable local bind' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.14.6 NAME 'olcTranslucentPwModLocal' DESC 'Enable local RFC 3062 Password Modify extended operation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.10.1 NAME 'olcUniqueBase' DESC 'Subtree for uniqueness searches' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.10.2 NAME 'olcUniqueIgnore' DESC 'Attributes for which uniqueness shall not be enforced' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.10.3 NAME 'olcUniqueAttribute' DESC 'Attributes for which uniqueness shall be enforced' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.10.4 NAME 'olcUniqueStrict' DESC 'Enforce uniqueness of null values' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.10.5 NAME 'olcUniqueURI' DESC 'List of keywords and LDAP URIs for a uniqueness domain' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.4203.1.12.2.3.3.5.1 NAME 'olcValSortAttr' DESC 'Sorting rule for attribute under given DN' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 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} )",
"( 2.5.4.4 NAME ( 'sn' 'surname' ) DESC 'RFC2256: last (family) name(s) for which the entity is known by' SUP name )",
"( 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} )",
"( 2.5.4.6 NAME ( 'c' 'countryName' ) DESC 'RFC4519: two-letter ISO-3166 country code' SUP name SYNTAX 1.3.6.1.4.1.1466.115.121.1.11 SINGLE-VALUE )",
"( 2.5.4.7 NAME ( 'l' 'localityName' ) DESC 'RFC2256: locality which this object resides in' SUP name )",
"( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) DESC 'RFC2256: state or province which this object resides in' SUP name )",
"( 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} )",
"( 2.5.4.10 NAME ( 'o' 'organizationName' ) DESC 'RFC2256: organization this object belongs to' SUP name )",
"( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) DESC 'RFC2256: organizational unit this object belongs to' SUP name )",
"( 2.5.4.12 NAME 'title' DESC 'RFC2256: title associated with the entity' SUP name )",
"( 2.5.4.14 NAME 'searchGuide' DESC 'RFC2256: search guide, deprecated by enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 )",
"( 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} )",
"( 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 )",
"( 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} )",
"( 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} )",
"( 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} )",
"( 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} )",
"( 2.5.4.21 NAME 'telexNumber' DESC 'RFC2256: Telex Number' SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )",
"( 2.5.4.22 NAME 'teletexTerminalIdentifier' DESC 'RFC2256: Teletex Terminal Identifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )",
"( 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 )",
"( 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} )",
"( 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} )",
"( 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 )",
"( 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} )",
"( 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 )",
"( 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 )",
"( 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 )",
"( 2.5.4.31 NAME 'member' DESC 'RFC2256: member of a group' SUP distinguishedName )",
"( 2.5.4.32 NAME 'owner' DESC 'RFC2256: owner (of the object)' SUP distinguishedName )",
"( 2.5.4.33 NAME 'roleOccupant' DESC 'RFC2256: occupant of role' SUP distinguishedName )",
"( 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 )",
"( 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 )",
"( 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 )",
"( 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 )",
"( 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.42 NAME ( 'givenName' 'gn' ) DESC 'RFC2256: first name(s) for which the entity is known by' SUP name )",
"( 2.5.4.43 NAME 'initials' DESC 'RFC2256: initials of some or all of names, but not the surname(s).' SUP name )",
"( 2.5.4.44 NAME 'generationQualifier' DESC 'RFC2256: name qualifier indicating a generation' SUP name )",
"( 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 )",
"( 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 )",
"( 2.5.4.47 NAME 'enhancedSearchGuide' DESC 'RFC2256: enhanced search guide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 )",
"( 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.50 NAME 'uniqueMember' DESC 'RFC2256: unique member of a group' EQUALITY uniqueMemberMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
"( 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} )",
"( 2.5.4.52 NAME 'supportedAlgorithms' DESC 'RFC2256: supported algorithms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 )",
"( 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 )",
"( 2.5.4.54 NAME 'dmdName' DESC 'RFC2256: name of DMD' SUP name )",
"( 2.5.4.65 NAME 'pseudonym' DESC 'X.520(4th): pseudonym for the object' SUP name )",
"( 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} )",
"( 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 )",
"( 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 )",
"( 1.2.840.113549.1.9.1 NAME ( 'email' 'emailAddress' 'pkcs9email' ) DESC 'RFC3280: legacy attribute for email addresses in DNs' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )",
"( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.4 NAME 'info' DESC 'RFC1274: general information' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2048} )",
"( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDrink' ) DESC 'RFC1274: favorite drink' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' DESC 'RFC1274: room number' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.7 NAME 'photo' DESC 'RFC1274: photo (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23{25000} )",
"( 0.9.2342.19200300.100.1.8 NAME 'userClass' DESC 'RFC1274: category of user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.9 NAME 'host' DESC 'RFC1274: host computer' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.10 NAME 'manager' DESC 'RFC1274: DN of manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' DESC 'RFC1274: unique identifier of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' DESC 'RFC1274: title of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' DESC 'RFC1274: version of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' DESC 'RFC1274: DN of author of document' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' DESC 'RFC1274: location of document original' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.20 NAME ( 'homePhone' 'homeTelephoneNumber' ) DESC 'RFC1274: home telephone number' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
"( 0.9.2342.19200300.100.1.21 NAME 'secretary' DESC 'RFC1274: DN of secretary' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox' SYNTAX 1.3.6.1.4.1.1466.115.121.1.39 )",
"( 0.9.2342.19200300.100.1.26 NAME 'aRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.27 NAME 'mDRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.28 NAME 'mXRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.29 NAME 'nSRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.30 NAME 'sOARecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.31 NAME 'cNAMERecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 0.9.2342.19200300.100.1.38 NAME 'associatedName' DESC 'RFC1274: DN of entry associated with domain' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' DESC 'RFC1274: home postal address' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
"( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' DESC 'RFC1274: personal title' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.41 NAME ( 'mobile' 'mobileTelephoneNumber' ) DESC 'RFC1274: mobile telephone number' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
"( 0.9.2342.19200300.100.1.42 NAME ( 'pager' 'pagerTelephoneNumber' ) DESC 'RFC1274: pager telephone number' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
"( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlyCountryName' ) DESC 'RFC1274: friendly country name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' DESC 'RFC1274: unique identifer' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus' DESC 'RFC1274: organizational status' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox' DESC 'RFC1274: Janet mailbox' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )",
"( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption' DESC 'RFC1274: mail preference option' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 0.9.2342.19200300.100.1.48 NAME 'buildingName' DESC 'RFC1274: name of building' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
"( 0.9.2342.19200300.100.1.49 NAME 'dSAQuality' DESC 'RFC1274: DSA Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.19 SINGLE-VALUE )",
"( 0.9.2342.19200300.100.1.50 NAME 'singleLevelQuality' DESC 'RFC1274: Single Level Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )",
"( 0.9.2342.19200300.100.1.51 NAME 'subtreeMinimumQuality' DESC 'RFC1274: Subtree Mininum Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )",
"( 0.9.2342.19200300.100.1.52 NAME 'subtreeMaximumQuality' DESC 'RFC1274: Subtree Maximun Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )",
"( 0.9.2342.19200300.100.1.53 NAME 'personalSignature' DESC 'RFC1274: Personal Signature (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23 )",
"( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect' DESC 'RFC1274: DIT Redirect' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 0.9.2342.19200300.100.1.55 NAME 'audio' DESC 'RFC1274: audio (u-law)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.4{25000} )",
"( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' DESC 'RFC1274: publisher of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.16.840.1.113730.3.1.1 NAME 'carLicense' DESC 'RFC2798: vehicle license or registration plate' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' DESC 'RFC2798: identifies a department within an organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.16.840.1.113730.3.1.241 NAME 'displayName' DESC 'RFC2798: preferred name to be used when displaying entries' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' DESC 'RFC2798: numerically identifies an employee within an organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 2.16.840.1.113730.3.1.4 NAME 'employeeType' DESC 'RFC2798: type of employment for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' DESC 'RFC2798: a JPEG image' SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )",
"( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' DESC 'RFC2798: preferred written or spoken language for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' DESC 'RFC2798: PKCS#7 SignedData used to support S/MIME' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )",
"( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' DESC 'RFC2798: personal identity information, a PKCS #12 PFX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )",
"( 1.3.6.1.1.1.1.2 NAME 'gecos' DESC 'The GECOS field; the common name' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' DESC 'The absolute path to the home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.4 NAME 'loginShell' DESC 'The path to the login shell' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.6 NAME 'shadowMin' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.7 NAME 'shadowMax' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.12 NAME 'memberUid' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgroup triple' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' DESC 'Service port number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' DESC 'Service protocol name' SUP name )",
"( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' DESC 'IP protocol number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' DESC 'ONC RPC number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' DESC 'IPv4 addresses as a dotted decimal omitting leading zeros or IPv6 addresses as defined in RFC2373' SUP name )",
"( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' DESC 'IP network as a dotted decimal, eg. 192.168, omitting leading zeros' SUP name SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0, omitting leading zeros' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.22 NAME 'macAddress' DESC 'MAC address in maximal, colon separated hex notation, eg. 00:00:92:90:ee:e2' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.23 NAME 'bootParameter' DESC 'rpc.bootparamd parameter' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.24 NAME 'bootFile' DESC 'Boot image name' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.26 NAME 'nisMapName' DESC 'Name of a A generic NIS map' SUP name )",
"( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' DESC 'A generic NIS entry' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey' DESC 'NIS public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey' DESC 'NIS secret key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.30 NAME 'nisDomain' DESC 'NIS domain' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.1.1.1.31 NAME 'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.32 NAME 'automountKey' DESC 'Automount Key value' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC 'Automount information' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.2 NAME 'suseDefaultBase' DESC 'Base DN where new Objects should be created by default' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.3 NAME 'suseNextUniqueId' DESC 'Next unused unique ID, can be used to generate directory wide uniqe IDs' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.4 NAME 'suseMinUniqueId' DESC 'lower Border for Unique IDs' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.5 NAME 'suseMaxUniqueId' DESC 'upper Border for Unique IDs' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.6 NAME 'suseDefaultTemplate' DESC 'The DN of a template that should be used by default' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.7 NAME 'suseSearchFilter' DESC 'Search filter to localize Objects' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.11 NAME 'suseDefaultValue' DESC 'an Attribute-Value-Assertions to define defaults for specific Attributes' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.7057.10.1.2.2.12 NAME 'suseNamingAttribute' DESC 'AttributeType that should be used as the RDN' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.15 NAME 'suseSecondaryGroup' DESC 'seconday group DN' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 1.3.6.1.4.1.7057.10.1.2.2.16 NAME 'suseMinPasswordLength' DESC 'minimum Password length for new users' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.17 NAME 'suseMaxPasswordLength' DESC 'maximum Password length for new users' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.18 NAME 'susePasswordHash' DESC 'Hash method to use for new users' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.19 NAME 'suseSkelDir' DESC '' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.4.1.7057.10.1.2.2.20 NAME 'susePlugin' DESC 'plugin to use upon user/ group creation' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.7057.10.1.2.2.21 NAME 'suseMapAttribute' DESC '' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.3.6.1.4.1.7057.10.1.2.2.22 NAME 'suseImapServer' DESC '' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.23 NAME 'suseImapAdmin' DESC '' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.24 NAME 'suseImapDefaultQuota' DESC '' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
"( 1.3.6.1.4.1.7057.10.1.2.2.25 NAME 'suseImapUseSsl' DESC '' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )"
],
"cn": [
"Subschema"
],
"createTimestamp": [
"20141024204149Z"
],
"entryDN": [
"cn=Subschema"
],
"ldapSyntaxes": [
"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.4203.666.11.10.2.1 DESC 'X.509 AttributeCertificate' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
"( 1.2.36.79672281.1.5.0 DESC 'RDN' )",
"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' )",
"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )",
"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
"( 1.3.6.1.1.16.1 DESC 'UUID' )"
],
"matchingRuleUse": [
"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbProtocolVersion $ olcDbConnectionPoolMax $ olcChainMaxReferralDepth $ olcDDSmaxDynamicObjects $ olcPcacheMaxQueries $ olcRetcodeSleep $ olcSssVlvMax $ olcSssVlvMaxKeys $ olcSssVlvMaxPerConn $ olcSpSessionlog $ mailPreferenceOption $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipServicePort $ ipProtocolNumber $ oncRpcNumber $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseMinPasswordLength $ suseMaxPasswordLength $ suseImapDefaultQuota ) )",
"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbProtocolVersion $ olcDbConnectionPoolMax $ olcChainMaxReferralDepth $ olcDDSmaxDynamicObjects $ olcPcacheMaxQueries $ olcRetcodeSleep $ olcSssVlvMax $ olcSssVlvMaxKeys $ olcSssVlvMaxPerConn $ olcSpSessionlog $ mailPreferenceOption $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipServicePort $ ipProtocolNumber $ oncRpcNumber $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseMinPasswordLength $ suseMaxPasswordLength $ suseImapDefaultQuota ) )",
"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' APPLIES ( altServer $ olcDbConfig $ c $ mail $ dc $ associatedDomain $ email $ aRecord $ mDRecord $ mXRecord $ nSRecord $ sOARecord $ cNAMERecord $ janetMailbox $ gecos $ homeDirectory $ loginShell $ memberUid $ memberNisNetgroup $ nisNetgroupTriple $ ipNetmaskNumber $ macAddress $ bootParameter $ bootFile $ nisMapEntry $ nisDomain $ automountMapName $ automountKey $ automountInformation $ suseNamingAttribute $ susePasswordHash $ suseSkelDir ) )",
"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' APPLIES ( altServer $ olcDbConfig $ c $ mail $ dc $ associatedDomain $ email $ aRecord $ mDRecord $ mXRecord $ nSRecord $ sOARecord $ cNAMERecord $ janetMailbox $ gecos $ homeDirectory $ loginShell $ memberUid $ memberNisNetgroup $ nisNetgroupTriple $ ipNetmaskNumber $ macAddress $ bootParameter $ bootFile $ nisMapEntry $ nisDomain $ automountMapName $ automountKey $ automountInformation $ suseNamingAttribute $ susePasswordHash $ suseSkelDir ) )",
"( 2.5.13.38 NAME 'certificateListExactMatch' APPLIES ( authorityRevocationList $ certificateRevocationList $ deltaRevocationList ) )",
"( 2.5.13.34 NAME 'certificateExactMatch' APPLIES ( userCertificate $ cACertificate ) )",
"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' APPLIES ( supportedControl $ supportedExtension $ supportedFeatures $ ldapSyntaxes $ supportedApplicationContext ) )",
"( 2.5.13.29 NAME 'integerFirstComponentMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbProtocolVersion $ olcDbConnectionPoolMax $ olcChainMaxReferralDepth $ olcDDSmaxDynamicObjects $ olcPcacheMaxQueries $ olcRetcodeSleep $ olcSssVlvMax $ olcSssVlvMaxKeys $ olcSssVlvMaxPerConn $ olcSpSessionlog $ mailPreferenceOption $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipServicePort $ ipProtocolNumber $ oncRpcNumber $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseMinPasswordLength $ suseMaxPasswordLength $ suseImapDefaultQuota ) )",
"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' APPLIES ( createTimestamp $ modifyTimestamp $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ pwdGraceUseTime ) )",
"( 2.5.13.27 NAME 'generalizedTimeMatch' APPLIES ( createTimestamp $ modifyTimestamp $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ pwdGraceUseTime ) )",
"( 2.5.13.24 NAME 'protocolInformationMatch' APPLIES protocolInformation )",
"( 2.5.13.23 NAME 'uniqueMemberMatch' APPLIES uniqueMember )",
"( 2.5.13.22 NAME 'presentationAddressMatch' APPLIES presentationAddress )",
"( 2.5.13.20 NAME 'telephoneNumberMatch' APPLIES ( telephoneNumber $ homePhone $ mobile $ pager ) )",
"( 2.5.13.18 NAME 'octetStringOrderingMatch' APPLIES ( userPassword $ olcDbCryptKey $ pwdHistory $ nisPublicKey $ nisSecretKey ) )",
"( 2.5.13.17 NAME 'octetStringMatch' APPLIES ( userPassword $ olcDbCryptKey $ pwdHistory $ nisPublicKey $ nisSecretKey ) )",
"( 2.5.13.16 NAME 'bitStringMatch' APPLIES x500UniqueIdentifier )",
"( 2.5.13.15 NAME 'integerOrderingMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbProtocolVersion $ olcDbConnectionPoolMax $ olcChainMaxReferralDepth $ olcDDSmaxDynamicObjects $ olcPcacheMaxQueries $ olcRetcodeSleep $ olcSssVlvMax $ olcSssVlvMaxKeys $ olcSssVlvMaxPerConn $ olcSpSessionlog $ mailPreferenceOption $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipServicePort $ ipProtocolNumber $ oncRpcNumber $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseMinPasswordLength $ suseMaxPasswordLength $ suseImapDefaultQuota ) )",
"( 2.5.13.14 NAME 'integerMatch' APPLIES ( supportedLDAPVersion $ entryTtl $ uidNumber $ gidNumber $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcIdleTimeout $ olcIndexSubstrIfMinLen $ olcIndexSubstrIfMaxLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcListenerThreads $ olcLocalSSF $ olcMaxDerefDepth $ olcReplicationInterval $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcThreads $ olcToolThreads $ olcWriteTimeout $ olcDbCacheFree $ olcDbCacheSize $ olcDbDNcacheSize $ olcDbIDLcacheSize $ olcDbSearchStack $ olcDbShmKey $ olcDbProtocolVersion $ olcDbConnectionPoolMax $ olcChainMaxReferralDepth $ olcDDSmaxDynamicObjects $ olcPcacheMaxQueries $ olcRetcodeSleep $ olcSssVlvMax $ olcSssVlvMaxKeys $ olcSssVlvMaxPerConn $ olcSpSessionlog $ mailPreferenceOption $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipServicePort $ ipProtocolNumber $ oncRpcNumber $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseMinPasswordLength $ suseMaxPasswordLength $ suseImapDefaultQuota ) )",
"( 2.5.13.13 NAME 'booleanMatch' APPLIES ( hasSubordinates $ olcAddContentAcl $ olcGentleHUP $ olcHidden $ olcLastMod $ olcMirrorMode $ olcMonitoring $ olcReadOnly $ olcReverseLookup $ olcSyncUseSubentry $ olcDbChecksum $ olcDbNoSync $ olcDbDirtyRead $ olcDbLinearIndex $ olcDbRebindAsUser $ olcDbChaseReferrals $ olcDbProxyWhoAmI $ olcDbSingleConn $ olcDbUseTemporaryConn $ olcDbNoRefs $ olcDbNoUndefFilter $ olcChainCacheURI $ olcChainReturnError $ olcAccessLogSuccess $ olcDDSstate $ olcMemberOfRefInt $ pwdReset $ olcPPolicyHashCleartext $ olcPPolicyForwardUpdates $ olcPPolicyUseLockout $ olcPcachePersist $ olcPcacheValidate $ olcPcacheOffline $ olcRetcodeInDir $ olcRwmNormalizeMapped $ olcRwmDropUnrequested $ olcSpNoPresent $ olcSpReloadHint $ olcTranslucentStrict $ olcTranslucentNoGlue $ olcTranslucentBindLocal $ olcTranslucentPwModLocal $ olcUniqueStrict $ suseImapUseSsl ) )",
"( 2.5.13.11 NAME 'caseIgnoreListMatch' APPLIES ( postalAddress $ registeredAddress $ homePostalAddress ) )",
"( 2.5.13.9 NAME 'numericStringOrderingMatch' APPLIES ( x121Address $ internationaliSDNNumber ) )",
"( 2.5.13.8 NAME 'numericStringMatch' APPLIES ( x121Address $ internationaliSDNNumber ) )",
"( 2.5.13.7 NAME 'caseExactSubstringsMatch' APPLIES ( serialNumber $ destinationIndicator $ dnQualifier ) )",
"( 2.5.13.6 NAME 'caseExactOrderingMatch' APPLIES ( supportedSASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olcDbLockDetect $ olcDbMode $ olcDbURI $ olcDbStartTLS $ olcDbACLPasswd $ olcDbACLBind $ olcDbIDAssertPasswd $ olcDbIDAssertBind $ olcDbIDAssertMode $ olcDbIDAssertAuthzFrom $ olcDbTFSupport $ olcDbTimeout $ olcDbIdleTimeout $ olcDbConnTtl $ olcDbNetworkTimeout $ olcDbCancel $ olcDbQuarantine $ olcDbIDAssertPassThru $ olcChainingBehavior $ olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBase $ olcAuditlogFile $ olcCollectInfo $ olcConstraintAttribute $ olcDDSmaxTtl $ olcDDSminTtl $ olcDDSdefaultTtl $ olcDDSinterval $ olcDDStolerance $ olcDGAttrPair $ olcDlAttrSet $ olcMemberOfDangling $ olcMemberOfGroupOC $ olcMemberOfMemberAD $ olcMemberOfMemberOfAD $ olcMemberOfDanglingError $ olcPcache $ olcPcacheAttrset $ olcPcacheTemplate $ olcPcachePosition $ olcPcacheBind $ olcRefintAttribute $ olcRetcodeItem $ olcRwmRewrite $ olcRwmTFSupport $ olcRwmMap $ olcSpCheckpoint $ olcTranslucentLocal $ olcTranslucentRemote $ olcUniqueIgnore $ olcUniqueAttribute $ olcUniqueURI $ olcValSortAttr $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ destinationIndicator $ givenName $ initials $ generationQualifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ documentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredLanguage $ ipServiceProtocol $ ipHostNumber $ ipNetworkNumber $ nisMapName $ suseSearchFilter $ suseDefaultValue $ susePlugin $ suseMapAttribute $ suseImapServer $ suseImapAdmin ) )",
"( 2.5.13.5 NAME 'caseExactMatch' APPLIES ( supportedSASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olcDbLockDetect $ olcDbMode $ olcDbURI $ olcDbStartTLS $ olcDbACLPasswd $ olcDbACLBind $ olcDbIDAssertPasswd $ olcDbIDAssertBind $ olcDbIDAssertMode $ olcDbIDAssertAuthzFrom $ olcDbTFSupport $ olcDbTimeout $ olcDbIdleTimeout $ olcDbConnTtl $ olcDbNetworkTimeout $ olcDbCancel $ olcDbQuarantine $ olcDbIDAssertPassThru $ olcChainingBehavior $ olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBase $ olcAuditlogFile $ olcCollectInfo $ olcConstraintAttribute $ olcDDSmaxTtl $ olcDDSminTtl $ olcDDSdefaultTtl $ olcDDSinterval $ olcDDStolerance $ olcDGAttrPair $ olcDlAttrSet $ olcMemberOfDangling $ olcMemberOfGroupOC $ olcMemberOfMemberAD $ olcMemberOfMemberOfAD $ olcMemberOfDanglingError $ olcPcache $ olcPcacheAttrset $ olcPcacheTemplate $ olcPcachePosition $ olcPcacheBind $ olcRefintAttribute $ olcRetcodeItem $ olcRwmRewrite $ olcRwmTFSupport $ olcRwmMap $ olcSpCheckpoint $ olcTranslucentLocal $ olcTranslucentRemote $ olcUniqueIgnore $ olcUniqueAttribute $ olcUniqueURI $ olcValSortAttr $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ destinationIndicator $ givenName $ initials $ generationQualifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ documentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredLanguage $ ipServiceProtocol $ ipHostNumber $ ipNetworkNumber $ nisMapName $ suseSearchFilter $ suseDefaultValue $ susePlugin $ suseMapAttribute $ suseImapServer $ suseImapAdmin ) )",
"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' APPLIES ( serialNumber $ destinationIndicator $ dnQualifier ) )",
"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' APPLIES ( supportedSASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olcDbLockDetect $ olcDbMode $ olcDbURI $ olcDbStartTLS $ olcDbACLPasswd $ olcDbACLBind $ olcDbIDAssertPasswd $ olcDbIDAssertBind $ olcDbIDAssertMode $ olcDbIDAssertAuthzFrom $ olcDbTFSupport $ olcDbTimeout $ olcDbIdleTimeout $ olcDbConnTtl $ olcDbNetworkTimeout $ olcDbCancel $ olcDbQuarantine $ olcDbIDAssertPassThru $ olcChainingBehavior $ olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBase $ olcAuditlogFile $ olcCollectInfo $ olcConstraintAttribute $ olcDDSmaxTtl $ olcDDSminTtl $ olcDDSdefaultTtl $ olcDDSinterval $ olcDDStolerance $ olcDGAttrPair $ olcDlAttrSet $ olcMemberOfDangling $ olcMemberOfGroupOC $ olcMemberOfMemberAD $ olcMemberOfMemberOfAD $ olcMemberOfDanglingError $ olcPcache $ olcPcacheAttrset $ olcPcacheTemplate $ olcPcachePosition $ olcPcacheBind $ olcRefintAttribute $ olcRetcodeItem $ olcRwmRewrite $ olcRwmTFSupport $ olcRwmMap $ olcSpCheckpoint $ olcTranslucentLocal $ olcTranslucentRemote $ olcUniqueIgnore $ olcUniqueAttribute $ olcUniqueURI $ olcValSortAttr $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ destinationIndicator $ givenName $ initials $ generationQualifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ documentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredLanguage $ ipServiceProtocol $ ipHostNumber $ ipNetworkNumber $ nisMapName $ suseSearchFilter $ suseDefaultValue $ susePlugin $ suseMapAttribute $ suseImapServer $ suseImapAdmin ) )",
"( 2.5.13.2 NAME 'caseIgnoreMatch' APPLIES ( supportedSASLMechanisms $ vendorName $ vendorVersion $ ref $ name $ cn $ uid $ labeledURI $ description $ olcConfigFile $ olcConfigDir $ olcAccess $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcBackend $ olcDatabase $ olcDisallows $ olcDitContentRules $ olcExtraAttrs $ olcInclude $ olcLdapSyntaxes $ olcLimits $ olcLogFile $ olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectClasses $ olcObjectIdentifier $ olcOverlay $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPlugin $ olcPluginLogFile $ olcReferral $ olcReplica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplogFile $ olcRequires $ olcRestrict $ olcRootDSE $ olcRootPW $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSortVals $ olcSubordinate $ olcSyncrepl $ olcTCPBuffer $ olcTimeLimit $ olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSCRLFile $ olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSProtocolMin $ olcUpdateRef $ olcDbDirectory $ olcDbCheckpoint $ olcDbCryptFile $ olcDbPageSize $ olcDbIndex $ olcDbLockDetect $ olcDbMode $ olcDbURI $ olcDbStartTLS $ olcDbACLPasswd $ olcDbACLBind $ olcDbIDAssertPasswd $ olcDbIDAssertBind $ olcDbIDAssertMode $ olcDbIDAssertAuthzFrom $ olcDbTFSupport $ olcDbTimeout $ olcDbIdleTimeout $ olcDbConnTtl $ olcDbNetworkTimeout $ olcDbCancel $ olcDbQuarantine $ olcDbIDAssertPassThru $ olcChainingBehavior $ olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBase $ olcAuditlogFile $ olcCollectInfo $ olcConstraintAttribute $ olcDDSmaxTtl $ olcDDSminTtl $ olcDDSdefaultTtl $ olcDDSinterval $ olcDDStolerance $ olcDGAttrPair $ olcDlAttrSet $ olcMemberOfDangling $ olcMemberOfGroupOC $ olcMemberOfMemberAD $ olcMemberOfMemberOfAD $ olcMemberOfDanglingError $ olcPcache $ olcPcacheAttrset $ olcPcacheTemplate $ olcPcachePosition $ olcPcacheBind $ olcRefintAttribute $ olcRetcodeItem $ olcRwmRewrite $ olcRwmTFSupport $ olcRwmMap $ olcSpCheckpoint $ olcTranslucentLocal $ olcTranslucentRemote $ olcUniqueIgnore $ olcUniqueAttribute $ olcUniqueURI $ olcValSortAttr $ knowledgeInformation $ sn $ serialNumber $ c $ l $ st $ street $ o $ ou $ title $ businessCategory $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ destinationIndicator $ givenName $ initials $ generationQualifier $ dnQualifier $ houseIdentifier $ dmdName $ pseudonym $ textEncodedORAddress $ info $ drink $ roomNumber $ userClass $ host $ documentIdentifier $ documentTitle $ documentVersion $ documentLocation $ personalTitle $ co $ uniqueIdentifier $ organizationalStatus $ buildingName $ documentPublisher $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ preferredLanguage $ ipServiceProtocol $ ipHostNumber $ ipNetworkNumber $ nisMapName $ suseSearchFilter $ suseDefaultValue $ susePlugin $ suseMapAttribute $ suseImapServer $ suseImapAdmin ) )",
"( 2.5.13.1 NAME 'distinguishedNameMatch' APPLIES ( creatorsName $ modifiersName $ subschemaSubentry $ entryDN $ namingContexts $ aliasedObjectName $ dynamicSubtrees $ distinguishedName $ seeAlso $ olcDefaultSearchBase $ olcRootDN $ olcSchemaDN $ olcSuffix $ olcUpdateDN $ olcDbACLAuthcDn $ olcDbIDAssertAuthcDn $ olcRelay $ olcAccessLogDB $ memberOf $ olcMemberOfDN $ pwdPolicySubentry $ olcPPolicyDefault $ olcRefintNothing $ olcRefintModifiersName $ olcRetcodeParent $ olcUniqueBase $ member $ owner $ roleOccupant $ manager $ documentAuthor $ secretary $ associatedName $ dITRedirect $ suseDefaultBase $ suseDefaultTemplate $ suseSecondaryGroup ) )",
"( 2.5.13.0 NAME 'objectIdentifierMatch' APPLIES ( supportedControl $ supportedExtension $ supportedFeatures $ supportedApplicationContext ) )"
],
"matchingRules": [
"( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' SYNTAX 1.3.6.1.1.16.1 )",
"( 1.3.6.1.1.16.2 NAME 'UUIDMatch' SYNTAX 1.3.6.1.1.16.1 )",
"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
"( 2.5.13.38 NAME 'certificateListExactMatch' SYNTAX 1.3.6.1.1.15.5 )",
"( 2.5.13.34 NAME 'certificateExactMatch' SYNTAX 1.3.6.1.1.15.1 )",
"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
"( 2.5.13.29 NAME 'integerFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
"( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
"( 2.5.13.23 NAME 'uniqueMemberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
"( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
"( 2.5.13.19 NAME 'octetStringSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
"( 2.5.13.18 NAME 'octetStringOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
"( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
"( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
"( 2.5.13.15 NAME 'integerOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 2.5.13.14 NAME 'integerMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
"( 2.5.13.13 NAME 'booleanMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
"( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
"( 2.5.13.10 NAME 'numericStringSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
"( 2.5.13.9 NAME 'numericStringOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
"( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
"( 2.5.13.7 NAME 'caseExactSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
"( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.5.13.5 NAME 'caseExactMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
"( 1.2.36.79672281.1.13.3 NAME 'rdnMatch' SYNTAX 1.2.36.79672281.1.5.0 )",
"( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
"( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )"
],
"modifyTimestamp": [
"20141024204149Z"
],
"objectClass": [
"top",
"subentry",
"subschema",
"extensibleObject"
],
"objectClasses": [
"( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT MUST objectClass )",
"( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' DESC 'RFC4512: extensible object' SUP top AUXILIARY )",
"( 2.5.6.1 NAME 'alias' DESC 'RFC4512: an alias' SUP top STRUCTURAL MUST aliasedObjectName )",
"( 2.16.840.1.113730.3.2.6 NAME 'referral' DESC 'namedref: named subordinate referral' SUP top STRUCTURAL MUST ref )",
"( 1.3.6.1.4.1.4203.1.4.1 NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) DESC 'OpenLDAP Root DSE object' SUP top STRUCTURAL MAY cn )",
"( 2.5.17.0 NAME 'subentry' DESC 'RFC3672: subentry' SUP top STRUCTURAL MUST ( cn $ subtreeSpecification ) )",
"( 2.5.20.1 NAME 'subschema' DESC 'RFC4512: controlling subschema (sub)entry' AUXILIARY MAY ( dITStructureRules $ nameForms $ dITContentRules $ objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )",
"( 1.3.6.1.4.1.1466.101.119.2 NAME 'dynamicObject' DESC 'RFC2589: Dynamic Object' SUP top AUXILIARY )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.0 NAME 'olcConfig' DESC 'OpenLDAP configuration object' SUP top ABSTRACT )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.1 NAME 'olcGlobal' DESC 'OpenLDAP Global configuration options' SUP olcConfig STRUCTURAL MAY ( cn $ olcConfigFile $ olcConfigDir $ olcAllows $ olcArgsFile $ olcAttributeOptions $ olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ olcDisallows $ olcGentleHUP $ olcIdleTimeout $ olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ olcLocalSSF $ olcLogFile $ olcLogLevel $ olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ olcPluginLogFile $ olcReadOnly $ olcReferral $ olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ olcRootDSE $ olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ olcSecurity $ olcServerID $ olcSizeLimit $ olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcTCPBuffer $ olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ olcTLSCACertificatePath $ olcTLSCertificateFile $ olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSCRLFile $ olcToolThreads $ olcWriteTimeout $ olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ olcDitContentRules $ olcLdapSyntaxes ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.2 NAME 'olcSchemaConfig' DESC 'OpenLDAP schema object' SUP olcConfig STRUCTURAL MAY ( cn $ olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ olcDitContentRules $ olcLdapSyntaxes ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.3 NAME 'olcBackendConfig' DESC 'OpenLDAP Backend-specific options' SUP olcConfig STRUCTURAL MUST olcBackend )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.4 NAME 'olcDatabaseConfig' DESC 'OpenLDAP Database-specific options' SUP olcConfig STRUCTURAL MUST olcDatabase MAY ( olcHidden $ olcSuffix $ olcSubordinate $ olcAccess $ olcAddContentAcl $ olcLastMod $ olcLimits $ olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ olcMonitoring $ olcExtraAttrs ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.5 NAME 'olcOverlayConfig' DESC 'OpenLDAP Overlay-specific options' SUP olcConfig STRUCTURAL MUST olcOverlay )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.6 NAME 'olcIncludeFile' DESC 'OpenLDAP configuration include file' SUP olcConfig STRUCTURAL MUST olcInclude MAY ( cn $ olcRootDSE ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.7 NAME 'olcFrontendConfig' DESC 'OpenLDAP frontend configuration' AUXILIARY MAY ( olcDefaultSearchBase $ olcPasswordHash $ olcSortVals ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.0.8 NAME 'olcModuleList' DESC 'OpenLDAP dynamic module info' SUP olcConfig STRUCTURAL MAY ( cn $ olcModulePath $ olcModuleLoad ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.2.1 NAME 'olcLdifConfig' DESC 'LDIF backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.4.1 NAME 'olcMonitorConfig' DESC 'Monitor backend configuration' SUP olcDatabaseConfig STRUCTURAL )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.1.1 NAME 'olcBdbConfig' DESC 'BDB backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ olcDbCryptFile $ olcDbCryptKey $ olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ olcDbMode $ olcDbSearchStack $ olcDbShmKey $ olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.1.2 NAME 'olcHdbConfig' DESC 'HDB backend configuration' SUP olcDatabaseConfig STRUCTURAL MUST olcDbDirectory MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ olcDbCryptFile $ olcDbCryptKey $ olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ olcDbMode $ olcDbSearchStack $ olcDbShmKey $ olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.3.1 NAME 'olcLDAPConfig' DESC 'LDAP backend configuration' SUP olcDatabaseConfig STRUCTURAL MAY ( olcDbURI $ olcDbStartTLS $ olcDbACLAuthcDn $ olcDbACLPasswd $ olcDbACLBind $ olcDbIDAssertAuthcDn $ olcDbIDAssertPasswd $ olcDbIDAssertBind $ olcDbIDAssertMode $ olcDbIDAssertAuthzFrom $ olcDbIDAssertPassThru $ olcDbRebindAsUser $ olcDbChaseReferrals $ olcDbTFSupport $ olcDbProxyWhoAmI $ olcDbTimeout $ olcDbIdleTimeout $ olcDbConnTtl $ olcDbNetworkTimeout $ olcDbProtocolVersion $ olcDbSingleConn $ olcDbCancel $ olcDbQuarantine $ olcDbUseTemporaryConn $ olcDbConnectionPoolMax $ olcDbNoRefs $ olcDbNoUndefFilter ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.3.1 NAME 'olcChainConfig' DESC 'Chain configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcChainingBehavior $ olcChainCacheURI $ olcChainMaxReferralDepth $ olcChainReturnError ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.3.2 NAME 'olcChainDatabase' DESC 'Chain remote server configuration' AUXILIARY )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.3.3 NAME 'olcPBindConfig' DESC 'Proxy Bind configuration' SUP olcOverlayConfig STRUCTURAL MUST olcDbURI MAY ( olcDbStartTLS $ olcDbNetworkTimeout $ olcDbQuarantine ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.7.1 NAME 'olcDistProcConfig' DESC 'Distributed procedures <draft-sermersheim-ldap-distproc> configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcChainingBehavior $ olcChainCacheURI ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.7.2 NAME 'olcDistProcDatabase' DESC 'Distributed procedure remote server configuration' AUXILIARY )",
"( 1.3.6.1.4.1.4203.1.12.2.4.2.5.1 NAME 'olcRelayConfig' DESC 'Relay backend configuration' SUP olcDatabaseConfig STRUCTURAL MAY olcRelay )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.4.1 NAME 'olcAccessLogConfig' DESC 'Access log configuration' SUP olcOverlayConfig STRUCTURAL MUST olcAccessLogDB MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess $ olcAccessLogOld $ olcAccessLogOldAttr $ olcAccessLogBase ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.15.1 NAME 'olcAuditlogConfig' DESC 'Auditlog configuration' SUP olcOverlayConfig STRUCTURAL MAY olcAuditlogFile )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.19.1 NAME 'olcCollectConfig' DESC 'Collective Attribute configuration' SUP olcOverlayConfig STRUCTURAL MAY olcCollectInfo )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.13.1 NAME 'olcConstraintConfig' DESC 'Constraint overlay configuration' SUP olcOverlayConfig STRUCTURAL MAY olcConstraintAttribute )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.9.1 NAME 'olcDDSConfig' DESC 'RFC2589 Dynamic directory services configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcDDSstate $ olcDDSmaxTtl $ olcDDSminTtl $ olcDDSdefaultTtl $ olcDDSinterval $ olcDDStolerance $ olcDDSmaxDynamicObjects ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.17.1 NAME 'olcDGConfig' DESC 'Dynamic Group configuration' SUP olcOverlayConfig STRUCTURAL MAY olcDGAttrPair )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.8.1 NAME 'olcDynamicList' DESC 'Dynamic list configuration' SUP olcOverlayConfig STRUCTURAL MAY olcDLattrSet )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.18.1 NAME 'olcMemberOf' DESC 'Member-of configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcMemberOfDN $ olcMemberOfDangling $ olcMemberOfDanglingError $ olcMemberOfRefInt $ olcMemberOfGroupOC $ olcMemberOfMemberAD $ olcMemberOfMemberOfAD ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.12.1 NAME 'olcPPolicyConfig' DESC 'Password Policy configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcPPolicyDefault $ olcPPolicyHashCleartext $ olcPPolicyUseLockout $ olcPPolicyForwardUpdates ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.2.1 NAME 'olcPcacheConfig' DESC 'ProxyCache configuration' SUP olcOverlayConfig STRUCTURAL MUST ( olcPcache $ olcPcacheAttrset $ olcPcacheTemplate ) MAY ( olcPcachePosition $ olcPcacheMaxQueries $ olcPcachePersist $ olcPcacheValidate $ olcPcacheOffline $ olcPcacheBind ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.2.2 NAME 'olcPcacheDatabase' DESC 'Cache database configuration' AUXILIARY )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.11.1 NAME 'olcRefintConfig' DESC 'Referential integrity configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcRefintAttribute $ olcRefintNothing $ olcRefintModifiersName ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.20.1 NAME 'olcRetcodeConfig' DESC 'Retcode configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcRetcodeParent $ olcRetcodeItem $ olcRetcodeInDir $ olcRetcodeSleep ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.16.1 NAME 'olcRwmConfig' DESC 'Rewrite/remap configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcRwmRewrite $ olcRwmTFSupport $ olcRwmMap $ olcRwmNormalizeMapped ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.21.1 NAME 'olcSssVlvConfig' DESC 'SSS VLV configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcSssVlvMax $ olcSssVlvMaxKeys ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.1.1 NAME 'olcSyncProvConfig' DESC 'SyncRepl Provider configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcSpCheckpoint $ olcSpSessionlog $ olcSpNoPresent $ olcSpReloadHint ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.14.1 NAME 'olcTranslucentConfig' DESC 'Translucent configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcTranslucentStrict $ olcTranslucentNoGlue $ olcTranslucentLocal $ olcTranslucentRemote $ olcTranslucentBindLocal $ olcTranslucentPwModLocal ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.14.2 NAME 'olcTranslucentDatabase' DESC 'Translucent target database configuration' AUXILIARY )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.10.1 NAME 'olcUniqueConfig' DESC 'Attribute value uniqueness configuration' SUP olcOverlayConfig STRUCTURAL MAY ( olcUniqueBase $ olcUniqueIgnore $ olcUniqueAttribute $ olcUniqueStrict $ olcUniqueURI ) )",
"( 1.3.6.1.4.1.4203.1.12.2.4.3.5.1 NAME 'olcValSortConfig' DESC 'Value Sorting configuration' SUP olcOverlayConfig STRUCTURAL MUST olcValSortAttr )",
"( 2.5.6.2 NAME 'country' DESC 'RFC2256: a country' SUP top STRUCTURAL MUST c MAY ( searchGuide $ description ) )",
"( 2.5.6.3 NAME 'locality' DESC 'RFC2256: a locality' SUP top STRUCTURAL MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) )",
"( 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 ) )",
"( 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 ) )",
"( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )",
"( 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 ) )",
"( 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 ) )",
"( 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 ) )",
"( 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 ) )",
"( 2.5.6.11 NAME 'applicationProcess' DESC 'RFC2256: an application process' SUP top STRUCTURAL MUST cn MAY ( seeAlso $ ou $ l $ description ) )",
"( 2.5.6.12 NAME 'applicationEntity' DESC 'RFC2256: an application entity' SUP top STRUCTURAL MUST ( presentationAddress $ cn ) MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $ description ) )",
"( 2.5.6.13 NAME 'dSA' DESC 'RFC2256: a directory system agent (a server)' SUP applicationEntity STRUCTURAL MAY knowledgeInformation )",
"( 2.5.6.14 NAME 'device' DESC 'RFC2256: a device' SUP top STRUCTURAL MUST cn MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )",
"( 2.5.6.15 NAME 'strongAuthenticationUser' DESC 'RFC2256: a strong authentication user' SUP top AUXILIARY MUST userCertificate )",
"( 2.5.6.16 NAME 'certificationAuthority' DESC 'RFC2256: a certificate authority' SUP top AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY crossCertificatePair )",
"( 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 ) )",
"( 2.5.6.18 NAME 'userSecurityInformation' DESC 'RFC2256: a user security information' SUP top AUXILIARY MAY supportedAlgorithms )",
"( 2.5.6.16.2 NAME 'certificationAuthority-V2' SUP certificationAuthority AUXILIARY MAY deltaRevocationList )",
"( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL MUST cn MAY ( certificateRevocationList $ authorityRevocationList $ deltaRevocationList ) )",
"( 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 ) )",
"( 2.5.6.21 NAME 'pkiUser' DESC 'RFC2587: a PKI user' SUP top AUXILIARY MAY userCertificate )",
"( 2.5.6.22 NAME 'pkiCA' DESC 'RFC2587: PKI certificate authority' SUP top AUXILIARY MAY ( authorityRevocationList $ certificateRevocationList $ cACertificate $ crossCertificatePair ) )",
"( 2.5.6.23 NAME 'deltaCRL' DESC 'RFC2587: PKI user' SUP top AUXILIARY MAY deltaRevocationList )",
"( 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 )",
"( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' DESC 'RFC1274: simple security object' SUP top AUXILIARY MUST userPassword )",
"( 1.3.6.1.4.1.1466.344 NAME 'dcObject' DESC 'RFC2247: domain component object' SUP top AUXILIARY MUST dc )",
"( 1.3.6.1.1.3.1 NAME 'uidObject' DESC 'RFC2377: uid object' SUP top AUXILIARY MUST uid )",
"( 0.9.2342.19200300.100.4.4 NAME ( 'pilotPerson' 'newPilotPerson' ) SUP person STRUCTURAL MAY ( userid $ textEncodedORAddress $ rfc822Mailbox $ favouriteDrink $ roomNumber $ userClass $ homeTelephoneNumber $ homePostalAddress $ secretary $ personalTitle $ preferredDeliveryMethod $ businessCategory $ janetMailbox $ otherMailbox $ mobileTelephoneNumber $ pagerTelephoneNumber $ organizationalStatus $ mailPreferenceOption $ personalSignature ) )",
"( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL MUST userid MAY ( description $ seeAlso $ localityName $ organizationName $ organizationalUnitName $ host ) )",
"( 0.9.2342.19200300.100.4.6 NAME 'document' SUP top STRUCTURAL MUST documentIdentifier MAY ( commonName $ description $ seeAlso $ localityName $ organizationName $ organizationalUnitName $ documentTitle $ documentVersion $ documentAuthor $ documentLocation $ documentPublisher ) )",
"( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURAL MUST commonName MAY ( roomNumber $ description $ seeAlso $ telephoneNumber ) )",
"( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top STRUCTURAL MUST commonName MAY ( description $ seeAlso $ telephonenumber $ localityName $ organizationName $ organizationalUnitName ) )",
"( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL MUST domainComponent MAY ( associatedName $ organizationName $ description $ businessCategory $ seeAlso $ searchGuide $ userPassword $ localityName $ stateOrProvinceName $ streetAddress $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ streetAddress $ facsimileTelephoneNumber $ internationalISDNNumber $ telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ preferredDeliveryMethod $ destinationIndicator $ registeredAddress $ x121Address ) )",
"( 0.9.2342.19200300.100.4.14 NAME 'RFC822localPart' SUP domain STRUCTURAL MAY ( commonName $ surname $ description $ seeAlso $ telephoneNumber $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ streetAddress $ facsimileTelephoneNumber $ internationalISDNNumber $ telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ preferredDeliveryMethod $ destinationIndicator $ registeredAddress $ x121Address ) )",
"( 0.9.2342.19200300.100.4.15 NAME 'dNSDomain' SUP domain STRUCTURAL MAY ( ARecord $ MDRecord $ MXRecord $ NSRecord $ SOARecord $ CNAMERecord ) )",
"( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' DESC 'RFC1274: an object related to an domain' SUP top AUXILIARY MUST associatedDomain )",
"( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP country STRUCTURAL MUST friendlyCountryName )",
"( 0.9.2342.19200300.100.4.20 NAME 'pilotOrganization' SUP ( organization $ organizationalUnit ) STRUCTURAL MAY buildingName )",
"( 0.9.2342.19200300.100.4.21 NAME 'pilotDSA' SUP dsa STRUCTURAL MAY dSAQuality )",
"( 0.9.2342.19200300.100.4.22 NAME 'qualityLabelledData' SUP top AUXILIARY MUST dsaQuality MAY ( subtreeMinimumQuality $ subtreeMaximumQuality ) )",
"( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2798: Internet Organizational Person' SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ roomNumber $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ preferredLanguage $ userSMIMECertificate $ userPKCS12 ) )",
"( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) )",
"( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' DESC 'Additional attributes for shadow passwords' SUP top AUXILIARY MUST uid MAY ( userPassword $ description $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ) )",
"( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top AUXILIARY MUST gidNumber MAY ( userPassword $ memberUid $ description ) )",
"( 1.3.6.1.1.1.2.3 NAME 'ipService' DESC 'Abstraction an Internet Protocol service. Maps an IP port and protocol (such as tcp or udp) to one or more names; the distinguished value of the cn attribute denotes the services canonical name' SUP top STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtocol ) MAY description )",
"( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' DESC 'Abstraction of an IP protocol. Maps a protocol number to one or more names. The distinguished value of the cn attribute denotes the protocols canonical name' SUP top STRUCTURAL MUST ( cn $ ipProtocolNumber ) MAY description )",
"( 1.3.6.1.1.1.2.5 NAME 'oncRpc' DESC 'Abstraction of an Open Network Computing (ONC) [RFC1057] Remote Procedure Call (RPC) binding. This class maps an ONC RPC number to a name. The distinguished value of the cn attribute denotes the RPC services canonical name' SUP top STRUCTURAL MUST ( cn $ oncRpcNumber ) MAY description )",
"( 1.3.6.1.1.1.2.6 NAME 'ipHost' DESC 'Abstraction of a host, an IP device. The distinguished value of the cn attribute denotes the hosts canonical name. Device SHOULD be used as a structural class' SUP top AUXILIARY MUST ( cn $ ipHostNumber ) MAY ( userPassword $ l $ description $ manager ) )",
"( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Abstraction of a network. The distinguished value of the cn attribute denotes the networks canonical name' SUP top STRUCTURAL MUST ipNetworkNumber MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )",
"( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' DESC 'Abstraction of a netgroup. May refer to other netgroups' SUP top STRUCTURAL MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )",
"( 1.3.6.1.1.1.2.9 NAME 'nisMap' DESC 'A generic abstraction of a NIS map' SUP top STRUCTURAL MUST nisMapName MAY description )",
"( 1.3.6.1.1.1.2.10 NAME 'nisObject' DESC 'An entry in a NIS map' SUP top STRUCTURAL MUST ( cn $ nisMapEntry $ nisMapName ) MAY description )",
"( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' DESC 'A device with a MAC address; device SHOULD be used as a structural class' SUP top AUXILIARY MAY macAddress )",
"( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' DESC 'A device with boot parameters; device SHOULD be used as a structural class' SUP top AUXILIARY MAY ( bootFile $ bootParameter ) )",
"( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' DESC 'An object with a public and secret key' SUP top AUXILIARY MUST ( cn $ nisPublicKey $ nisSecretKey ) MAY ( uidNumber $ description ) )",
"( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' DESC 'Associates a NIS domain with a naming context' SUP top AUXILIARY MUST nisDomain )",
"( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL MUST automountMapName MAY description )",
"( 1.3.6.1.1.1.2.17 NAME 'automount' DESC 'Automount information' SUP top STRUCTURAL MUST ( automountKey $ automountInformation ) MAY description )",
"( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top STRUCTURAL MAY cn )",
"( 1.3.6.1.4.1.7057.10.1.2.1.2 NAME 'suseModuleConfiguration' DESC 'Contains configuration of Management Modules' SUP top STRUCTURAL MUST cn MAY suseDefaultBase )",
"( 1.3.6.1.4.1.7057.10.1.2.1.3 NAME 'suseUserConfiguration' DESC 'Configuration of user management tools' SUP suseModuleConfiguration STRUCTURAL MAY ( suseMinPasswordLength $ suseMaxPasswordLength $ susePasswordHash $ suseSkelDir $ suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseDefaultTemplate $ suseSearchFilter $ suseMapAttribute ) )",
"( 1.3.6.1.4.1.7057.10.1.2.1.4 NAME 'suseObjectTemplate' DESC 'Base Class for Object-Templates' SUP top STRUCTURAL MUST cn MAY ( susePlugin $ suseDefaultValue $ suseNamingAttribute ) )",
"( 1.3.6.1.4.1.7057.10.1.2.1.5 NAME 'suseUserTemplate' DESC 'User object template' SUP suseObjectTemplate STRUCTURAL MUST cn MAY suseSecondaryGroup )",
"( 1.3.6.1.4.1.7057.10.1.2.1.6 NAME 'suseGroupTemplate' DESC 'Group object template' SUP suseObjectTemplate STRUCTURAL MUST cn )",
"( 1.3.6.1.4.1.7057.10.1.2.1.7 NAME 'suseGroupConfiguration' DESC 'Configuration of user management tools' SUP suseModuleConfiguration STRUCTURAL MAY ( suseNextUniqueId $ suseMinUniqueId $ suseMaxUniqueId $ suseDefaultTemplate $ suseSearchFilter $ suseMapAttribute ) )",
"( 1.3.6.1.4.1.7057.10.1.2.1.8 NAME 'suseCaConfiguration' DESC 'Configuration of CA management tools' SUP suseModuleConfiguration STRUCTURAL )",
"( 1.3.6.1.4.1.7057.10.1.2.1.9 NAME 'suseDnsConfiguration' DESC 'Configuration of mail server management tools' SUP suseModuleConfiguration STRUCTURAL )",
"( 1.3.6.1.4.1.7057.10.1.2.1.10 NAME 'suseDhcpConfiguration' DESC 'Configuration of DHCP server management tools' SUP suseModuleConfiguration STRUCTURAL )",
"( 1.3.6.1.4.1.7057.10.1.2.1.11 NAME 'suseMailConfiguration' DESC 'Configuration of IMAP user management tools' SUP suseModuleConfiguration STRUCTURAL MUST ( suseImapServer $ suseImapAdmin $ suseImapDefaultQuota $ suseImapUseSsl ) )"
],
"structuralObjectClass": [
"subentry"
],
"subschemaSubentry": [
"cn=Subschema"
]
},
"schema_entry": "cn=Subschema",
"type": "SchemaInfo"
}
"""
slapd_2_4_dsa_info = """
{
"raw": {
"configContext": [
"cn=config"
],
"entryDN": [
""
],
"namingContexts": [
"o=services",
"o=test"
],
"objectClass": [
"top",
"OpenLDAProotDSE"
],
"structuralObjectClass": [
"OpenLDAProotDSE"
],
"subschemaSubentry": [
"cn=Subschema"
],
"supportedControl": [
"1.3.6.1.4.1.4203.1.9.1.1",
"2.16.840.1.113730.3.4.18",
"2.16.840.1.113730.3.4.2",
"1.3.6.1.4.1.4203.1.10.1",
"1.2.840.113556.1.4.319",
"1.2.826.0.1.3344810.2.3",
"1.3.6.1.1.13.2",
"1.3.6.1.1.13.1",
"1.3.6.1.1.12"
],
"supportedExtension": [
"1.3.6.1.4.1.1466.20037",
"1.3.6.1.4.1.4203.1.11.1",
"1.3.6.1.4.1.4203.1.11.3",
"1.3.6.1.1.8"
],
"supportedFeatures": [
"1.3.6.1.1.14",
"1.3.6.1.4.1.4203.1.5.1",
"1.3.6.1.4.1.4203.1.5.2",
"1.3.6.1.4.1.4203.1.5.3",
"1.3.6.1.4.1.4203.1.5.4",
"1.3.6.1.4.1.4203.1.5.5"
],
"supportedLDAPVersion": [
"3"
],
"supportedSASLMechanisms": [
"GSSAPI",
"DIGEST-MD5"
]
},
"type": "DsaInfo"
}
"""