From 7e4b28b2d44d93a6783ee5523a6136b11b112904 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 13:37:01 +0100 Subject: [PATCH 1/8] [ldap-user-sync] Add LDAP -> Dispatcharr user sync plugin Syncs Admin/Streamer accounts from any standard LDAP directory into Dispatcharr on a schedule or on demand, with XC password provisioning and email delivery. --- plugins/ldap-user-sync/README.md | 86 + plugins/ldap-user-sync/__init__.py | 3 + .../_ldap_user_sync_durable/__init__.py | 96 + plugins/ldap-user-sync/ldap_client.py | 188 + plugins/ldap-user-sync/mailer.py | 260 ++ plugins/ldap-user-sync/plugin.json | 8 + plugins/ldap-user-sync/plugin.py | 408 ++ plugins/ldap-user-sync/scheduler.py | 194 + plugins/ldap-user-sync/sync_engine.py | 195 + .../ldap-user-sync/vendor/ldap3/__init__.py | 150 + .../vendor/ldap3/abstract/__init__.py | 50 + .../vendor/ldap3/abstract/attrDef.py | 121 + .../vendor/ldap3/abstract/attribute.py | 290 ++ .../vendor/ldap3/abstract/cursor.py | 912 +++++ .../vendor/ldap3/abstract/entry.py | 712 ++++ .../vendor/ldap3/abstract/objectDef.py | 270 ++ .../vendor/ldap3/core/__init__.py | 0 .../vendor/ldap3/core/connection.py | 1605 ++++++++ .../vendor/ldap3/core/exceptions.py | 608 +++ .../vendor/ldap3/core/pooling.py | 329 ++ .../ldap-user-sync/vendor/ldap3/core/rdns.py | 68 + .../vendor/ldap3/core/results.py | 137 + .../vendor/ldap3/core/server.py | 682 ++++ .../vendor/ldap3/core/timezone.py | 56 + .../ldap-user-sync/vendor/ldap3/core/tls.py | 327 ++ .../ldap-user-sync/vendor/ldap3/core/usage.py | 229 ++ .../vendor/ldap3/extend/__init__.py | 334 ++ .../vendor/ldap3/extend/microsoft/__init__.py | 0 .../extend/microsoft/addMembersToGroups.py | 98 + .../vendor/ldap3/extend/microsoft/dirSync.py | 94 + .../ldap3/extend/microsoft/modifyPassword.py | 75 + .../extend/microsoft/persistentSearch.py | 117 + .../microsoft/removeMembersFromGroups.py | 99 + .../ldap3/extend/microsoft/unlockAccount.py | 57 + .../vendor/ldap3/extend/novell/__init__.py | 0 .../ldap3/extend/novell/addMembersToGroups.py | 167 + .../extend/novell/checkGroupsMemberships.py | 180 + .../ldap3/extend/novell/endTransaction.py | 58 + .../vendor/ldap3/extend/novell/getBindDn.py | 41 + .../ldap3/extend/novell/listReplicas.py | 50 + .../extend/novell/nmasGetUniversalPassword.py | 56 + .../extend/novell/nmasSetUniversalPassword.py | 52 + .../extend/novell/partition_entry_count.py | 57 + .../extend/novell/removeMembersFromGroups.py | 170 + .../vendor/ldap3/extend/novell/replicaInfo.py | 79 + .../ldap3/extend/novell/startTransaction.py | 56 + .../vendor/ldap3/extend/operation.py | 98 + .../ldap3/extend/standard/PagedSearch.py | 146 + .../ldap3/extend/standard/PersistentSearch.py | 137 + .../vendor/ldap3/extend/standard/__init__.py | 0 .../ldap3/extend/standard/modifyPassword.py | 72 + .../vendor/ldap3/extend/standard/whoAmI.py | 40 + .../vendor/ldap3/operation/__init__.py | 0 .../vendor/ldap3/operation/abandon.py | 36 + .../vendor/ldap3/operation/add.py | 72 + .../vendor/ldap3/operation/bind.py | 160 + .../vendor/ldap3/operation/compare.py | 64 + .../vendor/ldap3/operation/delete.py | 46 + .../vendor/ldap3/operation/extended.py | 109 + .../vendor/ldap3/operation/modify.py | 96 + .../vendor/ldap3/operation/modifyDn.py | 62 + .../vendor/ldap3/operation/search.py | 579 +++ .../vendor/ldap3/operation/unbind.py | 32 + .../vendor/ldap3/protocol/__init__.py | 0 .../vendor/ldap3/protocol/controls.py | 40 + .../vendor/ldap3/protocol/convert.py | 221 ++ .../ldap3/protocol/formatters/__init__.py | 0 .../ldap3/protocol/formatters/formatters.py | 436 +++ .../ldap3/protocol/formatters/standard.py | 238 ++ .../ldap3/protocol/formatters/validators.py | 502 +++ .../vendor/ldap3/protocol/microsoft.py | 142 + .../vendor/ldap3/protocol/novell.py | 141 + .../vendor/ldap3/protocol/oid.py | 1208 ++++++ .../vendor/ldap3/protocol/persistentSearch.py | 85 + .../vendor/ldap3/protocol/rfc2696.py | 70 + .../vendor/ldap3/protocol/rfc2849.py | 295 ++ .../vendor/ldap3/protocol/rfc3062.py | 91 + .../vendor/ldap3/protocol/rfc4511.py | 1007 +++++ .../vendor/ldap3/protocol/rfc4512.py | 850 +++++ .../vendor/ldap3/protocol/rfc4527.py | 57 + .../vendor/ldap3/protocol/sasl/__init__.py | 0 .../vendor/ldap3/protocol/sasl/digestMd5.py | 159 + .../vendor/ldap3/protocol/sasl/external.py | 32 + .../vendor/ldap3/protocol/sasl/kerberos.py | 302 ++ .../vendor/ldap3/protocol/sasl/plain.py | 70 + .../vendor/ldap3/protocol/sasl/sasl.py | 171 + .../vendor/ldap3/protocol/schemas/__init__.py | 0 .../vendor/ldap3/protocol/schemas/ad2012R2.py | 2232 +++++++++++ .../vendor/ldap3/protocol/schemas/ds389.py | 1715 +++++++++ .../vendor/ldap3/protocol/schemas/edir888.py | 1127 ++++++ .../vendor/ldap3/protocol/schemas/edir914.py | 1157 ++++++ .../vendor/ldap3/protocol/schemas/slapd24.py | 758 ++++ .../vendor/ldap3/strategy/__init__.py | 0 .../vendor/ldap3/strategy/asyncStream.py | 119 + .../vendor/ldap3/strategy/asynchronous.py | 292 ++ .../vendor/ldap3/strategy/base.py | 925 +++++ .../vendor/ldap3/strategy/ldifProducer.py | 152 + .../vendor/ldap3/strategy/mockAsync.py | 200 + .../vendor/ldap3/strategy/mockBase.py | 921 +++++ .../vendor/ldap3/strategy/mockSync.py | 133 + .../vendor/ldap3/strategy/restartable.py | 260 ++ .../vendor/ldap3/strategy/reusable.py | 495 +++ .../vendor/ldap3/strategy/safeRestartable.py | 32 + .../vendor/ldap3/strategy/safeSync.py | 32 + .../vendor/ldap3/strategy/sync.py | 251 ++ .../vendor/ldap3/utils/__init__.py | 0 .../ldap-user-sync/vendor/ldap3/utils/asn1.py | 245 ++ .../vendor/ldap3/utils/ciDict.py | 199 + .../vendor/ldap3/utils/config.py | 299 ++ .../ldap-user-sync/vendor/ldap3/utils/conv.py | 272 ++ .../ldap-user-sync/vendor/ldap3/utils/dn.py | 405 ++ .../vendor/ldap3/utils/hashed.py | 94 + .../ldap-user-sync/vendor/ldap3/utils/log.py | 216 ++ .../ldap-user-sync/vendor/ldap3/utils/ntlm.py | 505 +++ .../vendor/ldap3/utils/ordDict.py | 130 + .../vendor/ldap3/utils/port_validators.py | 37 + .../ldap-user-sync/vendor/ldap3/utils/repr.py | 51 + .../vendor/ldap3/utils/tls_backport.py | 133 + .../ldap-user-sync/vendor/ldap3/utils/uri.py | 118 + .../ldap-user-sync/vendor/ldap3/version.py | 13 + .../vendor/licenses/ldap3/COPYING.LESSER.txt | 165 + .../vendor/licenses/ldap3/COPYING.txt | 674 ++++ .../vendor/licenses/ldap3/LICENSE.txt | 13 + .../vendor/licenses/pyasn1/LICENSE.rst | 24 + .../ldap-user-sync/vendor/pyasn1/__init__.py | 2 + .../vendor/pyasn1/codec/__init__.py | 1 + .../vendor/pyasn1/codec/ber/__init__.py | 1 + .../vendor/pyasn1/codec/ber/decoder.py | 2236 +++++++++++ .../vendor/pyasn1/codec/ber/encoder.py | 954 +++++ .../vendor/pyasn1/codec/ber/eoo.py | 28 + .../vendor/pyasn1/codec/cer/__init__.py | 1 + .../vendor/pyasn1/codec/cer/decoder.py | 149 + .../vendor/pyasn1/codec/cer/encoder.py | 331 ++ .../vendor/pyasn1/codec/der/__init__.py | 1 + .../vendor/pyasn1/codec/der/decoder.py | 120 + .../vendor/pyasn1/codec/der/encoder.py | 126 + .../vendor/pyasn1/codec/native/__init__.py | 1 + .../vendor/pyasn1/codec/native/decoder.py | 244 ++ .../vendor/pyasn1/codec/native/encoder.py | 285 ++ .../vendor/pyasn1/codec/streaming.py | 234 ++ .../vendor/pyasn1/compat/__init__.py | 4 + .../vendor/pyasn1/compat/integer.py | 13 + plugins/ldap-user-sync/vendor/pyasn1/debug.py | 146 + plugins/ldap-user-sync/vendor/pyasn1/error.py | 116 + .../vendor/pyasn1/type/__init__.py | 1 + .../ldap-user-sync/vendor/pyasn1/type/base.py | 699 ++++ .../ldap-user-sync/vendor/pyasn1/type/char.py | 288 ++ .../vendor/pyasn1/type/constraint.py | 751 ++++ .../vendor/pyasn1/type/error.py | 11 + .../vendor/pyasn1/type/namedtype.py | 550 +++ .../vendor/pyasn1/type/namedval.py | 192 + .../vendor/pyasn1/type/opentype.py | 104 + .../ldap-user-sync/vendor/pyasn1/type/tag.py | 347 ++ .../vendor/pyasn1/type/tagmap.py | 96 + .../ldap-user-sync/vendor/pyasn1/type/univ.py | 3338 +++++++++++++++++ .../vendor/pyasn1/type/useful.py | 190 + plugins/ldap-user-sync/xc_password.py | 20 + 157 files changed, 43664 insertions(+) create mode 100644 plugins/ldap-user-sync/README.md create mode 100644 plugins/ldap-user-sync/__init__.py create mode 100644 plugins/ldap-user-sync/_ldap_user_sync_durable/__init__.py create mode 100644 plugins/ldap-user-sync/ldap_client.py create mode 100644 plugins/ldap-user-sync/mailer.py create mode 100644 plugins/ldap-user-sync/plugin.json create mode 100644 plugins/ldap-user-sync/plugin.py create mode 100644 plugins/ldap-user-sync/scheduler.py create mode 100644 plugins/ldap-user-sync/sync_engine.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/attrDef.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/attribute.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/cursor.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/entry.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/abstract/objectDef.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/connection.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/exceptions.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/pooling.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/rdns.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/results.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/server.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/timezone.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/tls.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/core/usage.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/addMembersToGroups.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/dirSync.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/modifyPassword.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/persistentSearch.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/removeMembersFromGroups.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/unlockAccount.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/addMembersToGroups.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/checkGroupsMemberships.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/endTransaction.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/getBindDn.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/listReplicas.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasGetUniversalPassword.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasSetUniversalPassword.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/partition_entry_count.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/removeMembersFromGroups.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/replicaInfo.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/novell/startTransaction.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/operation.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/standard/PagedSearch.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/standard/PersistentSearch.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/standard/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/standard/modifyPassword.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/extend/standard/whoAmI.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/abandon.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/add.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/bind.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/compare.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/delete.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/extended.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/modify.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/modifyDn.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/search.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/operation/unbind.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/controls.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/convert.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/formatters.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/standard.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/validators.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/microsoft.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/novell.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/oid.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/persistentSearch.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2696.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2849.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc3062.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4511.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4512.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4527.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/external.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/kerberos.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/plain.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/sasl.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ad2012R2.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ds389.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir888.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir914.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/slapd24.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/asyncStream.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/asynchronous.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/base.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/ldifProducer.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/mockAsync.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/mockBase.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/mockSync.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/restartable.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/reusable.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/safeRestartable.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/safeSync.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/strategy/sync.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/asn1.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/ciDict.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/config.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/conv.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/dn.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/hashed.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/log.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/ordDict.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/port_validators.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/repr.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/tls_backport.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/uri.py create mode 100644 plugins/ldap-user-sync/vendor/ldap3/version.py create mode 100644 plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.LESSER.txt create mode 100644 plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.txt create mode 100644 plugins/ldap-user-sync/vendor/licenses/ldap3/LICENSE.txt create mode 100644 plugins/ldap-user-sync/vendor/licenses/pyasn1/LICENSE.rst create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/ber/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/ber/decoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/ber/encoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/ber/eoo.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/cer/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/cer/decoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/cer/encoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/der/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/der/decoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/der/encoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/native/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/native/decoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/native/encoder.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/codec/streaming.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/compat/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/compat/integer.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/debug.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/error.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/__init__.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/base.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/char.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/constraint.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/error.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/namedtype.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/namedval.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/opentype.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/tag.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/tagmap.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/univ.py create mode 100644 plugins/ldap-user-sync/vendor/pyasn1/type/useful.py create mode 100644 plugins/ldap-user-sync/xc_password.py diff --git a/plugins/ldap-user-sync/README.md b/plugins/ldap-user-sync/README.md new file mode 100644 index 00000000..0240339f --- /dev/null +++ b/plugins/ldap-user-sync/README.md @@ -0,0 +1,86 @@ +# LDAP User Sync + +Syncs Dispatcharr user accounts from any standard LDAP directory (Active +Directory, OpenLDAP, 389 Directory Server, Authentik's LDAP outpost, +etc.) based on group membership. + +## What it does + +- Binds to your LDAP directory (on a schedule and/or on demand) and reads + the members of two group DNs you configure: an **Admin** group and a + **Streamer** group. +- Creates or updates the matching Dispatcharr users, setting `user_level` + to Admin (`10`) or Streamer (`0`). Users in neither group are never + created or touched. +- Generates a random **Xtream Codes (XC) API password** for every newly + created user (the secret your IPTV client apps use — separate from the + Dispatcharr login password) and emails it via plain SMTP. Existing + users keep their XC password stable across future syncs; use the + **Reset XC Password** action to rotate one on demand. +- Disables (`is_active=False`) any previously-synced user who drops out + of both groups on a later sync (toggle-able). +- Optionally enables true **LDAP pass-through login**, so a user's + Dispatcharr login password always matches their live LDAP password + (see below for how this works and its limitations). + +## LDAP pass-through login + +We cannot read a user's plaintext LDAP password via a service-account +bind — no LDAP server exposes it. So the only way to make a Dispatcharr +login "match LDAP" is live pass-through authentication, not password +mirroring: + +- LDAP-managed users get `set_unusable_password()` locally — their local + Dispatcharr password is deterministically disabled. +- When **Enable LDAP pass-through login** is on, a custom Django + authentication backend attempts a live SIMPLE bind against your LDAP + server using the DN captured at the most recent sync and the password + the user typed in. Django's standard `ModelBackend` is tried first, so + non-LDAP accounts (e.g. a local break-glass admin) are unaffected. + +**Accepted limitations, by design:** +- If your LDAP server is unreachable, LDAP-managed users cannot log in + until it's back — there's no local fallback for them. To restore local + login for one user in an emergency, clear their + `custom_properties["ldap_synced"]`/`["ldap_dn"]` and call + `set_password()` directly (Django shell / admin). +- Nested/recursive group membership is not expanded — a user must be a + *direct* member of the configured group DN. +- If you fully uninstall this plugin, restart Dispatcharr afterward. + Django's authentication backend list isn't designed to be mutated at + runtime, so an already-running process keeps a reference to the + now-removed backend module until it restarts (it fails safely, closed, + in the meantime — it just won't clean itself up without a restart). + +## Vendored dependencies + +Dispatcharr plugins run inside the app's existing Python environment +with no dependency-installation step, and neither `ldap3` nor +`python-ldap` ships with Dispatcharr. This plugin vendors, unmodified, +as plain Python source under `vendor/`: + +- [`ldap3`](https://pypi.org/project/ldap3/) 2.9.1 — LGPL-3.0-only. + Full license text: `vendor/licenses/ldap3/`. +- [`pyasn1`](https://pypi.org/project/pyasn1/) 0.6.4 — BSD-2-Clause. + Full license text: `vendor/licenses/pyasn1/LICENSE.rst`. + +Both are pure Python with no compiled extensions. They are vendored as +clearly-separable, unmodified source trees with their original license +text preserved, satisfying LGPL's combination terms. This plugin's own +code is MIT-licensed; the vendored libraries keep their original +licenses regardless. + +## Settings reference + +See the in-app field descriptions (grouped into LDAP Connection, Group → +Role Mapping, User Attribute Mapping, Sync Behavior, Pass-Through Login, +XC Password, and SMTP sections). A couple worth calling out: + +- **Group Member Attribute**: `member` works for `groupOfNames`-style + groups (the common case, including AD and Authentik). Set it to + `uniqueMember` for `groupOfUniqueNames`, or turn on **Group lists + usernames, not DNs** and set it to `memberUid` for `posixGroup`-style + directories. +- **Dry Run Mode**: turn this on for your first sync against a real + directory — it logs exactly what would be created/updated/disabled + without writing anything. diff --git a/plugins/ldap-user-sync/__init__.py b/plugins/ldap-user-sync/__init__.py new file mode 100644 index 00000000..7d7931aa --- /dev/null +++ b/plugins/ldap-user-sync/__init__.py @@ -0,0 +1,3 @@ +from .plugin import Plugin + +__all__ = ["Plugin"] diff --git a/plugins/ldap-user-sync/_ldap_user_sync_durable/__init__.py b/plugins/ldap-user-sync/_ldap_user_sync_durable/__init__.py new file mode 100644 index 00000000..368aafc9 --- /dev/null +++ b/plugins/ldap-user-sync/_ldap_user_sync_durable/__init__.py @@ -0,0 +1,96 @@ +"""Standalone home for `LDAPPassthroughBackend`, kept out of `plugin.py`. + +`apps.plugins.loader.PluginManager._unload_package()` evicts every +`sys.modules` entry under the plugin's synthetic package name whenever +the plugin is disabled or force-reloaded. If this backend lived inside +`plugin.py` itself, Django's `AUTHENTICATION_BACKENDS` would hold a +dotted path that stops resolving the moment that happens, breaking the +very next login attempt that reaches it. + +This package is deliberately independent: `plugin.py` inserts the +plugin's own folder (not just `vendor/`) onto `sys.path`, so this module +stays importable via normal filesystem lookup even after a +`sys.modules` eviction — a cache eviction just means Python re-imports a +fresh copy from disk instead of failing. It re-does its own `vendor/` +bootstrap below so it never depends on `plugin.py` having already run in +the current call stack. + +The name is deliberately unique/underscore-prefixed to avoid colliding +with other plugins' same-named generic helper modules (several ship +their own `utils.py`/`config.py`) now that this plugin's own folder is +on `sys.path`. +""" + +import os +import sys + +_PLUGIN_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +_VENDOR_DIR = os.path.join(_PLUGIN_DIR, "vendor") +if _VENDOR_DIR not in sys.path: + sys.path.insert(0, _VENDOR_DIR) +if _PLUGIN_DIR not in sys.path: + sys.path.insert(0, _PLUGIN_DIR) + +from ldap3.core.exceptions import LDAPException # noqa: E402 + + +def _current_settings(): + """Read the plugin's live persisted settings straight from PluginConfig. + + Deliberately independent of plugin.py's own settings helper for the + same reload-durability reason described above. + """ + from apps.plugins.models import PluginConfig + + plugin_key = os.path.basename(_PLUGIN_DIR).replace(" ", "_").lower() + try: + return PluginConfig.objects.get(key=plugin_key).settings or {} + except PluginConfig.DoesNotExist: + return {} + + +class LDAPPassthroughBackend: + """Optional live LDAP bind-as-user authentication, opt-in per settings.""" + + def authenticate(self, request, username=None, password=None, **kwargs): + if not username or not password: + return None + + from apps.accounts.models import User + + try: + settings = _current_settings() + if not settings.get("enable_ldap_passthrough_login"): + return None + + user = User.objects.get(username=username, is_active=True) + custom_properties = user.custom_properties or {} + if not custom_properties.get("ldap_synced"): + return None + dn = custom_properties.get("ldap_dn") + if not dn: + return None + + # Import lazily so a broken vendor/import never breaks the + # ModelBackend path for every other login attempt. + from ldap_client import verify_user_credentials # noqa: PLC0415 + + if verify_user_credentials(settings, dn, password): + return user + return None + except User.DoesNotExist: + return None + except LDAPException: + return None + except Exception: + # A flaky/down directory or unexpected error must degrade to + # "this backend says no", never to an unhandled 500 on login. + return None + + def get_user(self, user_id): + from apps.accounts.models import User + + try: + return User.objects.get(pk=user_id) + except User.DoesNotExist: + return None diff --git a/plugins/ldap-user-sync/ldap_client.py b/plugins/ldap-user-sync/ldap_client.py new file mode 100644 index 00000000..62c2e678 --- /dev/null +++ b/plugins/ldap-user-sync/ldap_client.py @@ -0,0 +1,188 @@ +"""Generic LDAP directory access for the LDAP User Sync plugin. + +Uses the vendored ``ldap3``/``pyasn1`` (see ``vendor/``) since Dispatcharr +plugins run inside the app's existing Python environment with no +dependency-installation step, and neither library ships with Dispatcharr. + +Deliberately vendor-agnostic: no assumptions about Active Directory, +OpenLDAP, or any specific product (including Authentik's LDAP outpost, +which this plugin was developed and tested against, but never hardcodes +to). +""" + +import os +import re +import ssl +import sys + +_PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__)) +_VENDOR_DIR = os.path.join(_PLUGIN_DIR, "vendor") +if _VENDOR_DIR not in sys.path: + sys.path.insert(0, _VENDOR_DIR) + +import ldap3 # noqa: E402 +from ldap3 import ALL, BASE, SIMPLE, SUBTREE, Connection, Server, Tls # noqa: E402 +from ldap3.core.exceptions import LDAPException # noqa: E402 + +_USERNAME_RE = re.compile(r"[^\w.@+-]") + + +class LDAPConnectionError(Exception): + """Raised for any LDAP connect/bind/search failure, wrapping the underlying cause.""" + + +def sanitize_username(raw): + """Reduce an LDAP attribute value to Django's allowed username charset.""" + value = (raw or "").strip() + return _USERNAME_RE.sub("_", value) + + +def _build_server(settings): + host = (settings.get("ldap_host") or "").strip() + if not host: + raise LDAPConnectionError("LDAP host is not configured") + try: + port = int(settings.get("ldap_port") or 389) + except (TypeError, ValueError): + port = 389 + encryption = settings.get("ldap_encryption") or "starttls" + + tls = None + if encryption in ("starttls", "ldaps"): + ca_pem = (settings.get("ldap_ca_cert_pem") or "").strip() or None + tls = Tls( + validate=ssl.CERT_REQUIRED, + version=ssl.PROTOCOL_TLS_CLIENT, + ca_certs_data=ca_pem, + ) + + return Server( + host, + port=port, + use_ssl=(encryption == "ldaps"), + tls=tls, + get_info=ALL, + connect_timeout=10, + ), encryption + + +def connect_service_account(settings): + """Bind as the configured service account. Raises LDAPConnectionError on any failure.""" + server, encryption = _build_server(settings) + bind_dn = (settings.get("ldap_bind_dn") or "").strip() + bind_password = settings.get("ldap_bind_password") or "" + + try: + conn = Connection( + server, + user=bind_dn or None, + password=bind_password or None, + authentication=SIMPLE if bind_dn else None, + auto_bind=False, + receive_timeout=10, + ) + if encryption == "starttls": + if not conn.open() or not conn.start_tls(): + raise LDAPConnectionError(f"STARTTLS negotiation failed: {conn.result}") + if not conn.bind(): + raise LDAPConnectionError(f"LDAP bind failed: {conn.result}") + except LDAPException as exc: + raise LDAPConnectionError(f"LDAP connection error: {exc}") from exc + + return conn + + +def verify_user_credentials(settings, dn, password): + """Attempt a SIMPLE bind as `dn`/`password` on a fresh connection. Never raises.""" + if not dn or not password: + return False + try: + server, encryption = _build_server(settings) + conn = Connection( + server, + user=dn, + password=password, + authentication=SIMPLE, + auto_bind=False, + receive_timeout=10, + ) + if encryption == "starttls": + if not conn.open() or not conn.start_tls(): + return False + return bool(conn.bind()) + except Exception: + return False + + +def resolve_group_members(conn, settings, group_dn): + """Return the raw list of member values (DNs, or usernames) for a group entry.""" + if not group_dn: + return [] + member_attr = settings.get("ldap_group_member_attribute") or "member" + ok = conn.search( + search_base=group_dn, + search_filter="(objectClass=*)", + search_scope=BASE, + attributes=[member_attr], + ) + if not ok or not conn.entries: + return [] + entry = conn.entries[0] + if member_attr not in entry: + return [] + values = entry[member_attr].values + return [str(v) for v in values] + + +def fetch_user_by_dn(conn, dn, settings): + """Look up a single user entry by DN. Returns a normalized dict or None if stale.""" + attrs = [ + settings.get("ldap_username_attribute") or "uid", + settings.get("ldap_email_attribute") or "mail", + settings.get("ldap_first_name_attribute") or "givenName", + settings.get("ldap_last_name_attribute") or "sn", + ] + ok = conn.search(search_base=dn, search_filter="(objectClass=*)", search_scope=BASE, attributes=attrs) + if not ok or not conn.entries: + return None + return _normalize_entry(conn.entries[0], dn, settings) + + +def fetch_user_by_username(conn, settings, username): + """Look up a single user entry by username attribute under the base DN.""" + base_dn = (settings.get("ldap_base_dn") or "").strip() + username_attr = settings.get("ldap_username_attribute") or "uid" + attrs = [ + username_attr, + settings.get("ldap_email_attribute") or "mail", + settings.get("ldap_first_name_attribute") or "givenName", + settings.get("ldap_last_name_attribute") or "sn", + ] + escaped = ldap3.utils.conv.escape_filter_chars(username) + ok = conn.search( + search_base=base_dn, + search_filter=f"({username_attr}={escaped})", + search_scope=SUBTREE, + attributes=attrs, + ) + if not ok or not conn.entries: + return None + entry = conn.entries[0] + return _normalize_entry(entry, str(entry.entry_dn), settings) + + +def _first(entry, attr): + if attr not in entry: + return "" + values = entry[attr].values + return str(values[0]) if values else "" + + +def _normalize_entry(entry, dn, settings): + return { + "dn": dn, + "username": sanitize_username(_first(entry, settings.get("ldap_username_attribute") or "uid")), + "email": _first(entry, settings.get("ldap_email_attribute") or "mail"), + "first_name": _first(entry, settings.get("ldap_first_name_attribute") or "givenName"), + "last_name": _first(entry, settings.get("ldap_last_name_attribute") or "sn"), + } diff --git a/plugins/ldap-user-sync/mailer.py b/plugins/ldap-user-sync/mailer.py new file mode 100644 index 00000000..6b8392b2 --- /dev/null +++ b/plugins/ldap-user-sync/mailer.py @@ -0,0 +1,260 @@ +"""Plain-SMTP email delivery for the LDAP User Sync plugin. + +Dispatcharr core has no outbound email support of its own (no +``EMAIL_*`` settings, no ``django.core.mail`` usage anywhere in the app), +so this follows the same stdlib ``smtplib``/``ssl``/``email.mime`` +pattern already established by the merged ``m3u-expiration-notifier`` +plugin, reading every credential from plugin settings (never hardcoded) +and always verifying certificates via ``ssl.create_default_context()``. +The HTML email template below mirrors that plugin's layout/styling +(same brand bar, accent stripe, and detail-row table) for a consistent +look across Dispatcharr plugin notification emails. +""" + +import smtplib +import ssl +from email.mime.image import MIMEImage +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from html import escape as html_escape + +LOGO_PATH = "/app/frontend/dist/logo.png" +BRAND_DARK = "#1a1b1e" +ACCENT = "#2f9e44" + +_LOGO_CACHE = {"loaded": False, "bytes": None} + + +def _load_logo_bytes(): + if not _LOGO_CACHE["loaded"]: + try: + with open(LOGO_PATH, "rb") as fh: + _LOGO_CACHE["bytes"] = fh.read() + except OSError: + _LOGO_CACHE["bytes"] = None + _LOGO_CACHE["loaded"] = True + return _LOGO_CACHE["bytes"] + + +def resolve_smtp_params(settings): + host = (settings.get("smtp_host") or "").strip() + if not host: + raise ValueError("SMTP host is not configured") + try: + port = int(settings.get("smtp_port") or 587) + except (TypeError, ValueError): + port = 587 + security = settings.get("smtp_security") or "starttls" + username = (settings.get("smtp_username") or "").strip() + password = settings.get("smtp_password") or "" + from_addr = (settings.get("smtp_from_email") or username or "").strip() + if not from_addr: + raise ValueError("No From address available (set SMTP Username or From Address)") + return { + "host": host, + "port": port, + "security": security, + "username": username, + "password": password, + "from_addr": from_addr, + } + + +def _render_email_html(heading, status_label, accent_color, message_html, detail_rows): + logo_bytes = _load_logo_bytes() + if logo_bytes: + brand_html = ( + 'Dispatcharr' + ) + else: + brand_html = ( + 'DISPATCHARR' + ) + + rows_html = "".join( + f''' + {html_escape(label)} + {value_html} + ''' + for label, value_html, extra_style in detail_rows + ) + + return f''' + + + + + + +
+ + + + + + + + + + + + + +
{brand_html}
 
+

{html_escape(heading)}

+

{html_escape(status_label)}

+

{message_html}

+ {rows_html}
+
+

+ Sent by the LDAP User Sync plugin for Dispatcharr. +

+
+
+ +''' + + +def _render_email_text(heading, status_label, message_text, detail_rows): + lines = [f"{heading} - {status_label}", ""] + lines.append(message_text) + lines.append("") + for label, value_html, _extra_style in detail_rows: + lines.append(f"{label}: {value_html}") + lines.append("") + lines.append("Sent by the LDAP User Sync plugin for Dispatcharr.") + return "\n".join(lines) + + +def build_message(subject, from_addr, recipients, html_body, text_body): + msg_root = MIMEMultipart("related") + msg_root["Subject"] = subject + msg_root["From"] = from_addr + msg_root["To"] = ", ".join(recipients) + + msg_alt = MIMEMultipart("alternative") + msg_alt.attach(MIMEText(text_body, "plain", "utf-8")) + msg_alt.attach(MIMEText(html_body, "html", "utf-8")) + msg_root.attach(msg_alt) + + logo_bytes = _load_logo_bytes() + if logo_bytes: + img = MIMEImage(logo_bytes, _subtype="png") + img.add_header("Content-ID", "") + img.add_header("Content-Disposition", "inline") + msg_root.attach(img) + + return msg_root + + +def deliver_message(params, recipients, msg=None): + """Connect, authenticate, and optionally send `msg`. Pass msg=None to just test the login.""" + if not recipients: + raise ValueError("No recipient email address given") + + if params["security"] == "ssl": + server = smtplib.SMTP_SSL( + params["host"], params["port"], timeout=30, context=ssl.create_default_context() + ) + else: + server = smtplib.SMTP(params["host"], params["port"], timeout=30) + + with server: + if params["security"] == "starttls": + # Deliberately hard-fails if the server doesn't advertise STARTTLS + # rather than silently falling back to plaintext - that fallback + # is exactly the STARTTLS-stripping downgrade an attacker on-path + # would try to induce. Use "none" explicitly for servers that + # genuinely never support TLS (e.g. a trusted internal relay). + server.starttls(context=ssl.create_default_context()) + if params["username"]: + server.login(params["username"], params["password"]) + if msg is not None: + server.sendmail(params["from_addr"], recipients, msg.as_string()) + + +def send_xc_password_email(settings, recipient, username, xc_password): + params = resolve_smtp_params(settings) + public_url = (settings.get("public_url") or "").strip() + + message_text = "Your Dispatcharr Xtream Codes API password has been set." + message_html = ( + "Use these credentials in your IPTV client app - this is separate " + "from your Dispatcharr login password." + ) + detail_rows = [ + ("Username", html_escape(username), ""), + ( + "XC Password", + html_escape(xc_password), + "font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;", + ), + ] + + text_lines = [message_text, "", f"Username: {username}", f"XC Password: {xc_password}"] + if public_url: + message_html += f' Point your IPTV client app at {html_escape(public_url)}.' + text_lines += ["", f"Point your IPTV client app at: {public_url}"] + + html_body = _render_email_html( + heading="Your Xtream Codes password is ready", + status_label="Account Provisioned", + accent_color=ACCENT, + message_html=message_html, + detail_rows=detail_rows, + ) + text_body = _render_email_text( + heading="Your Xtream Codes password is ready", + status_label="Account Provisioned", + message_text="\n".join(text_lines), + detail_rows=[], + ) + + msg = build_message( + subject="[Dispatcharr] Your Xtream Codes API password", + from_addr=params["from_addr"], + recipients=[recipient], + html_body=html_body, + text_body=text_body, + ) + deliver_message(params, [recipient], msg) + + +def send_test_email(settings, recipient): + params = resolve_smtp_params(settings) + html_body = _render_email_html( + heading="Test email", + status_label="LDAP User Sync", + accent_color=ACCENT, + message_html="This is a test email from the LDAP User Sync plugin's SMTP settings. " + "If you can read this, delivery is working.", + detail_rows=[], + ) + text_body = _render_email_text( + heading="Test email", + status_label="LDAP User Sync", + message_text="This is a test email from the LDAP User Sync plugin's SMTP settings.", + detail_rows=[], + ) + msg = build_message( + subject="[Dispatcharr] LDAP User Sync test email", + from_addr=params["from_addr"], + recipients=[recipient], + html_body=html_body, + text_body=text_body, + ) + deliver_message(params, [recipient], msg) + + +def validate_smtp_connection(settings): + params = resolve_smtp_params(settings) + deliver_message(params, [params["from_addr"]], msg=None) diff --git a/plugins/ldap-user-sync/plugin.json b/plugins/ldap-user-sync/plugin.json new file mode 100644 index 00000000..388d8bb0 --- /dev/null +++ b/plugins/ldap-user-sync/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "LDAP User Sync", + "version": "1.0.0", + "description": "Syncs Dispatcharr user accounts from any standard LDAP directory (Active Directory, OpenLDAP, 389 Directory Server, Authentik's LDAP outpost, etc.). On a configurable schedule or on demand, binds to your directory, finds members of two configurable group DNs, and creates/updates the matching Dispatcharr users as Admins or Streamers, disabling accounts that fall out of both groups. Generates and emails a random Xtream Codes API password for each newly created user via plain SMTP, with a manual per-user reset action. Optionally enables true LDAP pass-through login so a user's Dispatcharr login password always matches their live LDAP password.", + "author": "ModdingFriendly", + "license": "MIT", + "min_dispatcharr_version": "v0.20.0" +} diff --git a/plugins/ldap-user-sync/plugin.py b/plugins/ldap-user-sync/plugin.py new file mode 100644 index 00000000..42ff1adf --- /dev/null +++ b/plugins/ldap-user-sync/plugin.py @@ -0,0 +1,408 @@ +import logging +import os +import sys + +_PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__)) +_VENDOR_DIR = os.path.join(_PLUGIN_DIR, "vendor") +if _VENDOR_DIR not in sys.path: + sys.path.insert(0, _VENDOR_DIR) +if _PLUGIN_DIR not in sys.path: + sys.path.insert(0, _PLUGIN_DIR) + +import mailer # noqa: E402 +import scheduler # noqa: E402 +import sync_engine # noqa: E402 +from ldap_client import LDAPConnectionError # noqa: E402 + +# All cross-file imports in this plugin are absolute top-level imports (not +# `from . import ...`), relying on the sys.path insertion above. This keeps a +# single canonical module instance per file across the whole plugin — mixing +# absolute and relative imports of the same file would create two separate +# module objects (and, critically, two distinct `LDAPConnectionError` class +# objects that would fail `isinstance`/`except` checks against each other). + +LOGGER = logging.getLogger(__name__) + +_PLUGIN_KEY = os.path.basename(_PLUGIN_DIR).replace(" ", "_").lower() +_AUTH_BACKEND_PATH = "_ldap_user_sync_durable.LDAPPassthroughBackend" + + +class Plugin: + name = "LDAP User Sync" + version = "1.0.0" + description = ( + "Syncs Dispatcharr Admin/Streamer accounts from any standard LDAP " + "directory based on group membership, provisions and emails a " + "random Xtream Codes API password per user, and optionally enables " + "live LDAP pass-through login." + ) + author = "ModdingFriendly" + + fields = [ + {"id": "info_ldap_connection", "type": "info", "label": "LDAP Directory Connection"}, + { + "id": "ldap_host", + "type": "string", + "label": "LDAP Host", + "default": "", + "help_text": "Hostname or IP of your LDAP server. Works with any standard LDAP " + "directory (OpenLDAP, Active Directory, 389 Directory Server, Authentik's LDAP " + "outpost, etc.) — no vendor-specific assumptions.", + }, + { + "id": "ldap_port", + "type": "number", + "label": "LDAP Port", + "default": 389, + "help_text": "Typically 389 (plain/STARTTLS) or 636 (implicit LDAPS).", + }, + { + "id": "ldap_encryption", + "type": "select", + "label": "Encryption", + "default": "starttls", + "options": [ + {"label": "None (not recommended)", "value": "plain"}, + {"label": "STARTTLS", "value": "starttls"}, + {"label": "LDAPS (implicit TLS)", "value": "ldaps"}, + ], + }, + { + "id": "ldap_ca_cert_pem", + "type": "text", + "label": "Custom CA Certificate (PEM)", + "default": "", + "help_text": "Optional. Paste a PEM-encoded CA certificate if your LDAP server " + "uses a private/internal CA. Certificate verification is always enforced — use " + "this instead of disabling it.", + }, + { + "id": "ldap_bind_dn", + "type": "string", + "label": "Bind DN", + "default": "", + "help_text": "Full DN of the service account used to search the directory, e.g. " + "cn=svc-dispatcharr,ou=service-accounts,dc=example,dc=com.", + }, + { + "id": "ldap_bind_password", + "type": "string", + "label": "Bind Password", + "default": "", + "input_type": "password", + }, + { + "id": "ldap_base_dn", + "type": "string", + "label": "Base DN", + "default": "", + "help_text": "e.g. dc=example,dc=com. Used as the default user search base.", + }, + {"id": "info_group_mapping", "type": "info", "label": "Group -> Role Mapping"}, + { + "id": "ldap_admin_group_dn", + "type": "string", + "label": "Admin Group DN", + "default": "", + "help_text": "Members become Dispatcharr Admins (user_level=10).", + }, + { + "id": "ldap_streamer_group_dn", + "type": "string", + "label": "Streamer Group DN", + "default": "", + "help_text": "Members become Dispatcharr Streamers (user_level=0). Users in " + "neither group are never created or touched.", + }, + { + "id": "ldap_group_member_attribute", + "type": "string", + "label": "Group Member Attribute", + "default": "member", + "help_text": "Use 'member' (groupOfNames, AD, Authentik) or 'uniqueMember' " + "(groupOfUniqueNames).", + }, + { + "id": "ldap_group_member_is_username", + "type": "boolean", + "label": "Group lists usernames, not DNs", + "default": False, + "help_text": "Turn ON only for posixGroup-style directories where 'memberUid' " + "stores raw usernames instead of full DNs (set the attribute above to memberUid).", + }, + {"id": "info_user_attributes", "type": "info", "label": "User Attribute Mapping"}, + {"id": "ldap_username_attribute", "type": "string", "label": "Username Attribute", "default": "uid"}, + {"id": "ldap_email_attribute", "type": "string", "label": "Email Attribute", "default": "mail"}, + { + "id": "ldap_first_name_attribute", + "type": "string", + "label": "First Name Attribute", + "default": "givenName", + }, + {"id": "ldap_last_name_attribute", "type": "string", "label": "Last Name Attribute", "default": "sn"}, + {"id": "info_sync_behavior", "type": "info", "label": "Sync Behavior"}, + { + "id": "sync_interval_minutes", + "type": "number", + "label": "Sync Interval (minutes)", + "default": 60, + "help_text": "0 disables the automatic schedule — 'Sync Now' is always available " + "regardless. Click 'Apply Schedule' after changing this.", + }, + { + "id": "disable_users_removed_from_groups", + "type": "boolean", + "label": "Disable users removed from groups", + "default": True, + "help_text": "When ON, a previously-synced user no longer in either LDAP group " + "gets is_active=False on the next sync.", + }, + { + "id": "dry_run_mode", + "type": "boolean", + "label": "Dry Run Mode", + "default": False, + "help_text": "Log what would change without writing anything. Recommended the " + "first time you point this at a real directory.", + }, + {"id": "info_login_passthrough", "type": "info", "label": "LDAP Pass-Through Login (Advanced)"}, + { + "id": "enable_ldap_passthrough_login", + "type": "boolean", + "label": "Enable LDAP pass-through login", + "default": False, + "help_text": "When ON, LDAP-synced users authenticate against a live LDAP bind at " + "login time instead of a locally stored password, so their Dispatcharr login " + "always matches their current LDAP password. See the plugin README for the full " + "design and limitations (e.g. login requires LDAP to be reachable).", + }, + {"id": "info_xc_password", "type": "info", "label": "Xtream Codes API Password"}, + { + "id": "xc_password_length", + "type": "number", + "label": "XC Password Length", + "default": 24, + }, + { + "id": "public_url", + "type": "string", + "label": "Public Dispatcharr/Xtream URL", + "default": "", + "help_text": "Optional. Included in the notification email.", + }, + { + "id": "reset_xc_password_for_username", + "type": "string", + "label": "Username to reset XC password for", + "default": "", + "help_text": "Fill this in, then click 'Reset XC Password' below.", + }, + {"id": "info_smtp", "type": "info", "label": "SMTP Email Delivery"}, + {"id": "smtp_host", "type": "string", "label": "SMTP Host", "default": ""}, + {"id": "smtp_port", "type": "number", "label": "SMTP Port", "default": 587}, + { + "id": "smtp_security", + "type": "select", + "label": "SMTP Security", + "default": "starttls", + "help_text": "Use 'None' only for a trusted internal relay with no TLS support " + "(e.g. one only reachable from inside your own private network).", + "options": [ + {"label": "STARTTLS", "value": "starttls"}, + {"label": "SSL/TLS", "value": "ssl"}, + {"label": "None (trusted internal relay only)", "value": "none"}, + ], + }, + {"id": "smtp_username", "type": "string", "label": "SMTP Username", "default": ""}, + { + "id": "smtp_password", + "type": "string", + "label": "SMTP Password", + "default": "", + "input_type": "password", + }, + { + "id": "smtp_from_email", + "type": "string", + "label": "From Address", + "default": "", + "help_text": "Optional. Falls back to SMTP Username.", + }, + { + "id": "test_email_recipient", + "type": "string", + "label": "Test Email Recipient", + "default": "", + }, + ] + + actions = [ + { + "id": "test_ldap_connection", + "label": "Test LDAP Connection", + "description": "Bind and resolve both group DNs without changing anything", + "button_label": "Test LDAP Connection", + "button_variant": "outline", + "button_color": "blue", + }, + { + "id": "sync_now", + "label": "Sync Now", + "description": "Run the full LDAP sync immediately", + "button_label": "Sync Now", + "button_variant": "filled", + "button_color": "blue", + }, + { + "id": "test_smtp_connection", + "label": "Test SMTP Connection", + "description": "Verify SMTP login without sending a message", + "button_label": "Test SMTP Connection", + "button_variant": "outline", + }, + { + "id": "send_test_email", + "label": "Send Test Email", + "description": "Send a real test email to the address configured above", + "button_label": "Send Test Email", + "button_variant": "outline", + }, + { + "id": "reset_xc_password_for_username", + "label": "Reset XC Password", + "description": "Rotate and email a new Xtream Codes password for the username above", + "button_label": "Reset XC Password", + "button_variant": "filled", + "button_color": "red", + "confirm": { + "title": "Reset XC password?", + "message": "This immediately invalidates the current Xtream Codes password " + "for this user and emails them a new one. Continue?", + }, + }, + { + "id": "apply_schedule", + "label": "Apply Schedule", + "description": "Restart the sync countdown using the current interval setting", + "button_label": "Apply Schedule", + "button_variant": "outline", + }, + { + "id": "scheduler_status", + "label": "Scheduler Status", + "description": "Report the next scheduled sync time", + "button_label": "Scheduler Status", + "button_variant": "outline", + }, + ] + + def __init__(self): + self._register_auth_backend() + self._scheduler = scheduler.Scheduler( + get_settings=self._current_settings, run_sync_fn=sync_engine.run_sync, logger=LOGGER + ) + self._scheduler.start() + + def _register_auth_backend(self): + from django.conf import settings as dj_settings + + if _AUTH_BACKEND_PATH not in dj_settings.AUTHENTICATION_BACKENDS: + dj_settings.AUTHENTICATION_BACKENDS = list(dj_settings.AUTHENTICATION_BACKENDS) + [ + _AUTH_BACKEND_PATH + ] + + def _current_settings(self): + from apps.plugins.models import PluginConfig + + try: + settings = dict(PluginConfig.objects.get(key=_PLUGIN_KEY).settings or {}) + except PluginConfig.DoesNotExist: + settings = {} + for field in self.fields: + field_id = field.get("id") + if field_id and field_id not in settings and "default" in field: + settings[field_id] = field["default"] + return settings + + # -- actions ------------------------------------------------------------- + + def _test_ldap_connection(self, settings, logger): + result = sync_engine.preview_groups(settings, logger) + return { + "status": "success", + "message": ( + f"LDAP bind succeeded. {result['admins']} admin(s), " + f"{result['streamers']} streamer(s) resolved, " + f"{result['skipped_stale']} stale/unresolvable reference(s) skipped." + ), + } + + def _sync_now(self, settings, logger): + summary = sync_engine.run_sync(settings, logger, dry_run=bool(settings.get("dry_run_mode"))) + lines = [ + f"created={summary['created']} updated={summary['updated']} " + f"disabled={summary['disabled']} skipped_stale={summary['skipped_stale']}" + ] + lines.extend(summary["details"]) + if summary["errors"]: + lines.append("Errors:") + lines.extend(summary["errors"]) + return {"status": "success" if not summary["errors"] else "error", "message": "\n".join(lines)} + + def _test_smtp_connection(self, settings, logger): + mailer.validate_smtp_connection(settings) + return {"status": "success", "message": "SMTP login succeeded."} + + def _send_test_email(self, settings, logger): + recipient = (settings.get("test_email_recipient") or "").strip() + if not recipient: + return {"status": "error", "message": "Set 'Test Email Recipient' first."} + mailer.send_test_email(settings, recipient) + return {"status": "success", "message": f"Test email sent to {recipient}."} + + def _reset_xc_password(self, settings, logger): + username = (settings.get("reset_xc_password_for_username") or "").strip() + if not username: + return {"status": "error", "message": "Set 'Username to reset XC password for' first."} + sync_engine.reset_xc_password_for_user(settings, username) + return {"status": "success", "message": f"XC password reset and emailed for {username}."} + + def _apply_schedule(self, settings, logger): + self._scheduler.request_reload() + return {"status": "success", "message": "Schedule applied."} + + def _scheduler_status(self, settings, logger): + import time + + next_run = self._scheduler.next_run_at() + if not next_run: + return {"status": "success", "message": "No sync currently scheduled (interval is 0 or none run yet)."} + seconds = max(0, int(next_run - time.time())) + return {"status": "success", "message": f"Next sync in ~{seconds} second(s)."} + + _ACTIONS = { + "test_ldap_connection": _test_ldap_connection, + "sync_now": _sync_now, + "test_smtp_connection": _test_smtp_connection, + "send_test_email": _send_test_email, + "reset_xc_password_for_username": _reset_xc_password, + "apply_schedule": _apply_schedule, + "scheduler_status": _scheduler_status, + } + + def run(self, action, params, context): + settings = context.get("settings", {}) or {} + logger = context.get("logger", LOGGER) + handler = self._ACTIONS.get(action) + if handler is None: + return {"status": "error", "message": f"Unknown action: {action}"} + try: + return handler(self, settings, logger) + except LDAPConnectionError as exc: + return {"status": "error", "message": str(exc)} + except Exception as exc: # noqa: BLE001 + logger.exception(f"LDAP User Sync: action '{action}' failed") + return {"status": "error", "message": f"Error: {exc}"} + + def stop(self, context): + self._scheduler.stop() diff --git a/plugins/ldap-user-sync/scheduler.py b/plugins/ldap-user-sync/scheduler.py new file mode 100644 index 00000000..f0dc1ee9 --- /dev/null +++ b/plugins/ldap-user-sync/scheduler.py @@ -0,0 +1,194 @@ +"""Self-elected, file-lock-based periodic scheduler. + +Dispatcharr plugins cannot use django_celery_beat/PeriodicTask for +scheduled work: plugin modules are imported dynamically, after the +Celery worker has already built its task dispatch table, so +beat-triggered plugin tasks always fail as unregistered (confirmed via +the merged m3u-expiration-notifier plugin's own code comment describing +exactly this failure mode). Since Dispatcharr runs multiple processes +(web/daphne, celery worker, celery beat) with no shared memory, a single +periodic sync instead requires one process to elect itself via an +atomic lock file and run an in-process background thread. This mirrors +that plugin's proven approach. +""" + +import json +import os +import threading +import time +import uuid + +_PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__)) + +LOCK_FILE = os.path.join(_PLUGIN_DIR, "scheduler.pid") +NEXT_RUN_FILE = os.path.join(_PLUGIN_DIR, "scheduler_next_run.json") +RELOAD_FLAG = os.path.join(_PLUGIN_DIR, "scheduler_reload.flag") +STOP_FLAG = os.path.join(_PLUGIN_DIR, "scheduler_stop.flag") + +POLL_SECONDS = 30 +INELIGIBLE_HOST_MARKERS = ("daphne", "dispatcharr.asgi") + + +def _is_ineligible_host(): + try: + with open("/proc/self/cmdline", "rb") as f: + cmdline = f.read().decode("utf-8", "replace") + except Exception: + return False + return any(marker in cmdline for marker in INELIGIBLE_HOST_MARKERS) + + +class Scheduler: + def __init__(self, get_settings, run_sync_fn, logger): + self._get_settings = get_settings + self._run_sync_fn = run_sync_fn + self._logger = logger + self._thread = None + self._stop_event = threading.Event() + self._holds_lock = False + + # -- locking --------------------------------------------------------- + + def _lock_is_stale(self): + try: + with open(LOCK_FILE, "r") as f: + content = f.read().strip() + pid = int(content.split(":", 1)[0]) + except Exception: + return True + if pid == os.getpid(): + return False + try: + os.kill(pid, 0) + return False + except ProcessLookupError: + return True + except PermissionError: + return False + + def _acquire_lock(self): + payload = f"{os.getpid()}:{uuid.uuid4().hex}".encode() + try: + fd = os.open(LOCK_FILE, os.O_CREAT | os.O_EXCL | os.O_WRONLY) + try: + os.write(fd, payload) + finally: + os.close(fd) + return True + except FileExistsError: + if self._lock_is_stale(): + try: + os.remove(LOCK_FILE) + except OSError: + return False + return self._acquire_lock() + return False + + def _release_lock(self): + if not self._holds_lock: + return + try: + with open(LOCK_FILE, "r") as f: + content = f.read().strip() + if content.startswith(f"{os.getpid()}:"): + os.remove(LOCK_FILE) + except Exception: + pass + self._holds_lock = False + + # -- persisted schedule state ----------------------------------------- + + def _configured_interval_minutes(self): + try: + return max(0, int(self._get_settings().get("sync_interval_minutes") or 0)) + except (TypeError, ValueError): + return 0 + + def _read_next_run(self): + try: + with open(NEXT_RUN_FILE, "r") as f: + return float(json.load(f).get("next_run") or 0) + except Exception: + return 0.0 + + def _write_next_run(self, ts): + try: + with open(NEXT_RUN_FILE, "w") as f: + json.dump({"next_run": ts}, f) + except Exception: + self._logger.debug("LDAP User Sync: failed to persist next_run", exc_info=True) + + @staticmethod + def _consume_flag(path): + if os.path.exists(path): + try: + os.remove(path) + except OSError: + pass + return True + return False + + # -- lifecycle --------------------------------------------------------- + + def start(self): + if _is_ineligible_host(): + return + if not self._acquire_lock(): + return + self._holds_lock = True + self._stop_event.clear() + self._thread = threading.Thread(target=self._loop, daemon=True) + self._thread.start() + + def _loop(self): + from django.db import close_old_connections + + interval_minutes = self._configured_interval_minutes() + next_run = self._read_next_run() + if interval_minutes and not next_run: + next_run = time.time() + interval_minutes * 60 + self._write_next_run(next_run) + + while not self._stop_event.is_set(): + if self._consume_flag(STOP_FLAG): + break + if self._consume_flag(RELOAD_FLAG): + interval_minutes = self._configured_interval_minutes() + next_run = (time.time() + interval_minutes * 60) if interval_minutes else 0 + self._write_next_run(next_run) + + interval_minutes = self._configured_interval_minutes() + if interval_minutes and next_run and time.time() >= next_run: + try: + settings = self._get_settings() + summary = self._run_sync_fn( + settings, self._logger, dry_run=bool(settings.get("dry_run_mode")) + ) + self._logger.info("LDAP User Sync: scheduled sync complete: %s", summary) + except Exception: + self._logger.exception("LDAP User Sync: scheduled sync failed") + finally: + close_old_connections() + next_run = time.time() + interval_minutes * 60 + self._write_next_run(next_run) + + self._stop_event.wait(POLL_SECONDS) + + def request_reload(self): + try: + open(RELOAD_FLAG, "a").close() + except OSError: + pass + + def next_run_at(self): + return self._read_next_run() + + def stop(self): + self._stop_event.set() + try: + open(STOP_FLAG, "a").close() + except OSError: + pass + if self._thread and self._thread.is_alive(): + self._thread.join(timeout=5) + self._release_lock() diff --git a/plugins/ldap-user-sync/sync_engine.py b/plugins/ldap-user-sync/sync_engine.py new file mode 100644 index 00000000..f25c876e --- /dev/null +++ b/plugins/ldap-user-sync/sync_engine.py @@ -0,0 +1,195 @@ +"""Reconciliation logic: LDAP groups -> Dispatcharr `User` rows. + +Two configurable LDAP group DNs map to Dispatcharr's `user_level` +(Admin=10, Streamer=0). Users in neither group are never touched. A +user who drops out of both groups on a later sync gets `is_active=False` +(configurable). XC passwords are generated once on creation and never +silently rotated afterward. +""" + +from apps.accounts.models import User + +import ldap_client +import mailer +import xc_password + + +def _resolve_group(conn, settings, group_dn, level): + is_username = bool(settings.get("ldap_group_member_is_username")) + raw_members = ldap_client.resolve_group_members(conn, settings, group_dn) + resolved = [] + stale = 0 + for raw in raw_members: + rec = ( + ldap_client.fetch_user_by_username(conn, settings, raw) + if is_username + else ldap_client.fetch_user_by_dn(conn, raw, settings) + ) + if rec is None or not rec.get("username"): + stale += 1 + continue + resolved.append({**rec, "level": level}) + return resolved, stale + + +def _build_matched_users(conn, settings, logger): + admin_records, admin_stale = _resolve_group( + conn, settings, (settings.get("ldap_admin_group_dn") or "").strip(), 10 + ) + streamer_records, streamer_stale = _resolve_group( + conn, settings, (settings.get("ldap_streamer_group_dn") or "").strip(), 0 + ) + + matched = {} + for rec in admin_records: + matched[rec["username"]] = rec + for rec in streamer_records: + if rec["username"] in matched: + logger.warning( + "LDAP User Sync: %s is a member of both groups, admin takes precedence", + rec["username"], + ) + continue + matched[rec["username"]] = rec + + return matched, admin_stale + streamer_stale + + +def _apply_create_or_update(username, rec, settings, dry_run, summary): + exists = User.objects.filter(username=username).exists() + + if dry_run: + summary["details"].append( + f"{'would update' if exists else 'would create'} {username} (level={rec['level']})" + ) + summary["created" if not exists else "updated"] += 1 + return + + user, created = User.objects.get_or_create(username=username) + + if created: + user.user_level = rec["level"] + user.email = rec["email"] + user.first_name = rec["first_name"] + user.last_name = rec["last_name"] + user.set_unusable_password() + secret = xc_password.generate(settings.get("xc_password_length")) + user.custom_properties = { + "ldap_synced": True, + "ldap_dn": rec["dn"], + "xc_password": secret, + } + user.save() + summary["created"] += 1 + summary["details"].append(f"created {username} (level={rec['level']})") + + if rec["email"]: + try: + mailer.send_xc_password_email(settings, rec["email"], username, secret) + except Exception as exc: # noqa: BLE001 - report, never crash the sync + summary["errors"].append(f"email to {username} failed: {exc}") + else: + summary["errors"].append(f"{username} has no email attribute - XC password not emailed") + return + + changed = False + if user.user_level != rec["level"]: + user.user_level = rec["level"] + changed = True + if rec["email"] and user.email != rec["email"]: + user.email = rec["email"] + changed = True + if rec["first_name"] and user.first_name != rec["first_name"]: + user.first_name = rec["first_name"] + changed = True + if rec["last_name"] and user.last_name != rec["last_name"]: + user.last_name = rec["last_name"] + changed = True + + custom_properties = dict(user.custom_properties or {}) + if custom_properties.get("ldap_dn") != rec["dn"]: + custom_properties["ldap_dn"] = rec["dn"] + changed = True + if not custom_properties.get("ldap_synced"): + custom_properties["ldap_synced"] = True + changed = True + if not user.is_active: + user.is_active = True + changed = True + + if changed: + user.custom_properties = custom_properties + user.save() + summary["updated"] += 1 + summary["details"].append(f"updated {username} (level={rec['level']})") + + +def _apply_disable_pass(matched, settings, dry_run, summary): + if not settings.get("disable_users_removed_from_groups", True): + return + ldap_managed = User.objects.filter(custom_properties__ldap_synced=True) + for user in ldap_managed: + if user.username in matched or not user.is_active: + continue + if dry_run: + summary["details"].append(f"would disable {user.username}") + summary["disabled"] += 1 + continue + user.is_active = False + user.save(update_fields=["is_active"]) + summary["disabled"] += 1 + summary["details"].append(f"disabled {user.username}") + + +def run_sync(settings, logger, dry_run=False): + summary = { + "created": 0, + "updated": 0, + "disabled": 0, + "skipped_stale": 0, + "errors": [], + "details": [], + } + + conn = ldap_client.connect_service_account(settings) + try: + matched, stale = _build_matched_users(conn, settings, logger) + finally: + conn.unbind() + summary["skipped_stale"] = stale + + for username, rec in matched.items(): + try: + _apply_create_or_update(username, rec, settings, dry_run, summary) + except Exception as exc: # noqa: BLE001 - isolate one bad record from the rest + summary["errors"].append(f"{username}: {exc}") + + _apply_disable_pass(matched, settings, dry_run, summary) + + return summary + + +def preview_groups(settings, logger): + """Read-only counts for the 'Test LDAP Connection' action. Writes nothing.""" + conn = ldap_client.connect_service_account(settings) + try: + matched, stale = _build_matched_users(conn, settings, logger) + finally: + conn.unbind() + admins = sum(1 for rec in matched.values() if rec["level"] == 10) + streamers = sum(1 for rec in matched.values() if rec["level"] == 0) + return {"admins": admins, "streamers": streamers, "skipped_stale": stale} + + +def reset_xc_password_for_user(settings, username): + username = (username or "").strip() + if not username: + raise ValueError("No username given") + user = User.objects.get(username=username) + secret = xc_password.generate(settings.get("xc_password_length")) + xc_password.write_for_user(user, secret) + if user.email: + mailer.send_xc_password_email(settings, user.email, username, secret) + else: + raise ValueError(f"{username} has no email address on file - password rotated but not emailed") + return secret diff --git a/plugins/ldap-user-sync/vendor/ldap3/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/__init__.py new file mode 100644 index 00000000..19c206fa --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/__init__.py @@ -0,0 +1,150 @@ +""" +""" + +# Created on 2013.05.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 . + +from types import GeneratorType + +# authentication +ANONYMOUS = 'ANONYMOUS' +SIMPLE = 'SIMPLE' +SASL = 'SASL' +NTLM = 'NTLM' + +# SASL MECHANISMS +EXTERNAL = 'EXTERNAL' +DIGEST_MD5 = 'DIGEST-MD5' +KERBEROS = GSSAPI = 'GSSAPI' +PLAIN = 'PLAIN' + +AUTO_BIND_DEFAULT = 'DEFAULT' # binds connection when using "with" context manager +AUTO_BIND_NONE = 'NONE' # same as False, no bind is performed +AUTO_BIND_NO_TLS = 'NO_TLS' # same as True, bind is performed without tls +AUTO_BIND_TLS_BEFORE_BIND = 'TLS_BEFORE_BIND' # start_tls is performed before bind +AUTO_BIND_TLS_AFTER_BIND = 'TLS_AFTER_BIND' # start_tls is performed after bind + +# server IP dual stack mode +IP_SYSTEM_DEFAULT = 'IP_SYSTEM_DEFAULT' +IP_V4_ONLY = 'IP_V4_ONLY' +IP_V6_ONLY = 'IP_V6_ONLY' +IP_V4_PREFERRED = 'IP_V4_PREFERRED' +IP_V6_PREFERRED = 'IP_V6_PREFERRED' + +# search scope +BASE = 'BASE' +LEVEL = 'LEVEL' +SUBTREE = 'SUBTREE' + +# search alias +DEREF_NEVER = 'NEVER' +DEREF_SEARCH = 'SEARCH' +DEREF_BASE = 'FINDING_BASE' +DEREF_ALWAYS = 'ALWAYS' + +# search attributes +ALL_ATTRIBUTES = '*' +NO_ATTRIBUTES = '1.1' # as per RFC 4511 +ALL_OPERATIONAL_ATTRIBUTES = '+' # as per RFC 3673 + +# modify type +MODIFY_ADD = 'MODIFY_ADD' +MODIFY_DELETE = 'MODIFY_DELETE' +MODIFY_REPLACE = 'MODIFY_REPLACE' +MODIFY_INCREMENT = 'MODIFY_INCREMENT' + +# client strategies +SYNC = 'SYNC' +SAFE_SYNC = 'SAFE_SYNC' +SAFE_RESTARTABLE = 'SAFE_RESTARTABLE' +ASYNC = 'ASYNC' +LDIF = 'LDIF' +RESTARTABLE = 'RESTARTABLE' +REUSABLE = 'REUSABLE' +MOCK_SYNC = 'MOCK_SYNC' +MOCK_ASYNC = 'MOCK_ASYNC' +ASYNC_STREAM = 'ASYNC_STREAM' + +# get rootDSE info +NONE = 'NO_INFO' +DSA = 'DSA' +SCHEMA = 'SCHEMA' +ALL = 'ALL' + +OFFLINE_EDIR_8_8_8 = 'EDIR_8_8_8' +OFFLINE_EDIR_9_1_4 = 'EDIR_9_1_4' +OFFLINE_AD_2012_R2 = 'AD_2012_R2' +OFFLINE_SLAPD_2_4 = 'SLAPD_2_4' +OFFLINE_DS389_1_3_3 = 'DS389_1_3_3' + +# server pooling +FIRST = 'FIRST' +ROUND_ROBIN = 'ROUND_ROBIN' +RANDOM = 'RANDOM' + +# Hashed password +HASHED_NONE = 'PLAIN' +HASHED_SHA = 'SHA' +HASHED_SHA256 = 'SHA256' +HASHED_SHA384 = 'SHA384' +HASHED_SHA512 = 'SHA512' +HASHED_MD5 = 'MD5' +HASHED_SALTED_SHA = 'SALTED_SHA' +HASHED_SALTED_SHA256 = 'SALTED_SHA256' +HASHED_SALTED_SHA384 = 'SALTED_SHA384' +HASHED_SALTED_SHA512 = 'SALTED_SHA512' +HASHED_SALTED_MD5 = 'SALTED_MD5' + +if str is not bytes: # Python 3 + NUMERIC_TYPES = (int, float) + INTEGER_TYPES = (int, ) +else: + NUMERIC_TYPES = (int, long, float) + INTEGER_TYPES = (int, long) + +# types for string and sequence +if str is not bytes: # Python 3 + STRING_TYPES = (str, ) + SEQUENCE_TYPES = (set, list, tuple, GeneratorType, type(dict().keys())) # dict.keys() is a iterable memoryview in Python 3 +else: # Python 2 + try: + from future.types.newstr import newstr + except ImportError: + pass + + STRING_TYPES = (str, unicode) + SEQUENCE_TYPES = (set, list, tuple, GeneratorType) + +# centralized imports # must be at the end of the __init__.py file +from .version import __author__, __version__, __email__, __description__, __status__, __license__, __url__ +from .utils.config import get_config_parameter, set_config_parameter +from .core.server import Server +from .core.connection import Connection +from .core.tls import Tls +from .core.pooling import ServerPool +from .core.rdns import ReverseDnsSetting +from .abstract.objectDef import ObjectDef +from .abstract.attrDef import AttrDef +from .abstract.attribute import Attribute, WritableAttribute, OperationalAttribute +from .abstract.entry import Entry, WritableEntry +from .abstract.cursor import Reader, Writer +from .protocol.rfc4512 import DsaInfo, SchemaInfo diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/__init__.py new file mode 100644 index 00000000..38c144d0 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/__init__.py @@ -0,0 +1,50 @@ +""" +""" + +# Created on 2016.08.31 +# +# 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 . + +STATUS_INIT = 'Initialized' # The entry object is initialized +STATUS_VIRTUAL = 'Virtual' # The entry is a new writable entry, still empty +STATUS_MANDATORY_MISSING = 'Missing mandatory attributes' # The entry has some mandatory attributes missing +STATUS_READ = 'Read' # The entry has been read +STATUS_WRITABLE = 'Writable' # The entry has been made writable, still no changes +STATUS_PENDING_CHANGES = 'Pending changes' # The entry has some changes to commit, mandatory attributes are present +STATUS_COMMITTED = 'Committed' # The entry changes has been committed +STATUS_READY_FOR_DELETION = 'Ready for deletion' # The entry is set to be deleted +STATUS_READY_FOR_MOVING = 'Ready for moving' # The entry is set to be moved in the DIT +STATUS_READY_FOR_RENAMING = 'Ready for renaming' # The entry is set to be renamed +STATUS_DELETED = 'Deleted' # The entry has been deleted + +STATUSES = [STATUS_INIT, + STATUS_VIRTUAL, + STATUS_MANDATORY_MISSING, + STATUS_READ, + STATUS_WRITABLE, + STATUS_PENDING_CHANGES, + STATUS_COMMITTED, + STATUS_READY_FOR_DELETION, + STATUS_READY_FOR_MOVING, + STATUS_READY_FOR_RENAMING, + STATUS_DELETED] + +INITIAL_STATUSES = [STATUS_READ, STATUS_WRITABLE, STATUS_VIRTUAL] diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/attrDef.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/attrDef.py new file mode 100644 index 00000000..af47382d --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/attrDef.py @@ -0,0 +1,121 @@ +""" +""" + +# Created on 2014.01.11 +# +# 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 . + +from os import linesep + +from .. import SEQUENCE_TYPES +from ..core.exceptions import LDAPKeyError +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED + + +class AttrDef(object): + """Hold the definition of an attribute + + :param name: the real attribute name + :type name: string + :param key: the friendly name to use in queries and when accessing the attribute, default to the real attribute name + :type key: string + :param validate: called to check if the value in the query is valid, the callable is called with the value parameter + :type validate: callable + :param pre_query: called to transform values returned by search + :type pre_query: callable + :param post_query: called to transform values returned by search + :type post_query: callable + :param default: value returned when the attribute is absent (defaults to NotImplemented to allow use of None as default) + :type default: string, integer + :param dereference_dn: reference to an ObjectDef instance. When the attribute value contains a dn it will be searched and substituted in the entry + :type dereference_dn: ObjectDef + :param description: custom attribute description + :type description: string + :param mandatory: specify if attribute is defined as mandatory in LDAP schema + :type mandatory: boolean + """ + + def __init__(self, name, key=None, validate=None, pre_query=None, post_query=None, default=NotImplemented, dereference_dn=None, description=None, mandatory=False, single_value=None, alias=None): + self.name = name + self.key = ''.join(key.split()) if key else name # key set to name if not present + self.validate = validate + self.pre_query = pre_query + self.post_query = post_query + self.default = default + self.dereference_dn = dereference_dn + self.description = description + self.mandatory = mandatory + self.single_value = single_value + self.oid_info = None + if not alias: + self.other_names = None + elif isinstance(alias, SEQUENCE_TYPES): # multiple aliases + self.\ + other_names = set(alias) + else: # single alias + self.other_names = set([alias]) # python 2 compatibility + + if log_enabled(BASIC): + log(BASIC, 'instantiated AttrDef: <%r>', self) + + def __repr__(self): + r = 'ATTR: ' + ', '.join([self.key] + list(self.other_names)) if self.other_names else self.key + r += '' if self.name == self.key else ' [' + self.name + ']' + r += '' if self.default is NotImplemented else ' - default: ' + str(self.default) + r += '' if self.mandatory is None else ' - mandatory: ' + str(self.mandatory) + r += '' if self.single_value is None else ' - single_value: ' + str(self.single_value) + r += '' if not self.dereference_dn else ' - dereference_dn: ' + str(self.dereference_dn) + r += '' if not self.description else ' - description: ' + str(self.description) + if self.oid_info: + for line in str(self.oid_info).split(linesep): + r += linesep + ' ' + line + return r + + def __str__(self): + return self.__repr__() + + def __eq__(self, other): + if isinstance(other, AttrDef): + return self.key == other.key + + return False + + def __lt__(self, other): + if isinstance(other, AttrDef): + return self.key < other.key + + return False + + def __hash__(self): + if self.key: + return hash(self.key) + else: + return id(self) # unique for each instance + + def __setattr__(self, key, value): + if hasattr(self, 'key') and key == 'key': # key cannot be changed because is being used for __hash__ + error_message = 'key \'%s\' already set' % key + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + else: + object.__setattr__(self, key, value) diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/attribute.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/attribute.py new file mode 100644 index 00000000..5d33cc78 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/attribute.py @@ -0,0 +1,290 @@ +""" +""" + +# Created on 2014.01.06 +# +# 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 . + +from os import linesep + +from .. import MODIFY_ADD, MODIFY_REPLACE, MODIFY_DELETE, SEQUENCE_TYPES +from ..core.exceptions import LDAPCursorError +from ..utils.repr import to_stdout_encoding +from . import STATUS_PENDING_CHANGES, STATUS_VIRTUAL, STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED + + +# noinspection PyUnresolvedReferences +class Attribute(object): + """Attribute/values object, it includes the search result (after post_query transformation) of each attribute in an entry + + Attribute object is read only + + - values: contain the processed attribute values + - raw_values': contain the unprocessed attribute values + + + """ + + def __init__(self, attr_def, entry, cursor): + self.key = attr_def.key + self.definition = attr_def + self.values = [] + self.raw_values = [] + self.response = None + self.entry = entry + self.cursor = cursor + other_names = [name for name in attr_def.oid_info.name if self.key.lower() != name.lower()] if attr_def.oid_info else None + self.other_names = set(other_names) if other_names else None # self.other_names is None if there are no short names, else is a set of secondary names + + def __repr__(self): + if len(self.values) == 1: + r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0]) + elif len(self.values) > 1: + r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0]) + filler = ' ' * (len(self.key) + 6) + for value in self.values[1:]: + r += linesep + filler + to_stdout_encoding(value) + else: + r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding('') + + return r + + def __str__(self): + if len(self.values) == 1: + return to_stdout_encoding(self.values[0]) + else: + return to_stdout_encoding(self.values) + + def __len__(self): + return len(self.values) + + def __iter__(self): + return self.values.__iter__() + + def __getitem__(self, item): + return self.values[item] + + def __getstate__(self): + cpy = dict(self.__dict__) + cpy['cursor'] = None + return cpy + + def __eq__(self, other): + try: + if self.value == other: + return True + except Exception: + return False + + def __ne__(self, other): + return not self == other + + @property + def value(self): + """ + :return: The single value or a list of values of the attribute. + """ + if not self.values: + return None + + return self.values[0] if len(self.values) == 1 else self.values + + +class OperationalAttribute(Attribute): + """Operational attribute/values object. Include the search result of an + operational attribute in an entry + + OperationalAttribute object is read only + + - values: contains the processed attribute values + - raw_values: contains the unprocessed attribute values + + It may not have an AttrDef + + """ + + def __repr__(self): + if len(self.values) == 1: + r = to_stdout_encoding(self.key) + ' [OPERATIONAL]: ' + to_stdout_encoding(self.values[0]) + elif len(self.values) > 1: + r = to_stdout_encoding(self.key) + ' [OPERATIONAL]: ' + to_stdout_encoding(self.values[0]) + filler = ' ' * (len(self.key) + 6) + for value in sorted(self.values[1:]): + r += linesep + filler + to_stdout_encoding(value) + else: + r = '' + + return r + + +class WritableAttribute(Attribute): + def __repr__(self): + filler = ' ' * (len(self.key) + 6) + if len(self.values) == 1: + r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0]) + elif len(self.values) > 1: + r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0]) + for value in self.values[1:]: + r += linesep + filler + to_stdout_encoding(value) + else: + r = to_stdout_encoding(self.key) + to_stdout_encoding(': ') + if self.definition.name in self.entry._changes: + r += linesep + filler + 'CHANGES: ' + str(self.entry._changes[self.definition.name]) + return r + + def __iadd__(self, other): + self.add(other) + return Ellipsis # hack to avoid calling set() in entry __setattr__ + + def __isub__(self, other): + self.delete(other) + return Ellipsis # hack to avoid calling set_value in entry __setattr__ + + def _update_changes(self, changes, remove_old=False): + # checks for friendly key in AttrDef and uses the real attribute name + if self.definition and self.definition.name: + key = self.definition.name + else: + key = self.key + + if key not in self.entry._changes or remove_old: # remove old changes (for removing attribute) + self.entry._changes[key] = [] + + self.entry._changes[key].append(changes) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'updated changes <%r> for <%s> attribute in <%s> entry', changes, self.key, self.entry.entry_dn) + self.entry._state.set_status(STATUS_PENDING_CHANGES) + + def add(self, values): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'adding %r to <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn) + # new value for attribute to commit with a MODIFY_ADD + if self.entry._state._initial_status == STATUS_VIRTUAL: + error_message = 'cannot perform a modify operation in a new entry' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]: + error_message = self.entry.entry_status + ' - cannot add attributes' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if values is None: + error_message = 'value to add cannot be None' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if values is not None: + validated = self.definition.validate(values) # returns True, False or a value to substitute to the actual values + if validated is False: + error_message = 'value \'%s\' non valid for attribute \'%s\'' % (values, self.key) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + elif validated is not True: # a valid LDAP value equivalent to the actual values + values = validated + self._update_changes((MODIFY_ADD, values if isinstance(values, SEQUENCE_TYPES) else [values])) + + def set(self, values): + # new value for attribute to commit with a MODIFY_REPLACE, old values are deleted + if log_enabled(PROTOCOL): + log(PROTOCOL, 'setting %r to <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn) + if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]: + error_message = self.entry.entry_status + ' - cannot set attributes' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if values is None: + error_message = 'new value cannot be None' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + validated = self.definition.validate(values) # returns True, False or a value to substitute to the actual values + if validated is False: + error_message = 'value \'%s\' non valid for attribute \'%s\'' % (values, self.key) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + elif validated is not True: # a valid LDAP value equivalent to the actual values + values = validated + self._update_changes((MODIFY_REPLACE, values if isinstance(values, SEQUENCE_TYPES) else [values]), remove_old=True) + + def delete(self, values): + # value for attribute to delete in commit with a MODIFY_DELETE + if log_enabled(PROTOCOL): + log(PROTOCOL, 'deleting %r from <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn) + if self.entry._state._initial_status == STATUS_VIRTUAL: + error_message = 'cannot delete an attribute value in a new entry' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]: + error_message = self.entry.entry_status + ' - cannot delete attributes' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if values is None: + error_message = 'value to delete cannot be None' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if not isinstance(values, SEQUENCE_TYPES): + values = [values] + for single_value in values: + if single_value not in self.values: + error_message = 'value \'%s\' not present in \'%s\'' % (single_value, ', '.join(self.values)) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self._update_changes((MODIFY_DELETE, values)) + + def remove(self): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'removing <%s> attribute in <%s> entry', self.key, self.entry.entry_dn) + if self.entry._state._initial_status == STATUS_VIRTUAL: + error_message = 'cannot remove an attribute in a new entry' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]: + error_message = self.entry.entry_status + ' - cannot remove attributes' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self._update_changes((MODIFY_REPLACE, []), True) + + def discard(self): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'discarding <%s> attribute in <%s> entry', self.key, self.entry.entry_dn) + del self.entry._changes[self.key] + if not self.entry._changes: + self.entry._state.set_status(self.entry._state._initial_status) + + @property + def virtual(self): + return False if len(self.values) else True + + @property + def changes(self): + if self.key in self.entry._changes: + return self.entry._changes[self.key] + return None diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/cursor.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/cursor.py new file mode 100644 index 00000000..690e87d4 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/cursor.py @@ -0,0 +1,912 @@ +""" +""" + +# Created on 2014.01.06 +# +# 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 . +from collections import namedtuple +from copy import deepcopy +from datetime import datetime +from os import linesep +from time import sleep + +from . import STATUS_VIRTUAL, STATUS_READ, STATUS_WRITABLE +from .. import SUBTREE, LEVEL, DEREF_ALWAYS, DEREF_NEVER, BASE, SEQUENCE_TYPES, STRING_TYPES, get_config_parameter +from ..abstract import STATUS_PENDING_CHANGES +from .attribute import Attribute, OperationalAttribute, WritableAttribute +from .attrDef import AttrDef +from .objectDef import ObjectDef +from .entry import Entry, WritableEntry +from ..core.exceptions import LDAPCursorError, LDAPObjectDereferenceError +from ..core.results import RESULT_SUCCESS +from ..utils.ciDict import CaseInsensitiveWithAliasDict +from ..utils.dn import safe_dn, safe_rdn +from ..utils.conv import to_raw +from ..utils.config import get_config_parameter +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED +from ..protocol.oid import ATTRIBUTE_DIRECTORY_OPERATION, ATTRIBUTE_DISTRIBUTED_OPERATION, ATTRIBUTE_DSA_OPERATION, CLASS_AUXILIARY + +Operation = namedtuple('Operation', ('request', 'result', 'response')) + + +def _ret_search_value(value): + return value[0] + '=' + value[1:] if value[0] in '<>~' and value[1] != '=' else value + + +def _create_query_dict(query_text): + """ + Create a dictionary with query key:value definitions + query_text is a comma delimited key:value sequence + """ + query_dict = dict() + if query_text: + for arg_value_str in query_text.split(','): + if ':' in arg_value_str: + arg_value_list = arg_value_str.split(':') + query_dict[arg_value_list[0].strip()] = arg_value_list[1].strip() + + return query_dict + + +class Cursor(object): + # entry_class and attribute_class define the type of entry and attribute used by the cursor + # entry_initial_status defines the initial status of a entry + # entry_class = Entry, must be defined in subclasses + # attribute_class = Attribute, must be defined in subclasses + # entry_initial_status = STATUS, must be defined in subclasses + + def __init__(self, connection, object_def, get_operational_attributes=False, attributes=None, controls=None, auxiliary_class=None): + conf_attributes_excluded_from_object_def = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF')] + self.connection = connection + self.get_operational_attributes = get_operational_attributes + if connection._deferred_bind or connection._deferred_open: # probably a lazy connection, tries to bind + connection._fire_deferred() + + if isinstance(object_def, (STRING_TYPES, SEQUENCE_TYPES)): + if connection.closed: # try to open connection if closed to read schema + connection.bind() + object_def = ObjectDef(object_def, connection.server.schema, auxiliary_class=auxiliary_class) + self.definition = object_def + if attributes: # checks if requested attributes are defined in ObjectDef + not_defined_attributes = [] + if isinstance(attributes, STRING_TYPES): + attributes = [attributes] + + for attribute in attributes: + if attribute not in self.definition._attributes and attribute.lower() not in conf_attributes_excluded_from_object_def: + not_defined_attributes.append(attribute) + + if not_defined_attributes: + error_message = 'Attributes \'%s\' non in definition' % ', '.join(not_defined_attributes) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + self.attributes = set(attributes) if attributes else set([attr.name for attr in self.definition]) + self.controls = controls + self.execution_time = None + self.entries = [] + self.schema = self.connection.server.schema + self._do_not_reset = False # used for refreshing entry in entry_refresh() without removing all entries from the Cursor + self._operation_history = list() # a list storing all the requests, results and responses for the last cursor operation + + def __repr__(self): + r = 'CURSOR : ' + self.__class__.__name__ + linesep + r += 'CONN : ' + str(self.connection) + linesep + r += 'DEFS : ' + ', '.join(self.definition._object_class) + if self.definition._auxiliary_class: + r += ' [AUX: ' + ', '.join(self.definition._auxiliary_class) + ']' + r += linesep + # for attr_def in sorted(self.definition): + # r += (attr_def.key if attr_def.key == attr_def.name else (attr_def.key + ' <' + attr_def.name + '>')) + ', ' + # if r[-2] == ',': + # r = r[:-2] + # r += ']' + linesep + if hasattr(self, 'attributes'): + r += 'ATTRS : ' + repr(sorted(self.attributes)) + (' [OPERATIONAL]' if self.get_operational_attributes else '') + linesep + if isinstance(self, Reader): + if hasattr(self, 'base'): + r += 'BASE : ' + repr(self.base) + (' [SUB]' if self.sub_tree else ' [LEVEL]') + linesep + if hasattr(self, '_query') and self._query: + r += 'QUERY : ' + repr(self._query) + ('' if '(' in self._query else (' [AND]' if self.components_in_and else ' [OR]')) + linesep + if hasattr(self, 'validated_query') and self.validated_query: + r += 'PARSED : ' + repr(self.validated_query) + ('' if '(' in self._query else (' [AND]' if self.components_in_and else ' [OR]')) + linesep + if hasattr(self, 'query_filter') and self.query_filter: + r += 'FILTER : ' + repr(self.query_filter) + linesep + + if hasattr(self, 'execution_time') and self.execution_time: + r += 'ENTRIES: ' + str(len(self.entries)) + r += ' [executed at: ' + str(self.execution_time.isoformat()) + ']' + linesep + + if self.failed: + r += 'LAST OPERATION FAILED [' + str(len(self.errors)) + ' failure' + ('s' if len(self.errors) > 1 else '') + ' at operation' + ('s ' if len(self.errors) > 1 else ' ') + ', '.join([str(i) for i, error in enumerate(self.operations) if error.result['result'] != RESULT_SUCCESS]) + ']' + + return r + + def __str__(self): + return self.__repr__() + + def __iter__(self): + return self.entries.__iter__() + + def __getitem__(self, item): + """Return indexed item, if index is not found then try to sequentially search in DN of entries. + If only one entry is found return it else raise a KeyError exception. The exception message + includes the number of entries that matches, if less than 10 entries match then show the DNs + in the exception message. + """ + try: + return self.entries[item] + except TypeError: + pass + + if isinstance(item, STRING_TYPES): + found = self.match_dn(item) + + if len(found) == 1: + return found[0] + elif len(found) > 1: + error_message = 'Multiple entries found: %d entries match the text in dn' % len(found) + ('' if len(found) > 10 else (' [' + '; '.join([e.entry_dn for e in found]) + ']')) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise KeyError(error_message) + + error_message = 'no entry found' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise KeyError(error_message) + + def __len__(self): + return len(self.entries) + + if str is not bytes: # Python 3 + def __bool__(self): # needed to make the cursor appears as existing in "if cursor:" even if there are no entries + return True + else: # Python 2 + def __nonzero__(self): + return True + + def _get_attributes(self, response, attr_defs, entry): + """Assign the result of the LDAP query to the Entry object dictionary. + + If the optional 'post_query' callable is present in the AttrDef it is called with each value of the attribute and the callable result is stored in the attribute. + + Returns the default value for missing attributes. + If the 'dereference_dn' in AttrDef is a ObjectDef then the attribute values are treated as distinguished name and the relevant entry is retrieved and stored in the attribute value. + + """ + conf_operational_attribute_prefix = get_config_parameter('ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX') + conf_attributes_excluded_from_object_def = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF')] + attributes = CaseInsensitiveWithAliasDict() + used_attribute_names = set() + for attr in attr_defs: + attr_def = attr_defs[attr] + attribute_name = None + for attr_name in response['attributes']: + if attr_def.name.lower() == attr_name.lower(): + attribute_name = attr_name + break + + if attribute_name or attr_def.default is not NotImplemented: # attribute value found in result or default value present - NotImplemented allows use of None as default + attribute = self.attribute_class(attr_def, entry, self) + attribute.response = response + attribute.raw_values = response['raw_attributes'][attribute_name] if attribute_name else None + if attr_def.post_query and attr_def.name in response['attributes'] and response['raw_attributes'] != list(): + attribute.values = attr_def.post_query(attr_def.key, response['attributes'][attribute_name]) + else: + if attr_def.default is NotImplemented or (attribute_name and response['raw_attributes'][attribute_name] != list()): + attribute.values = response['attributes'][attribute_name] + else: + attribute.values = attr_def.default if isinstance(attr_def.default, SEQUENCE_TYPES) else [attr_def.default] + if not isinstance(attribute.values, list): # force attribute values to list (if attribute is single-valued) + attribute.values = [attribute.values] + if attr_def.dereference_dn: # try to get object referenced in value + if attribute.values: + temp_reader = Reader(self.connection, attr_def.dereference_dn, base='', get_operational_attributes=self.get_operational_attributes, controls=self.controls) + temp_values = [] + for element in attribute.values: + if entry.entry_dn != element: + temp_values.append(temp_reader.search_object(element)) + else: + error_message = 'object %s is referencing itself in the \'%s\' attribute' % (entry.entry_dn, attribute.definition.name) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPObjectDereferenceError(error_message) + del temp_reader # remove the temporary Reader + attribute.values = temp_values + attributes[attribute.key] = attribute + if attribute.other_names: + attributes.set_alias(attribute.key, attribute.other_names) + if attr_def.other_names: + attributes.set_alias(attribute.key, attr_def.other_names) + used_attribute_names.add(attribute_name) + + if self.attributes: + used_attribute_names.update(self.attributes) + + for attribute_name in response['attributes']: + if attribute_name not in used_attribute_names: + operational_attribute = False + # check if the type is an operational attribute + if attribute_name in self.schema.attribute_types: + if self.schema.attribute_types[attribute_name].no_user_modification or self.schema.attribute_types[attribute_name].usage in [ATTRIBUTE_DIRECTORY_OPERATION, ATTRIBUTE_DISTRIBUTED_OPERATION, ATTRIBUTE_DSA_OPERATION]: + operational_attribute = True + else: + operational_attribute = True + if not operational_attribute and attribute_name not in attr_defs and attribute_name.lower() not in conf_attributes_excluded_from_object_def: + error_message = 'attribute \'%s\' not in object class \'%s\' for entry %s' % (attribute_name, ', '.join(entry.entry_definition._object_class), entry.entry_dn) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + attribute = OperationalAttribute(AttrDef(conf_operational_attribute_prefix + attribute_name), entry, self) + attribute.raw_values = response['raw_attributes'][attribute_name] + attribute.values = response['attributes'][attribute_name] if isinstance(response['attributes'][attribute_name], SEQUENCE_TYPES) else [response['attributes'][attribute_name]] + if (conf_operational_attribute_prefix + attribute_name) not in attributes: + attributes[conf_operational_attribute_prefix + attribute_name] = attribute + + return attributes + + def match_dn(self, dn): + """Return entries with text in DN""" + matched = [] + for entry in self.entries: + if dn.lower() in entry.entry_dn.lower(): + matched.append(entry) + return matched + + def match(self, attributes, value): + """Return entries with text in one of the specified attributes""" + matched = [] + if not isinstance(attributes, SEQUENCE_TYPES): + attributes = [attributes] + + for entry in self.entries: + found = False + for attribute in attributes: + if attribute in entry: + for attr_value in entry[attribute].values: + if hasattr(attr_value, 'lower') and hasattr(value, 'lower') and value.lower() in attr_value.lower(): + found = True + elif value == attr_value: + found = True + if found: + matched.append(entry) + break + if found: + break + # checks raw values, tries to convert value to byte + raw_value = to_raw(value) + if isinstance(raw_value, (bytes, bytearray)): + for attr_value in entry[attribute].raw_values: + if hasattr(attr_value, 'lower') and hasattr(raw_value, 'lower') and raw_value.lower() in attr_value.lower(): + found = True + elif raw_value == attr_value: + found = True + if found: + matched.append(entry) + break + if found: + break + return matched + + def _create_entry(self, response): + if not response['type'] == 'searchResEntry': + return None + + entry = self.entry_class(response['dn'], self) # define an Entry (writable or readonly), as specified in the cursor definition + entry._state.attributes = self._get_attributes(response, self.definition._attributes, entry) + entry._state.raw_attributes = deepcopy(response['raw_attributes']) + + entry._state.response = response + entry._state.read_time = datetime.now() + entry._state.set_status(self.entry_initial_status) + for attr in entry: # returns the whole attribute object + entry.__dict__[attr.key] = attr + + return entry + + def _execute_query(self, query_scope, attributes): + if not self.connection: + error_message = 'no connection established' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + old_query_filter = None + if query_scope == BASE: # requesting a single object so an always-valid filter is set + if hasattr(self, 'query_filter'): # only Reader has a query filter + old_query_filter = self.query_filter + self.query_filter = '(objectclass=*)' + else: + self._create_query_filter() + if log_enabled(PROTOCOL): + log(PROTOCOL, 'executing query - base: %s - filter: %s - scope: %s for <%s>', self.base, self.query_filter, query_scope, self) + with self.connection: + result = self.connection.search(search_base=self.base, + search_filter=self.query_filter, + search_scope=query_scope, + dereference_aliases=self.dereference_aliases, + attributes=attributes if attributes else list(self.attributes), + get_operational_attributes=self.get_operational_attributes, + controls=self.controls) + if not self.connection.strategy.sync: + response, result, request = self.connection.get_response(result, get_request=True) + else: + if self.connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = self.connection.response + result = self.connection.result + request = self.connection.request + + self._store_operation_in_history(request, result, response) + + if self._do_not_reset: # trick to not remove entries when using _refresh() + return self._create_entry(response[0]) + + self.entries = [] + for r in response: + entry = self._create_entry(r) + if entry is not None: + self.entries.append(entry) + if 'objectClass' in entry: + for object_class in entry.objectClass: + if self.schema and self.schema.object_classes[object_class].kind == CLASS_AUXILIARY and object_class not in self.definition._auxiliary_class: + # add auxiliary class to object definition + self.definition._auxiliary_class.append(object_class) + self.definition._populate_attr_defs(object_class) + self.execution_time = datetime.now() + + if old_query_filter: # requesting a single object so an always-valid filter is set + self.query_filter = old_query_filter + + def remove(self, entry): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'removing entry <%s> in <%s>', entry, self) + self.entries.remove(entry) + + def _reset_history(self): + self._operation_history = list() + + def _store_operation_in_history(self, request, result, response): + self._operation_history.append(Operation(request, result, response)) + + @property + def operations(self): + return self._operation_history + + @property + def errors(self): + return [error for error in self._operation_history if error.result['result'] != RESULT_SUCCESS] + + @property + def failed(self): + if hasattr(self, '_operation_history'): + return any([error.result['result'] != RESULT_SUCCESS for error in self._operation_history]) + + +class Reader(Cursor): + """Reader object to perform searches: + + :param connection: the LDAP connection object to use + :type connection: LDAPConnection + :param object_def: the ObjectDef of the LDAP object returned + :type object_def: ObjectDef + :param query: the simplified query (will be transformed in an LDAP filter) + :type query: str + :param base: starting base of the search + :type base: str + :param components_in_and: specify if assertions in the query must all be satisfied or not (AND/OR) + :type components_in_and: bool + :param sub_tree: specify if the search must be performed ad Single Level (False) or Whole SubTree (True) + :type sub_tree: bool + :param get_operational_attributes: specify if operational attributes are returned or not + :type get_operational_attributes: bool + :param controls: controls to be used in search + :type controls: tuple + + """ + entry_class = Entry # entries are read_only + attribute_class = Attribute # attributes are read_only + entry_initial_status = STATUS_READ + + def __init__(self, connection, object_def, base, query='', components_in_and=True, sub_tree=True, get_operational_attributes=False, attributes=None, controls=None, auxiliary_class=None): + Cursor.__init__(self, connection, object_def, get_operational_attributes, attributes, controls, auxiliary_class) + self._components_in_and = components_in_and + self.sub_tree = sub_tree + self._query = query + self.base = base + self.dereference_aliases = DEREF_ALWAYS + self.validated_query = None + self._query_dict = dict() + self._validated_query_dict = dict() + self.query_filter = None + self.reset() + + if log_enabled(BASIC): + log(BASIC, 'instantiated Reader Cursor: <%r>', self) + + @property + def query(self): + return self._query + + @query.setter + def query(self, value): + self._query = value + self.reset() + + @property + def components_in_and(self): + return self._components_in_and + + @components_in_and.setter + def components_in_and(self, value): + self._components_in_and = value + self.reset() + + def clear(self): + """Clear the Reader search parameters + + """ + self.dereference_aliases = DEREF_ALWAYS + self._reset_history() + + def reset(self): + """Clear all the Reader parameters + + """ + self.clear() + self.validated_query = None + self._query_dict = dict() + self._validated_query_dict = dict() + self.execution_time = None + self.query_filter = None + self.entries = [] + self._create_query_filter() + + def _validate_query(self): + """Processes the text query and verifies that the requested friendly names are in the Reader dictionary + If the AttrDef has a 'validate' property the callable is executed and if it returns False an Exception is raised + + """ + if not self._query_dict: + self._query_dict = _create_query_dict(self._query) + + query = '' + for d in sorted(self._query_dict): + attr = d[1:] if d[0] in '&|' else d + for attr_def in self.definition: + if ''.join(attr.split()).lower() == attr_def.key.lower(): + attr = attr_def.key + break + if attr in self.definition: + vals = sorted(self._query_dict[d].split(';')) + + query += (d[0] + attr if d[0] in '&|' else attr) + ': ' + for val in vals: + val = val.strip() + val_not = True if val[0] == '!' else False + val_search_operator = '=' # default + if val_not: + if val[1:].lstrip()[0] not in '=<>~': + value = val[1:].lstrip() + else: + val_search_operator = val[1:].lstrip()[0] + value = val[1:].lstrip()[1:] + else: + if val[0] not in '=<>~': + value = val.lstrip() + else: + val_search_operator = val[0] + value = val[1:].lstrip() + + if self.definition[attr].validate: + validated = self.definition[attr].validate(value) # returns True, False or a value to substitute to the actual values + if validated is False: + error_message = 'validation failed for attribute %s and value %s' % (d, val) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + elif validated is not True: # a valid LDAP value equivalent to the actual values + value = validated + if val_not: + query += '!' + val_search_operator + str(value) + else: + query += val_search_operator + str(value) + + query += ';' + query = query[:-1] + ', ' + else: + error_message = 'attribute \'%s\' not in definition' % attr + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self.validated_query = query[:-2] + self._validated_query_dict = _create_query_dict(self.validated_query) + + def _create_query_filter(self): + """Converts the query dictionary to the filter text""" + self.query_filter = '' + + if self.definition._object_class: + self.query_filter += '(&' + if isinstance(self.definition._object_class, SEQUENCE_TYPES) and len(self.definition._object_class) == 1: + self.query_filter += '(objectClass=' + self.definition._object_class[0] + ')' + elif isinstance(self.definition._object_class, SEQUENCE_TYPES): + self.query_filter += '(&' + for object_class in self.definition._object_class: + self.query_filter += '(objectClass=' + object_class + ')' + self.query_filter += ')' + else: + error_message = 'object class must be a string or a list' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + if self._query and self._query.startswith('(') and self._query.endswith(')'): # query is already an LDAP filter + if 'objectclass' not in self._query.lower(): + self.query_filter += self._query + ')' # if objectclass not in filter adds from definition + else: + self.query_filter = self._query + return + elif self._query: # if a simplified filter is present + if not self.components_in_and: + self.query_filter += '(|' + elif not self.definition._object_class: + self.query_filter += '(&' + + self._validate_query() + + attr_counter = 0 + for attr in sorted(self._validated_query_dict): + attr_counter += 1 + multi = True if ';' in self._validated_query_dict[attr] else False + vals = sorted(self._validated_query_dict[attr].split(';')) + attr_def = self.definition[attr[1:]] if attr[0] in '&|' else self.definition[attr] + if attr_def.pre_query: + modvals = [] + for val in vals: + modvals.append(val[0] + attr_def.pre_query(attr_def.key, val[1:])) + vals = modvals + if multi: + if attr[0] in '&|': + self.query_filter += '(' + attr[0] + else: + self.query_filter += '(|' + + for val in vals: + if val[0] == '!': + self.query_filter += '(!(' + attr_def.name + _ret_search_value(val[1:]) + '))' + else: + self.query_filter += '(' + attr_def.name + _ret_search_value(val) + ')' + if multi: + self.query_filter += ')' + + if not self.components_in_and: + self.query_filter += '))' + else: + self.query_filter += ')' + + if not self.definition._object_class and attr_counter == 1: # removes unneeded starting filter + self.query_filter = self.query_filter[2: -1] + + if self.query_filter == '(|)' or self.query_filter == '(&)': # removes empty filter + self.query_filter = '' + else: # no query, remove unneeded leading (& + self.query_filter = self.query_filter[2:] + + def search(self, attributes=None): + """Perform the LDAP search + + :return: Entries found in search + + """ + self.clear() + query_scope = SUBTREE if self.sub_tree else LEVEL + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing search in <%s>', self) + self._execute_query(query_scope, attributes) + + return self.entries + + def search_object(self, entry_dn=None, attributes=None): # base must be a single dn + """Perform the LDAP search operation SINGLE_OBJECT scope + + :return: Entry found in search + + """ + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing object search in <%s>', self) + self.clear() + if entry_dn: + old_base = self.base + self.base = entry_dn + self._execute_query(BASE, attributes) + self.base = old_base + else: + self._execute_query(BASE, attributes) + + return self.entries[0] if len(self.entries) > 0 else None + + def search_level(self, attributes=None): + """Perform the LDAP search operation with SINGLE_LEVEL scope + + :return: Entries found in search + + """ + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing single level search in <%s>', self) + self.clear() + self._execute_query(LEVEL, attributes) + + return self.entries + + def search_subtree(self, attributes=None): + """Perform the LDAP search operation WHOLE_SUBTREE scope + + :return: Entries found in search + + """ + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing whole subtree search in <%s>', self) + self.clear() + self._execute_query(SUBTREE, attributes) + + return self.entries + + def _entries_generator(self, responses): + for response in responses: + yield self._create_entry(response) + + def search_paged(self, paged_size, paged_criticality=True, generator=True, attributes=None): + """Perform a paged search, can be called as an Iterator + + :param attributes: optional attributes to search + :param paged_size: number of entries returned in each search + :type paged_size: int + :param paged_criticality: specify if server must not execute the search if it is not capable of paging searches + :type paged_criticality: bool + :param generator: if True the paged searches are executed while generating the entries, + if False all the paged searches are execute before returning the generator + :type generator: bool + :return: Entries found in search + + """ + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing paged search in <%s> with paged size %s', self, str(paged_size)) + if not self.connection: + error_message = 'no connection established' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + self.clear() + self._create_query_filter() + self.entries = [] + self.execution_time = datetime.now() + response = self.connection.extend.standard.paged_search(search_base=self.base, + search_filter=self.query_filter, + search_scope=SUBTREE if self.sub_tree else LEVEL, + dereference_aliases=self.dereference_aliases, + attributes=attributes if attributes else self.attributes, + get_operational_attributes=self.get_operational_attributes, + controls=self.controls, + paged_size=paged_size, + paged_criticality=paged_criticality, + generator=generator) + if generator: + return self._entries_generator(response) + else: + return list(self._entries_generator(response)) + + +class Writer(Cursor): + entry_class = WritableEntry + attribute_class = WritableAttribute + entry_initial_status = STATUS_WRITABLE + + @staticmethod + def from_cursor(cursor, connection=None, object_def=None, custom_validator=None): + if connection is None: + connection = cursor.connection + if object_def is None: + object_def = cursor.definition + writer = Writer(connection, object_def, attributes=cursor.attributes) + for entry in cursor.entries: + if isinstance(cursor, Reader): + entry.entry_writable(object_def, writer, custom_validator=custom_validator) + elif isinstance(cursor, Writer): + pass + else: + error_message = 'unknown cursor type %s' % str(type(cursor)) + if log_enabled(ERROR): + log(ERROR, '%s', error_message) + raise LDAPCursorError(error_message) + writer.execution_time = cursor.execution_time + if log_enabled(BASIC): + log(BASIC, 'instantiated Writer Cursor <%r> from cursor <%r>', writer, cursor) + return writer + + @staticmethod + def from_response(connection, object_def, response=None): + if response is None: + if not connection.strategy.sync: + error_message = 'with asynchronous strategies response must be specified' + if log_enabled(ERROR): + log(ERROR, '%s', error_message) + raise LDAPCursorError(error_message) + elif connection.response: + response = connection.response + else: + error_message = 'response not present' + if log_enabled(ERROR): + log(ERROR, '%s', error_message) + raise LDAPCursorError(error_message) + writer = Writer(connection, object_def) + + for resp in response: + if resp['type'] == 'searchResEntry': + entry = writer._create_entry(resp) + writer.entries.append(entry) + if log_enabled(BASIC): + log(BASIC, 'instantiated Writer Cursor <%r> from response', writer) + return writer + + def __init__(self, connection, object_def, get_operational_attributes=False, attributes=None, controls=None, auxiliary_class=None): + Cursor.__init__(self, connection, object_def, get_operational_attributes, attributes, controls, auxiliary_class) + self.dereference_aliases = DEREF_NEVER + + if log_enabled(BASIC): + log(BASIC, 'instantiated Writer Cursor: <%r>', self) + + def commit(self, refresh=True): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'committed changes for <%s>', self) + self._reset_history() + successful = True + for entry in self.entries: + if not entry.entry_commit_changes(refresh=refresh, controls=self.controls, clear_history=False): + successful = False + + self.execution_time = datetime.now() + + return successful + + def discard(self): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'discarded changes for <%s>', self) + for entry in self.entries: + entry.entry_discard_changes() + + def _refresh_object(self, entry_dn, attributes=None, tries=4, seconds=2, controls=None): # base must be a single dn + """Performs the LDAP search operation SINGLE_OBJECT scope + + :return: Entry found in search + + """ + if log_enabled(PROTOCOL): + log(PROTOCOL, 'refreshing object <%s> for <%s>', entry_dn, self) + if not self.connection: + error_message = 'no connection established' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + response = [] + with self.connection: + counter = 0 + while counter < tries: + result = self.connection.search(search_base=entry_dn, + search_filter='(objectclass=*)', + search_scope=BASE, + dereference_aliases=DEREF_NEVER, + attributes=attributes if attributes else self.attributes, + get_operational_attributes=self.get_operational_attributes, + controls=controls) + if not self.connection.strategy.sync: + response, result, request = self.connection.get_response(result, get_request=True) + else: + if self.connection.strategy.thread_safe: + _, result, response, request = result + else: + response = self.connection.response + result = self.connection.result + request = self.connection.request + + if result['result'] in [RESULT_SUCCESS]: + break + sleep(seconds) + counter += 1 + self._store_operation_in_history(request, result, response) + + if len(response) == 1: + return self._create_entry(response[0]) + elif len(response) == 0: + return None + + error_message = 'more than 1 entry returned for a single object search' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + def new(self, dn): + if log_enabled(BASIC): + log(BASIC, 'creating new entry <%s> for <%s>', dn, self) + dn = safe_dn(dn) + for entry in self.entries: # checks if dn is already used in an cursor entry + if entry.entry_dn == dn: + error_message = 'dn already present in cursor' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + rdns = safe_rdn(dn, decompose=True) + entry = self.entry_class(dn, self) # defines a new empty Entry + for attr in entry.entry_mandatory_attributes: # defines all mandatory attributes as virtual + entry._state.attributes[attr] = self.attribute_class(entry._state.definition[attr], entry, self) + entry.__dict__[attr] = entry._state.attributes[attr] + entry.objectclass.set(self.definition._object_class) + for rdn in rdns: # adds virtual attributes from rdns in entry name (should be more than one with + syntax) + if rdn[0] in entry._state.definition._attributes: + rdn_name = entry._state.definition._attributes[rdn[0]].name # normalize case folding + if rdn_name not in entry._state.attributes: + entry._state.attributes[rdn_name] = self.attribute_class(entry._state.definition[rdn_name], entry, self) + entry.__dict__[rdn_name] = entry._state.attributes[rdn_name] + entry.__dict__[rdn_name].set(rdn[1]) + else: + error_message = 'rdn type \'%s\' not in object class definition' % rdn[0] + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + entry._state.set_status(STATUS_VIRTUAL) # set intial status + entry._state.set_status(STATUS_PENDING_CHANGES) # tries to change status to PENDING_CHANGES. If mandatory attributes are missing status is reverted to MANDATORY_MISSING + self.entries.append(entry) + return entry + + def refresh_entry(self, entry, tries=4, seconds=2): + conf_operational_attribute_prefix = get_config_parameter('ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX') + + self._do_not_reset = True + attr_list = [] + if log_enabled(PROTOCOL): + log(PROTOCOL, 'refreshing entry <%s> for <%s>', entry, self) + for attr in entry._state.attributes: # check friendly attribute name in AttrDef, do not check operational attributes + if attr.lower().startswith(conf_operational_attribute_prefix.lower()): + continue + if entry._state.definition[attr].name: + attr_list.append(entry._state.definition[attr].name) + else: + attr_list.append(entry._state.definition[attr].key) + + temp_entry = self._refresh_object(entry.entry_dn, attr_list, tries, seconds=seconds) # if any attributes is added adds only to the entry not to the definition + self._do_not_reset = False + if temp_entry: + temp_entry._state.origin = entry._state.origin + entry.__dict__.clear() + entry.__dict__['_state'] = temp_entry._state + for attr in entry._state.attributes: # returns the attribute key + entry.__dict__[attr] = entry._state.attributes[attr] + + for attr in entry.entry_attributes: # if any attribute of the class was deleted makes it virtual + if attr not in entry._state.attributes and attr in entry.entry_definition._attributes: + entry._state.attributes[attr] = WritableAttribute(entry.entry_definition[attr], entry, self) + entry.__dict__[attr] = entry._state.attributes[attr] + entry._state.set_status(entry._state._initial_status) + return True + return False diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/entry.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/entry.py new file mode 100644 index 00000000..2375796a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/entry.py @@ -0,0 +1,712 @@ +""" +""" + +# Created on 2016.08.19 +# +# 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 . + + +import json +try: + from collections import OrderedDict +except ImportError: + from ..utils.ordDict import OrderedDict # for Python 2.6 + +from os import linesep +from copy import deepcopy + +from .. import STRING_TYPES, SEQUENCE_TYPES, MODIFY_ADD, MODIFY_REPLACE +from .attribute import WritableAttribute +from .objectDef import ObjectDef +from .attrDef import AttrDef +from ..core.exceptions import LDAPKeyError, LDAPCursorError, LDAPCursorAttributeError +from ..utils.conv import check_json_dict, format_json, prepare_for_stream +from ..protocol.rfc2849 import operation_to_ldif, add_ldif_header +from ..utils.dn import safe_dn, safe_rdn, to_dn +from ..utils.repr import to_stdout_encoding +from ..utils.ciDict import CaseInsensitiveWithAliasDict +from ..utils.config import get_config_parameter +from . import STATUS_VIRTUAL, STATUS_WRITABLE, STATUS_PENDING_CHANGES, STATUS_COMMITTED, STATUS_DELETED,\ + STATUS_INIT, STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING, STATUS_MANDATORY_MISSING, STATUSES, INITIAL_STATUSES +from ..core.results import RESULT_SUCCESS +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED + + +class EntryState(object): + """Contains data on the status of the entry. Does not pollute the Entry __dict__. + + """ + + def __init__(self, dn, cursor): + self.dn = dn + self._initial_status = None + self._to = None # used for move and rename + self.status = STATUS_INIT + self.attributes = CaseInsensitiveWithAliasDict() + self.raw_attributes = CaseInsensitiveWithAliasDict() + self.response = None + self.cursor = cursor + self.origin = None # reference to the original read-only entry (set when made writable). Needed to update attributes in read-only when modified (only if both refer the same server) + self.read_time = None + self.changes = OrderedDict() # includes changes to commit in a writable entry + if cursor.definition: + self.definition = cursor.definition + else: + self.definition = None + + def __repr__(self): + if self.__dict__ and self.dn is not None: + r = 'DN: ' + to_stdout_encoding(self.dn) + ' - STATUS: ' + ((self._initial_status + ', ') if self._initial_status != self.status else '') + self.status + ' - READ TIME: ' + (self.read_time.isoformat() if self.read_time else '') + linesep + r += 'attributes: ' + ', '.join(sorted(self.attributes.keys())) + linesep + r += 'object def: ' + (', '.join(sorted(self.definition._object_class)) if self.definition._object_class else '') + linesep + r += 'attr defs: ' + ', '.join(sorted(self.definition._attributes.keys())) + linesep + r += 'response: ' + ('present' if self.response else '') + linesep + r += 'cursor: ' + (self.cursor.__class__.__name__ if self.cursor else '') + linesep + return r + else: + return object.__repr__(self) + + def __str__(self): + return self.__repr__() + + def __getstate__(self): + cpy = dict(self.__dict__) + cpy['cursor'] = None + return cpy + + def set_status(self, status): + conf_ignored_mandatory_attributes_in_object_def = [v.lower() for v in get_config_parameter('IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF')] + if status not in STATUSES: + error_message = 'invalid entry status ' + str(status) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + if status in INITIAL_STATUSES: + self._initial_status = status + self.status = status + if status == STATUS_DELETED: + self._initial_status = STATUS_VIRTUAL + if status == STATUS_COMMITTED: + self._initial_status = STATUS_WRITABLE + if self.status == STATUS_VIRTUAL or (self.status == STATUS_PENDING_CHANGES and self._initial_status == STATUS_VIRTUAL): # checks if all mandatory attributes are present in new entries + for attr in self.definition._attributes: + if self.definition._attributes[attr].mandatory and attr.lower() not in conf_ignored_mandatory_attributes_in_object_def: + if (attr not in self.attributes or self.attributes[attr].virtual) and attr not in self.changes: + self.status = STATUS_MANDATORY_MISSING + break + + @property + def entry_raw_attributes(self): + return self.raw_attributes + + +class EntryBase(object): + """The Entry object contains a single LDAP entry. + Attributes can be accessed either by sequence, by assignment + or as dictionary keys. Keys are not case sensitive. + + The Entry object is read only + + - The DN is retrieved by entry_dn + - The cursor reference is in _cursor + - Raw attributes values are retrieved with _raw_attributes and the _raw_attribute() methods + """ + + def __init__(self, dn, cursor): + self._state = EntryState(dn, cursor) + + def __repr__(self): + if self.__dict__ and self.entry_dn is not None: + r = 'DN: ' + to_stdout_encoding(self.entry_dn) + ' - STATUS: ' + ((self._state._initial_status + ', ') if self._state._initial_status != self.entry_status else '') + self.entry_status + ' - READ TIME: ' + (self.entry_read_time.isoformat() if self.entry_read_time else '') + linesep + if self._state.attributes: + for attr in sorted(self._state.attributes): + if self._state.attributes[attr] or (hasattr(self._state.attributes[attr], 'changes') and self._state.attributes[attr].changes): + r += ' ' + repr(self._state.attributes[attr]) + linesep + return r + else: + return object.__repr__(self) + + def __str__(self): + return self.__repr__() + + def __iter__(self): + for attribute in self._state.attributes: + yield self._state.attributes[attribute] + # raise StopIteration # deprecated in PEP 479 + return + + def __contains__(self, item): + try: + self.__getitem__(item) + return True + except LDAPKeyError: + return False + + def __getattr__(self, item): + if isinstance(item, STRING_TYPES): + if item == '_state': + return object.__getattr__(self, item) + item = ''.join(item.split()).lower() + attr_found = None + for attr in self._state.attributes.keys(): + if item == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.aliases(): + if item == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.keys(): + if item + ';binary' == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.aliases(): + if item + ';binary' == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.keys(): + if item + ';range' in attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.aliases(): + if item + ';range' in attr.lower(): + attr_found = attr + break + if not attr_found: + error_message = 'attribute \'%s\' not found' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + return self._state.attributes[attr] + error_message = 'attribute name must be a string' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + + def __setattr__(self, item, value): + if item == '_state': + object.__setattr__(self, item, value) + elif item in self._state.attributes: + error_message = 'attribute \'%s\' is read only' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + else: + error_message = 'entry is read only, cannot add \'%s\'' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + + def __getitem__(self, item): + if isinstance(item, STRING_TYPES): + item = ''.join(item.split()).lower() + attr_found = None + for attr in self._state.attributes.keys(): + if item == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.aliases(): + if item == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.keys(): + if item + ';binary' == attr.lower(): + attr_found = attr + break + if not attr_found: + for attr in self._state.attributes.aliases(): + if item + ';binary' == attr.lower(): + attr_found = attr + break + if not attr_found: + error_message = 'key \'%s\' not found' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + return self._state.attributes[attr] + + error_message = 'key must be a string' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + + def __eq__(self, other): + if isinstance(other, EntryBase): + return self.entry_dn == other.entry_dn + + return False + + def __lt__(self, other): + if isinstance(other, EntryBase): + return self.entry_dn <= other.entry_dn + + return False + + @property + def entry_dn(self): + return self._state.dn + + @property + def entry_cursor(self): + return self._state.cursor + + @property + def entry_status(self): + return self._state.status + + @property + def entry_definition(self): + return self._state.definition + + @property + def entry_raw_attributes(self): + return self._state.raw_attributes + + def entry_raw_attribute(self, name): + """ + + :param name: name of the attribute + :return: raw (unencoded) value of the attribute, None if attribute is not found + """ + return self._state.raw_attributes[name] if name in self._state.raw_attributes else None + + @property + def entry_mandatory_attributes(self): + return [attribute for attribute in self.entry_definition._attributes if self.entry_definition._attributes[attribute].mandatory] + + @property + def entry_attributes(self): + return list(self._state.attributes.keys()) + + @property + def entry_attributes_as_dict(self): + return dict((attribute_key, deepcopy(attribute_value.values)) for (attribute_key, attribute_value) in self._state.attributes.items()) + + @property + def entry_read_time(self): + return self._state.read_time + + @property + def _changes(self): + return self._state.changes + + def entry_to_json(self, raw=False, indent=4, sort=True, stream=None, checked_attributes=True, include_empty=True): + json_entry = dict() + json_entry['dn'] = self.entry_dn + if checked_attributes: + if not include_empty: + # needed for python 2.6 compatibility + json_entry['attributes'] = dict((key, self.entry_attributes_as_dict[key]) for key in self.entry_attributes_as_dict if self.entry_attributes_as_dict[key]) + else: + json_entry['attributes'] = self.entry_attributes_as_dict + if raw: + if not include_empty: + # needed for python 2.6 compatibility + json_entry['raw'] = dict((key, self.entry_raw_attributes[key]) for key in self.entry_raw_attributes if self.entry_raw_attributes[key]) + else: + json_entry['raw'] = dict(self.entry_raw_attributes) + + if str is bytes: # Python 2 + check_json_dict(json_entry) + + json_output = json.dumps(json_entry, + ensure_ascii=True, + sort_keys=sort, + indent=indent, + check_circular=True, + default=format_json, + separators=(',', ': ')) + + if stream: + stream.write(json_output) + + return json_output + + def entry_to_ldif(self, all_base64=False, line_separator=None, sort_order=None, stream=None): + ldif_lines = operation_to_ldif('searchResponse', [self._state.response], all_base64, sort_order=sort_order) + ldif_lines = add_ldif_header(ldif_lines) + line_separator = line_separator or linesep + ldif_output = line_separator.join(ldif_lines) + if stream: + if stream.tell() == 0: + header = add_ldif_header(['-'])[0] + stream.write(prepare_for_stream(header + line_separator + line_separator)) + stream.write(prepare_for_stream(ldif_output + line_separator + line_separator)) + return ldif_output + + +class Entry(EntryBase): + """The Entry object contains a single LDAP entry. + Attributes can be accessed either by sequence, by assignment + or as dictionary keys. Keys are not case sensitive. + + The Entry object is read only + + - The DN is retrieved by entry_dn + - The Reader reference is in _cursor() + - Raw attributes values are retrieved by the _ra_attributes and + _raw_attribute() methods + + """ + def entry_writable(self, object_def=None, writer_cursor=None, attributes=None, custom_validator=None, auxiliary_class=None): + conf_operational_attribute_prefix = get_config_parameter('ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX') + if not self.entry_cursor.schema: + error_message = 'schema must be available to make an entry writable' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + # returns a new WritableEntry and its Writer cursor + if object_def is None: + if self.entry_cursor.definition._object_class: + object_def = self.entry_definition._object_class + auxiliary_class = self.entry_definition._auxiliary_class + (auxiliary_class if isinstance(auxiliary_class, SEQUENCE_TYPES) else []) + elif 'objectclass' in self: + object_def = self.objectclass.values + + if not object_def: + error_message = 'object class must be specified to make an entry writable' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + + if not isinstance(object_def, ObjectDef): + object_def = ObjectDef(object_def, self.entry_cursor.schema, custom_validator, auxiliary_class) + + if attributes: + if isinstance(attributes, STRING_TYPES): + attributes = [attributes] + + if isinstance(attributes, SEQUENCE_TYPES): + for attribute in attributes: + if attribute not in object_def._attributes: + error_message = 'attribute \'%s\' not in schema for \'%s\'' % (attribute, object_def) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + else: + attributes = [] + + if not writer_cursor: + from .cursor import Writer # local import to avoid circular reference in import at startup + writable_cursor = Writer(self.entry_cursor.connection, object_def) + else: + writable_cursor = writer_cursor + + if attributes: # force reading of attributes + writable_entry = writable_cursor._refresh_object(self.entry_dn, list(attributes) + self.entry_attributes) + else: + writable_entry = writable_cursor._create_entry(self._state.response) + writable_cursor.entries.append(writable_entry) + writable_entry._state.read_time = self.entry_read_time + writable_entry._state.origin = self # reference to the original read-only entry + # checks original entry for custom definitions in AttrDefs + attr_to_add = [] + attr_to_remove = [] + object_def_to_add = [] + object_def_to_remove = [] + for attr in writable_entry._state.origin.entry_definition._attributes: + original_attr = writable_entry._state.origin.entry_definition._attributes[attr] + if attr != original_attr.name and (attr not in writable_entry._state.attributes or conf_operational_attribute_prefix + original_attr.name not in writable_entry._state.attributes): + old_attr_def = writable_entry.entry_definition._attributes[original_attr.name] + new_attr_def = AttrDef(original_attr.name, + key=attr, + validate=original_attr.validate, + pre_query=original_attr.pre_query, + post_query=original_attr.post_query, + default=original_attr.default, + dereference_dn=original_attr.dereference_dn, + description=original_attr.description, + mandatory=old_attr_def.mandatory, # keeps value read from schema + single_value=old_attr_def.single_value, # keeps value read from schema + alias=original_attr.other_names) + od = writable_entry.entry_definition + object_def_to_remove.append(old_attr_def) + object_def_to_add.append(new_attr_def) + # updates attribute name in entry attributes + new_attr = WritableAttribute(new_attr_def, writable_entry, writable_cursor) + if original_attr.name in writable_entry._state.attributes: + new_attr.other_names = writable_entry._state.attributes[original_attr.name].other_names + new_attr.raw_values = writable_entry._state.attributes[original_attr.name].raw_values + new_attr.values = writable_entry._state.attributes[original_attr.name].values + new_attr.response = writable_entry._state.attributes[original_attr.name].response + attr_to_add.append((attr, new_attr)) + attr_to_remove.append(original_attr.name) + # writable_entry._state.attributes[attr] = new_attr + ## writable_entry._state.attributes.set_alias(attr, new_attr.other_names) + # del writable_entry._state.attributes[original_attr.name] + for attr, new_attr in attr_to_add: + writable_entry._state.attributes[attr] = new_attr + for attr in attr_to_remove: + del writable_entry._state.attributes[attr] + for object_def in object_def_to_remove: + o = writable_entry.entry_definition + o -= object_def + for object_def in object_def_to_add: + o = writable_entry.entry_definition + o += object_def + + writable_entry._state.set_status(STATUS_WRITABLE) + return writable_entry + + +class WritableEntry(EntryBase): + def __setitem__(self, key, value): + if value is not Ellipsis: # hack for using implicit operators in writable attributes + self.__setattr__(key, value) + + def __setattr__(self, item, value): + conf_attributes_excluded_from_object_def = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF')] + if item == '_state' and isinstance(value, EntryState): + self.__dict__['_state'] = value + return + + if value is not Ellipsis: # hack for using implicit operators in writable attributes + # checks if using an alias + if item in self.entry_cursor.definition._attributes or item.lower() in conf_attributes_excluded_from_object_def: + if item not in self._state.attributes: # setting value to an attribute still without values + new_attribute = WritableAttribute(self.entry_cursor.definition._attributes[item], self, cursor=self.entry_cursor) + self._state.attributes[str(item)] = new_attribute # force item to a string for key in attributes dict + self._state.attributes[item].set(value) # try to add to new_values + else: + error_message = 'attribute \'%s\' not defined' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + + def __getattr__(self, item): + if isinstance(item, STRING_TYPES): + if item == '_state': + return self.__dict__['_state'] + item = ''.join(item.split()).lower() + for attr in self._state.attributes.keys(): + if item == attr.lower(): + return self._state.attributes[attr] + for attr in self._state.attributes.aliases(): + if item == attr.lower(): + return self._state.attributes[attr] + if item in self.entry_definition._attributes: # item is a new attribute to commit, creates the AttrDef and add to the attributes to retrive + self._state.attributes[item] = WritableAttribute(self.entry_definition._attributes[item], self, self.entry_cursor) + self.entry_cursor.attributes.add(item) + return self._state.attributes[item] + error_message = 'attribute \'%s\' not defined' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + else: + error_message = 'attribute name must be a string' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorAttributeError(error_message) + + @property + def entry_virtual_attributes(self): + return [attr for attr in self.entry_attributes if self[attr].virtual] + + def entry_commit_changes(self, refresh=True, controls=None, clear_history=True): + if clear_history: + self.entry_cursor._reset_history() + + if self.entry_status == STATUS_READY_FOR_DELETION: + result = self.entry_cursor.connection.delete(self.entry_dn, controls) + if not self.entry_cursor.connection.strategy.sync: + response, result, request = self.entry_cursor.connection.get_response(result, get_request=True) + else: + if self.entry_cursor.connection.strategy.thread_safe: + _, result, response, request = result + else: + response = self.entry_cursor.connection.response + result = self.entry_cursor.connection.result + request = self.entry_cursor.connection.request + self.entry_cursor._store_operation_in_history(request, result, response) + if result['result'] == RESULT_SUCCESS: + dn = self.entry_dn + if self._state.origin and self.entry_cursor.connection.server == self._state.origin.entry_cursor.connection.server: # deletes original read-only Entry + cursor = self._state.origin.entry_cursor + self._state.origin.__dict__.clear() + self._state.origin.__dict__['_state'] = EntryState(dn, cursor) + self._state.origin._state.set_status(STATUS_DELETED) + cursor = self.entry_cursor + self.__dict__.clear() + self._state = EntryState(dn, cursor) + self._state.set_status(STATUS_DELETED) + return True + return False + elif self.entry_status == STATUS_READY_FOR_MOVING: + result = self.entry_cursor.connection.modify_dn(self.entry_dn, '+'.join(safe_rdn(self.entry_dn)), new_superior=self._state._to) + if not self.entry_cursor.connection.strategy.sync: + response, result, request = self.entry_cursor.connection.get_response(result, get_request=True) + else: + if self.entry_cursor.connection.strategy.thread_safe: + _, result, response, request = result + else: + response = self.entry_cursor.connection.response + result = self.entry_cursor.connection.result + request = self.entry_cursor.connection.request + self.entry_cursor._store_operation_in_history(request, result, response) + if result['result'] == RESULT_SUCCESS: + self._state.dn = safe_dn('+'.join(safe_rdn(self.entry_dn)) + ',' + self._state._to) + if refresh: + if self.entry_refresh(): + if self._state.origin and self.entry_cursor.connection.server == self._state.origin.entry_cursor.connection.server: # refresh dn of origin + self._state.origin._state.dn = self.entry_dn + self._state.set_status(STATUS_COMMITTED) + self._state._to = None + return True + return False + elif self.entry_status == STATUS_READY_FOR_RENAMING: + rdn = '+'.join(safe_rdn(self._state._to)) + result = self.entry_cursor.connection.modify_dn(self.entry_dn, rdn) + if not self.entry_cursor.connection.strategy.sync: + response, result, request = self.entry_cursor.connection.get_response(result, get_request=True) + else: + if self.entry_cursor.connection.strategy.thread_safe: + _, result, response, request = result + else: + response = self.entry_cursor.connection.response + result = self.entry_cursor.connection.result + request = self.entry_cursor.connection.request + self.entry_cursor._store_operation_in_history(request, result, response) + if result['result'] == RESULT_SUCCESS: + self._state.dn = rdn + ',' + ','.join(to_dn(self.entry_dn)[1:]) + if refresh: + if self.entry_refresh(): + if self._state.origin and self.entry_cursor.connection.server == self._state.origin.entry_cursor.connection.server: # refresh dn of origin + self._state.origin._state.dn = self.entry_dn + self._state.set_status(STATUS_COMMITTED) + self._state._to = None + return True + return False + elif self.entry_status in [STATUS_VIRTUAL, STATUS_MANDATORY_MISSING]: + missing_attributes = [] + for attr in self.entry_mandatory_attributes: + if (attr not in self._state.attributes or self._state.attributes[attr].virtual) and attr not in self._changes: + missing_attributes.append('\'' + attr + '\'') + error_message = 'mandatory attributes %s missing in entry %s' % (', '.join(missing_attributes), self.entry_dn) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + elif self.entry_status == STATUS_PENDING_CHANGES: + if self._changes: + if self.entry_definition._auxiliary_class: # checks if an attribute is from an auxiliary class and adds it to the objectClass attribute if not present + for attr in self._changes: + # checks schema to see if attribute is defined in one of the already present object classes + attr_classes = self.entry_cursor.schema.attribute_types[attr].mandatory_in + self.entry_cursor.schema.attribute_types[attr].optional_in + for object_class in self.objectclass: + if object_class in attr_classes: + break + else: # executed only if the attribute class is not present in the objectClass attribute + # checks if attribute is defined in one of the possible auxiliary classes + for aux_class in self.entry_definition._auxiliary_class: + if aux_class in attr_classes: + if self._state._initial_status == STATUS_VIRTUAL: # entry is new, there must be a pending objectClass MODIFY_REPLACE + self._changes['objectClass'][0][1].append(aux_class) + else: + self.objectclass += aux_class + if self._state._initial_status == STATUS_VIRTUAL: + new_attributes = dict() + for attr in self._changes: + new_attributes[attr] = self._changes[attr][0][1] + result = self.entry_cursor.connection.add(self.entry_dn, None, new_attributes, controls) + else: + result = self.entry_cursor.connection.modify(self.entry_dn, self._changes, controls) + + if not self.entry_cursor.connection.strategy.sync: # asynchronous request + response, result, request = self.entry_cursor.connection.get_response(result, get_request=True) + else: + if self.entry_cursor.connection.strategy.thread_safe: + _, result, response, request = result + else: + response = self.entry_cursor.connection.response + result = self.entry_cursor.connection.result + request = self.entry_cursor.connection.request + self.entry_cursor._store_operation_in_history(request, result, response) + + if result['result'] == RESULT_SUCCESS: + if refresh: + if self.entry_refresh(): + if self._state.origin and self.entry_cursor.connection.server == self._state.origin.entry_cursor.connection.server: # updates original read-only entry if present + for attr in self: # adds AttrDefs from writable entry to origin entry definition if some is missing + if attr.key in self.entry_definition._attributes and attr.key not in self._state.origin.entry_definition._attributes: + self._state.origin.entry_cursor.definition.add_attribute(self.entry_cursor.definition._attributes[attr.key]) # adds AttrDef from writable entry to original entry if missing + temp_entry = self._state.origin.entry_cursor._create_entry(self._state.response) + self._state.origin.__dict__.clear() + self._state.origin.__dict__['_state'] = temp_entry._state + for attr in self: # returns the whole attribute object + if not hasattr(attr,'virtual'): + self._state.origin.__dict__[attr.key] = self._state.origin._state.attributes[attr.key] + self._state.origin._state.read_time = self.entry_read_time + else: + self.entry_discard_changes() # if not refreshed remove committed changes + self._state.set_status(STATUS_COMMITTED) + return True + return False + + def entry_discard_changes(self): + self._changes.clear() + self._state.set_status(self._state._initial_status) + + def entry_delete(self): + if self.entry_status not in [STATUS_WRITABLE, STATUS_COMMITTED, STATUS_READY_FOR_DELETION]: + error_message = 'cannot delete entry, invalid status: ' + self.entry_status + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self._state.set_status(STATUS_READY_FOR_DELETION) + + def entry_refresh(self, tries=4, seconds=2): + """ + + Refreshes the entry from the LDAP Server + """ + if self.entry_cursor.connection: + if self.entry_cursor.refresh_entry(self, tries, seconds): + return True + + return False + + def entry_move(self, destination_dn): + if self.entry_status not in [STATUS_WRITABLE, STATUS_COMMITTED, STATUS_READY_FOR_MOVING]: + error_message = 'cannot move entry, invalid status: ' + self.entry_status + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self._state._to = safe_dn(destination_dn) + self._state.set_status(STATUS_READY_FOR_MOVING) + + def entry_rename(self, new_name): + if self.entry_status not in [STATUS_WRITABLE, STATUS_COMMITTED, STATUS_READY_FOR_RENAMING]: + error_message = 'cannot rename entry, invalid status: ' + self.entry_status + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPCursorError(error_message) + self._state._to = new_name + self._state.set_status(STATUS_READY_FOR_RENAMING) + + @property + def entry_changes(self): + return self._changes diff --git a/plugins/ldap-user-sync/vendor/ldap3/abstract/objectDef.py b/plugins/ldap-user-sync/vendor/ldap3/abstract/objectDef.py new file mode 100644 index 00000000..0de49df2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/abstract/objectDef.py @@ -0,0 +1,270 @@ +""" +""" + +# Created on 2014.02.02 +# +# 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 . + +from os import linesep + +from .attrDef import AttrDef +from ..core.exceptions import LDAPKeyError, LDAPObjectError, LDAPAttributeError, LDAPSchemaError +from .. import STRING_TYPES, SEQUENCE_TYPES, Server, Connection +from ..protocol.rfc4512 import SchemaInfo, constant_to_class_kind +from ..protocol.formatters.standard import find_attribute_validator +from ..utils.ciDict import CaseInsensitiveWithAliasDict +from ..utils.config import get_config_parameter +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED + + +class ObjectDef(object): + """Represent an object in the LDAP server. AttrDefs are stored in a dictionary; the key is the friendly name defined in AttrDef. + + AttrDefs can be added and removed using the += and -= operators + + ObjectDef can be accessed either as a sequence and a dictionary. When accessed the whole AttrDef instance is returned + + """ + def __init__(self, object_class=None, schema=None, custom_validator=None, auxiliary_class=None): + if object_class is None: + object_class = [] + + if not isinstance(object_class, SEQUENCE_TYPES): + object_class = [object_class] + + if auxiliary_class is None: + auxiliary_class = [] + + if not isinstance(auxiliary_class, SEQUENCE_TYPES): + auxiliary_class = [auxiliary_class] + + self.__dict__['_attributes'] = CaseInsensitiveWithAliasDict() + self.__dict__['_custom_validator'] = custom_validator + self.__dict__['_oid_info'] = [] + + if isinstance(schema, Connection) and (schema._deferred_bind or schema._deferred_open): # probably a lazy connection, tries to bind + schema._fire_deferred() + + if schema is not None: + if isinstance(schema, Server): + schema = schema.schema + elif isinstance(schema, Connection): + schema = schema.server.schema + elif isinstance(schema, SchemaInfo): + pass + elif schema: + error_message = 'unable to read schema' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPSchemaError(error_message) + if schema is None: + error_message = 'schema not present' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPSchemaError(error_message) + self.__dict__['_schema'] = schema + + if self._schema: + object_class = [schema.object_classes[name].name[0] for name in object_class] # uses object class names capitalized as in schema + auxiliary_class = [schema.object_classes[name].name[0] for name in auxiliary_class] + for object_name in object_class: + if object_name: + self._populate_attr_defs(object_name) + + for object_name in auxiliary_class: + if object_name: + self._populate_attr_defs(object_name) + + self.__dict__['_object_class'] = object_class + self.__dict__['_auxiliary_class'] = auxiliary_class + + if log_enabled(BASIC): + log(BASIC, 'instantiated ObjectDef: <%r>', self) + + def _populate_attr_defs(self, object_name): + if object_name in self._schema.object_classes: + object_schema = self._schema.object_classes[object_name] + self.__dict__['_oid_info'].append(object_name + " (" + constant_to_class_kind(object_schema.kind) + ") " + str(object_schema.oid)) + + if object_schema.superior: + for sup in object_schema.superior: + self._populate_attr_defs(sup) + for attribute_name in object_schema.must_contain: + self.add_from_schema(attribute_name, True) + for attribute_name in object_schema.may_contain: + if attribute_name not in self._attributes: # the attribute could already be defined as "mandatory" in a superclass + self.add_from_schema(attribute_name, False) + else: + error_message = 'object class \'%s\' not defined in schema' % object_name + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPObjectError(error_message) + + def __repr__(self): + if self._object_class: + r = 'OBJ : ' + ', '.join(self._object_class) + linesep + else: + r = 'OBJ : ' + linesep + if self._auxiliary_class: + r += 'AUX : ' + ', '.join(self._auxiliary_class) + linesep + else: + r += 'AUX : ' + linesep + r += 'OID: ' + ', '.join([oid for oid in self._oid_info]) + linesep + r += 'MUST: ' + ', '.join(sorted([attr for attr in self._attributes if self._attributes[attr].mandatory])) + linesep + r += 'MAY : ' + ', '.join(sorted([attr for attr in self._attributes if not self._attributes[attr].mandatory])) + linesep + + return r + + def __str__(self): + return self.__repr__() + + def __getitem__(self, item): + return self.__getattr__(item) + + def __getattr__(self, item): + item = ''.join(item.split()).lower() + if '_attributes' in self.__dict__: + try: + return self._attributes[item] + except KeyError: + error_message = 'key \'%s\' not present' % item + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + else: + error_message = 'internal _attributes property not defined' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + + def __setattr__(self, key, value): + error_message = 'object \'%s\' is read only' % key + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPObjectError(error_message) + + def __iadd__(self, other): + self.add_attribute(other) + return self + + def __isub__(self, other): + if isinstance(other, AttrDef): + self.remove_attribute(other.key) + elif isinstance(other, STRING_TYPES): + self.remove_attribute(other) + + return self + + def __iter__(self): + for attribute in self._attributes: + yield self._attributes[attribute] + + def __len__(self): + return len(self._attributes) + + if str is not bytes: # Python 3 + def __bool__(self): # needed to make the objectDef appears as existing in "if cursor:" even if there are no entries + return True + else: # Python 2 + def __nonzero__(self): + return True + + def __contains__(self, item): + try: + self.__getitem__(item) + except KeyError: + return False + + return True + + def add_from_schema(self, attribute_name, mandatory=False): + attr_def = AttrDef(attribute_name) + attr_def.validate = find_attribute_validator(self._schema, attribute_name, self._custom_validator) + attr_def.mandatory = mandatory # in schema mandatory is specified in the object class, not in the attribute class + if self._schema and self._schema.attribute_types and attribute_name in self._schema.attribute_types: + attr_def.single_value = self._schema.attribute_types[attribute_name].single_value + attr_def.oid_info = self._schema.attribute_types[attribute_name] + self.add_attribute(attr_def) + + def add_attribute(self, definition=None): + """Add an AttrDef to the ObjectDef. Can be called with the += operator. + :param definition: the AttrDef object to add, can also be a string containing the name of attribute to add. Can be a list of both + + """ + conf_attributes_excluded_from_object_def = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF')] + if isinstance(definition, STRING_TYPES): + self.add_from_schema(definition) + elif isinstance(definition, AttrDef): + if definition.key.lower() not in conf_attributes_excluded_from_object_def: + if definition.key not in self._attributes: + self._attributes[definition.key] = definition + if definition.name and definition.name != definition.key: + self._attributes.set_alias(definition.key, definition.name) + other_names = [name for name in definition.oid_info.name if definition.key.lower() != name.lower()] if definition.oid_info else None + if other_names: + self._attributes.set_alias(definition.key, other_names) + + if not definition.validate: + validator = find_attribute_validator(self._schema, definition.key, self._custom_validator) + self._attributes[definition.key].validate = validator + elif isinstance(definition, SEQUENCE_TYPES): + for element in definition: + self.add_attribute(element) + else: + error_message = 'unable to add element to object definition' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPObjectError(error_message) + + def remove_attribute(self, item): + """Remove an AttrDef from the ObjectDef. Can be called with the -= operator. + :param item: the AttrDef to remove, can also be a string containing the name of attribute to remove + + """ + key = None + if isinstance(item, STRING_TYPES): + key = ''.join(item.split()).lower() + elif isinstance(item, AttrDef): + key = item.key.lower() + + if key: + for attr in self._attributes: + if key == attr.lower(): + del self._attributes[attr] + break + else: + error_message = 'key \'%s\' not present' % key + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPKeyError(error_message) + else: + error_message = 'key type must be str or AttrDef not ' + str(type(item)) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error_message, self) + raise LDAPAttributeError(error_message) + + def clear_attributes(self): + """Empty the ObjectDef attribute list + + """ + self.__dict__['object_class'] = None + self.__dict__['auxiliary_class'] = None + self.__dict__['_attributes'] = dict() diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/connection.py b/plugins/ldap-user-sync/vendor/ldap3/core/connection.py new file mode 100644 index 00000000..c062d3aa --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/connection.py @@ -0,0 +1,1605 @@ +""" +""" + +# Created on 2014.05.31 +# +# 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 . +from copy import deepcopy, copy +from os import linesep +from threading import RLock +from functools import reduce +import json + +from .. import ANONYMOUS, SIMPLE, SASL, MODIFY_ADD, MODIFY_DELETE, MODIFY_REPLACE, get_config_parameter, DEREF_ALWAYS, \ + SUBTREE, ASYNC, SYNC, NO_ATTRIBUTES, ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, MODIFY_INCREMENT, LDIF, ASYNC_STREAM, \ + RESTARTABLE, ROUND_ROBIN, REUSABLE, AUTO_BIND_DEFAULT, AUTO_BIND_NONE, AUTO_BIND_TLS_BEFORE_BIND, SAFE_SYNC, SAFE_RESTARTABLE, \ + AUTO_BIND_TLS_AFTER_BIND, AUTO_BIND_NO_TLS, STRING_TYPES, SEQUENCE_TYPES, MOCK_SYNC, MOCK_ASYNC, NTLM, EXTERNAL,\ + DIGEST_MD5, GSSAPI, PLAIN, DSA, SCHEMA, ALL + +from .results import RESULT_SUCCESS, RESULT_COMPARE_TRUE, RESULT_COMPARE_FALSE +from ..extend import ExtendedOperationsRoot +from .pooling import ServerPool +from .server import Server +from ..operation.abandon import abandon_operation, abandon_request_to_dict +from ..operation.add import add_operation, add_request_to_dict +from ..operation.bind import bind_operation, bind_request_to_dict +from ..operation.compare import compare_operation, compare_request_to_dict +from ..operation.delete import delete_operation, delete_request_to_dict +from ..operation.extended import extended_operation, extended_request_to_dict +from ..operation.modify import modify_operation, modify_request_to_dict +from ..operation.modifyDn import modify_dn_operation, modify_dn_request_to_dict +from ..operation.search import search_operation, search_request_to_dict +from ..protocol.rfc2849 import operation_to_ldif, add_ldif_header +from ..protocol.sasl.digestMd5 import sasl_digest_md5 +from ..protocol.sasl.external import sasl_external +from ..protocol.sasl.plain import sasl_plain +from ..strategy.sync import SyncStrategy +from ..strategy.safeSync import SafeSyncStrategy +from ..strategy.safeRestartable import SafeRestartableStrategy +from ..strategy.mockAsync import MockAsyncStrategy +from ..strategy.asynchronous import AsyncStrategy +from ..strategy.reusable import ReusableStrategy +from ..strategy.restartable import RestartableStrategy +from ..strategy.ldifProducer import LdifProducerStrategy +from ..strategy.mockSync import MockSyncStrategy +from ..strategy.asyncStream import AsyncStreamStrategy +from ..operation.unbind import unbind_operation +from ..protocol.rfc2696 import paged_search_control +from .usage import ConnectionUsage +from .tls import Tls +from .exceptions import LDAPUnknownStrategyError, LDAPBindError, LDAPUnknownAuthenticationMethodError, \ + LDAPSASLMechanismNotSupportedError, LDAPObjectClassError, LDAPConnectionIsReadOnlyError, LDAPChangeError, LDAPExceptionError, \ + LDAPObjectError, LDAPSocketReceiveError, LDAPAttributeError, LDAPInvalidValueError, LDAPInvalidPortError, LDAPStartTLSError + +from ..utils.conv import escape_bytes, prepare_for_stream, check_json_dict, format_json, to_unicode +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED, get_library_log_hide_sensitive_data +from ..utils.dn import safe_dn +from ..utils.port_validators import check_port_and_port_list + + +SASL_AVAILABLE_MECHANISMS = [EXTERNAL, + DIGEST_MD5, + GSSAPI, + PLAIN] + +CLIENT_STRATEGIES = [SYNC, + SAFE_SYNC, + SAFE_RESTARTABLE, + ASYNC, + LDIF, + RESTARTABLE, + REUSABLE, + MOCK_SYNC, + MOCK_ASYNC, + ASYNC_STREAM] + + +def _format_socket_endpoint(endpoint): + if endpoint and len(endpoint) == 2: # IPv4 + return str(endpoint[0]) + ':' + str(endpoint[1]) + elif endpoint and len(endpoint) == 4: # IPv6 + return '[' + str(endpoint[0]) + ']:' + str(endpoint[1]) + + try: + return str(endpoint) + except Exception: + return '?' + + +def _format_socket_endpoints(sock): + if sock: + try: + local = sock.getsockname() + except Exception: + local = (None, None, None, None) + try: + remote = sock.getpeername() + except Exception: + remote = (None, None, None, None) + + return '' + return '' + + +class Connection(object): + """Main ldap connection class. + + Controls, if used, must be a list of tuples. Each tuple must have 3 + elements, the control OID, a boolean meaning if the control is + critical, a value. + + If the boolean is set to True the server must honor the control or + refuse the operation + + Mixing controls must be defined in controls specification (as per + RFC 4511) + + :param server: the Server object to connect to + :type server: Server, str + :param user: the user name for simple authentication + :type user: str + :param password: the password for simple authentication + :type password: str + :param auto_bind: specify if the bind will be performed automatically when defining the Connection object + :type auto_bind: int, can be one of AUTO_BIND_DEFAULT, AUTO_BIND_NONE, AUTO_BIND_NO_TLS, AUTO_BIND_TLS_BEFORE_BIND, AUTO_BIND_TLS_AFTER_BIND as specified in ldap3 + :param version: LDAP version, default to 3 + :type version: int + :param authentication: type of authentication + :type authentication: int, can be one of ANONYMOUS, SIMPLE or SASL, as specified in ldap3 + :param client_strategy: communication strategy used in the Connection + :type client_strategy: can be one of SYNC, ASYNC, LDIF, RESTARTABLE, REUSABLE as specified in ldap3 + :param auto_referrals: specify if the connection object must automatically follow referrals + :type auto_referrals: bool + :param sasl_mechanism: mechanism for SASL authentication, can be one of 'EXTERNAL', 'DIGEST-MD5', 'GSSAPI', 'PLAIN' + :type sasl_mechanism: str + :param sasl_credentials: credentials for SASL mechanism + :type sasl_credentials: tuple + :param check_names: if True the library will check names of attributes and object classes against the schema. Also values found in entries will be formatted as indicated by the schema + :type check_names: bool + :param collect_usage: collect usage metrics in the usage attribute + :type collect_usage: bool + :param read_only: disable operations that modify data in the LDAP server + :type read_only: bool + :param lazy: open and bind the connection only when an actual operation is performed + :type lazy: bool + :param raise_exceptions: raise exceptions when operations are not successful, if False operations return False if not successful but not raise exceptions + :type raise_exceptions: bool + :param pool_name: pool name for pooled strategies + :type pool_name: str + :param pool_size: pool size for pooled strategies + :type pool_size: int + :param pool_lifetime: pool lifetime for pooled strategies + :type pool_lifetime: int + :param cred_store: credential store for gssapi + :type cred_store: dict + :param use_referral_cache: keep referral connections open and reuse them + :type use_referral_cache: bool + :param auto_escape: automatic escaping of filter values + :type auto_escape: bool + :param auto_encode: automatic encoding of attribute values + :type auto_encode: bool + :param source_address: the ip address or hostname to use as the source when opening the connection to the server + :type source_address: str + :param source_port: the source port to use when opening the connection to the server. Cannot be specified with source_port_list + :type source_port: int + :param source_port_list: a list of source ports to choose from when opening the connection to the server. Cannot be specified with source_port + :type source_port_list: list + """ + def __init__(self, + server, + user=None, + password=None, + auto_bind=AUTO_BIND_DEFAULT, + version=3, + authentication=None, + client_strategy=SYNC, + auto_referrals=True, + auto_range=True, + sasl_mechanism=None, + sasl_credentials=None, + check_names=True, + collect_usage=False, + read_only=False, + lazy=False, + raise_exceptions=False, + pool_name=None, + pool_size=None, + pool_lifetime=None, + cred_store=None, + fast_decoder=True, + receive_timeout=None, + return_empty_attributes=True, + use_referral_cache=False, + auto_escape=True, + auto_encode=True, + pool_keepalive=None, + source_address=None, + source_port=None, + source_port_list=None): + + conf_default_pool_name = get_config_parameter('DEFAULT_THREADED_POOL_NAME') + self.connection_lock = RLock() # re-entrant lock to ensure that operations in the Connection object are executed atomically in the same thread + with self.connection_lock: + if client_strategy not in CLIENT_STRATEGIES: + self.last_error = 'unknown client connection strategy' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownStrategyError(self.last_error) + + self.strategy_type = client_strategy + self.user = user + self.password = password + + if not authentication and self.user: + self.authentication = SIMPLE + elif not authentication: + self.authentication = ANONYMOUS + elif authentication in [SIMPLE, ANONYMOUS, SASL, NTLM]: + self.authentication = authentication + else: + self.last_error = 'unknown authentication method' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownAuthenticationMethodError(self.last_error) + + self.version = version + self.auto_referrals = True if auto_referrals else False + self.request = None + self.response = None + self.result = None + self.bound = False + self.listening = False + self.closed = True + self.last_error = None + if auto_bind is False: # compatibility with older version where auto_bind was a boolean + self.auto_bind = AUTO_BIND_DEFAULT + elif auto_bind is True: + self.auto_bind = AUTO_BIND_NO_TLS + else: + self.auto_bind = auto_bind + self.sasl_mechanism = sasl_mechanism + self.sasl_credentials = sasl_credentials + self._usage = ConnectionUsage() if collect_usage else None + self.socket = None + self.tls_started = False + self.sasl_in_progress = False + self.read_only = read_only + self._context_state = [] + self._deferred_open = False + self._deferred_bind = False + self._deferred_start_tls = False + self._bind_controls = None + self._executing_deferred = False + self.lazy = lazy + self.pool_name = pool_name if pool_name else conf_default_pool_name + self.pool_size = pool_size + self.cred_store = cred_store + self.pool_lifetime = pool_lifetime + self.pool_keepalive = pool_keepalive + self.starting_tls = False + self.check_names = check_names + self.raise_exceptions = raise_exceptions + self.auto_range = True if auto_range else False + self.extend = ExtendedOperationsRoot(self) + self._entries = [] + self.fast_decoder = fast_decoder + self.receive_timeout = receive_timeout + self.empty_attributes = return_empty_attributes + self.use_referral_cache = use_referral_cache + self.auto_escape = auto_escape + self.auto_encode = auto_encode + self._digest_md5_kic = None + self._digest_md5_kis = None + self._digest_md5_sec_num = 0 + + port_err = check_port_and_port_list(source_port, source_port_list) + if port_err: + if log_enabled(ERROR): + log(ERROR, port_err) + raise LDAPInvalidPortError(port_err) + # using an empty string to bind a socket means "use the default as if this wasn't provided" because socket + # binding requires that you pass something for the ip if you want to pass a specific port + self.source_address = source_address if source_address is not None else '' + # using 0 as the source port to bind a socket means "use the default behavior of picking a random port from + # all ports as if this wasn't provided" because socket binding requires that you pass something for the port + # if you want to pass a specific ip + self.source_port_list = [0] + if source_port is not None: + self.source_port_list = [source_port] + elif source_port_list is not None: + self.source_port_list = source_port_list[:] + + if isinstance(server, STRING_TYPES): + server = Server(server) + if isinstance(server, SEQUENCE_TYPES): + server = ServerPool(server, ROUND_ROBIN, active=True, exhaust=True) + + if isinstance(server, ServerPool): + self.server_pool = server + self.server_pool.initialize(self) + self.server = self.server_pool.get_current_server(self) + else: + self.server_pool = None + self.server = server + + # if self.authentication == SIMPLE and self.user and self.check_names: + # self.user = safe_dn(self.user) + # if log_enabled(EXTENDED): + # log(EXTENDED, 'user name sanitized to <%s> for simple authentication via <%s>', self.user, self) + + if self.strategy_type == SYNC: + self.strategy = SyncStrategy(self) + elif self.strategy_type == SAFE_SYNC: + self.strategy = SafeSyncStrategy(self) + elif self.strategy_type == SAFE_RESTARTABLE: + self.strategy = SafeRestartableStrategy(self) + elif self.strategy_type == ASYNC: + self.strategy = AsyncStrategy(self) + elif self.strategy_type == LDIF: + self.strategy = LdifProducerStrategy(self) + elif self.strategy_type == RESTARTABLE: + self.strategy = RestartableStrategy(self) + elif self.strategy_type == REUSABLE: + self.strategy = ReusableStrategy(self) + self.lazy = False + elif self.strategy_type == MOCK_SYNC: + self.strategy = MockSyncStrategy(self) + elif self.strategy_type == MOCK_ASYNC: + self.strategy = MockAsyncStrategy(self) + elif self.strategy_type == ASYNC_STREAM: + self.strategy = AsyncStreamStrategy(self) + else: + self.last_error = 'unknown strategy' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownStrategyError(self.last_error) + + # maps strategy functions to connection functions + self.send = self.strategy.send + self.open = self.strategy.open + self.get_response = self.strategy.get_response + self.post_send_single_response = self.strategy.post_send_single_response + self.post_send_search = self.strategy.post_send_search + + if not self.strategy.no_real_dsa: + self._do_auto_bind() + # else: # for strategies with a fake server set get_info to NONE if server hasn't a schema + # if self.server and not self.server.schema: + # self.server.get_info = NONE + if log_enabled(BASIC): + if get_library_log_hide_sensitive_data(): + log(BASIC, 'instantiated Connection: <%s>', self.repr_with_sensitive_data_stripped()) + else: + log(BASIC, 'instantiated Connection: <%r>', self) + + def _prepare_return_value(self, status, response=False): + if self.strategy.thread_safe: + temp_response = self.response + self.response = None + temp_request = self.request + self.request = None + return status, deepcopy(self.result), deepcopy(temp_response) if response else None, copy(temp_request) + return status + + def _do_auto_bind(self): + if self.auto_bind and self.auto_bind not in [AUTO_BIND_NONE, AUTO_BIND_DEFAULT]: + if log_enabled(BASIC): + log(BASIC, 'performing automatic bind for <%s>', self) + if self.closed: + self.open(read_server_info=False) + if self.auto_bind == AUTO_BIND_NO_TLS: + self.bind(read_server_info=True) + elif self.auto_bind == AUTO_BIND_TLS_BEFORE_BIND: + if self.start_tls(read_server_info=False): + self.bind(read_server_info=True) + else: + error = 'automatic start_tls befored bind not successful' + (' - ' + self.last_error if self.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.unbind() # unbind anyway to close connection + raise LDAPStartTLSError(error) + elif self.auto_bind == AUTO_BIND_TLS_AFTER_BIND: + self.bind(read_server_info=False) + if not self.start_tls(read_server_info=True): + error = 'automatic start_tls after bind not successful' + (' - ' + self.last_error if self.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.unbind() + raise LDAPStartTLSError(error) + if not self.bound: + error = 'automatic bind not successful' + (' - ' + self.last_error if self.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.unbind() + raise LDAPBindError(error) + + def __str__(self): + s = [ + str(self.server) if self.server else 'None', + 'user: ' + str(self.user), + 'lazy' if self.lazy else 'not lazy', + 'unbound' if not self.bound else ('deferred bind' if self._deferred_bind else 'bound'), + 'closed' if self.closed else ('deferred open' if self._deferred_open else 'open'), + _format_socket_endpoints(self.socket), + 'tls not started' if not self.tls_started else('deferred start_tls' if self._deferred_start_tls else 'tls started'), + 'listening' if self.listening else 'not listening', + self.strategy.__class__.__name__ if hasattr(self, 'strategy') else 'No strategy', + 'internal decoder' if self.fast_decoder else 'pyasn1 decoder' + ] + return ' - '.join(s) + + def __repr__(self): + conf_default_pool_name = get_config_parameter('DEFAULT_THREADED_POOL_NAME') + if self.server_pool: + r = 'Connection(server={0.server_pool!r}'.format(self) + else: + r = 'Connection(server={0.server!r}'.format(self) + r += '' if self.user is None else ', user={0.user!r}'.format(self) + r += '' if self.password is None else ', password={0.password!r}'.format(self) + r += '' if self.auto_bind is None else ', auto_bind={0.auto_bind!r}'.format(self) + r += '' if self.version is None else ', version={0.version!r}'.format(self) + r += '' if self.authentication is None else ', authentication={0.authentication!r}'.format(self) + r += '' if self.strategy_type is None else ', client_strategy={0.strategy_type!r}'.format(self) + r += '' if self.auto_referrals is None else ', auto_referrals={0.auto_referrals!r}'.format(self) + r += '' if self.sasl_mechanism is None else ', sasl_mechanism={0.sasl_mechanism!r}'.format(self) + r += '' if self.sasl_credentials is None else ', sasl_credentials={0.sasl_credentials!r}'.format(self) + r += '' if self.check_names is None else ', check_names={0.check_names!r}'.format(self) + r += '' if self.usage is None else (', collect_usage=' + ('True' if self.usage else 'False')) + r += '' if self.read_only is None else ', read_only={0.read_only!r}'.format(self) + r += '' if self.lazy is None else ', lazy={0.lazy!r}'.format(self) + r += '' if self.raise_exceptions is None else ', raise_exceptions={0.raise_exceptions!r}'.format(self) + r += '' if (self.pool_name is None or self.pool_name == conf_default_pool_name) else ', pool_name={0.pool_name!r}'.format(self) + r += '' if self.pool_size is None else ', pool_size={0.pool_size!r}'.format(self) + r += '' if self.pool_lifetime is None else ', pool_lifetime={0.pool_lifetime!r}'.format(self) + r += '' if self.pool_keepalive is None else ', pool_keepalive={0.pool_keepalive!r}'.format(self) + r += '' if self.cred_store is None else (', cred_store=' + repr(self.cred_store)) + r += '' if self.fast_decoder is None else (', fast_decoder=' + ('True' if self.fast_decoder else 'False')) + r += '' if self.auto_range is None else (', auto_range=' + ('True' if self.auto_range else 'False')) + r += '' if self.receive_timeout is None else ', receive_timeout={0.receive_timeout!r}'.format(self) + r += '' if self.empty_attributes is None else (', return_empty_attributes=' + ('True' if self.empty_attributes else 'False')) + r += '' if self.auto_encode is None else (', auto_encode=' + ('True' if self.auto_encode else 'False')) + r += '' if self.auto_escape is None else (', auto_escape=' + ('True' if self.auto_escape else 'False')) + r += '' if self.use_referral_cache is None else (', use_referral_cache=' + ('True' if self.use_referral_cache else 'False')) + r += ')' + + return r + + def repr_with_sensitive_data_stripped(self): + conf_default_pool_name = get_config_parameter('DEFAULT_THREADED_POOL_NAME') + if self.server_pool: + r = 'Connection(server={0.server_pool!r}'.format(self) + else: + r = 'Connection(server={0.server!r}'.format(self) + r += '' if self.user is None else ', user={0.user!r}'.format(self) + r += '' if self.password is None else ", password='{0}'".format('' % len(self.password)) + r += '' if self.auto_bind is None else ', auto_bind={0.auto_bind!r}'.format(self) + r += '' if self.version is None else ', version={0.version!r}'.format(self) + r += '' if self.authentication is None else ', authentication={0.authentication!r}'.format(self) + r += '' if self.strategy_type is None else ', client_strategy={0.strategy_type!r}'.format(self) + r += '' if self.auto_referrals is None else ', auto_referrals={0.auto_referrals!r}'.format(self) + r += '' if self.sasl_mechanism is None else ', sasl_mechanism={0.sasl_mechanism!r}'.format(self) + if self.sasl_mechanism == DIGEST_MD5: + r += '' if self.sasl_credentials is None else ", sasl_credentials=({0!r}, {1!r}, '{2}', {3!r})".format(self.sasl_credentials[0], self.sasl_credentials[1], '*' * len(self.sasl_credentials[2]), self.sasl_credentials[3]) + else: + r += '' if self.sasl_credentials is None else ', sasl_credentials={0.sasl_credentials!r}'.format(self) + r += '' if self.check_names is None else ', check_names={0.check_names!r}'.format(self) + r += '' if self.usage is None else (', collect_usage=' + 'True' if self.usage else 'False') + r += '' if self.read_only is None else ', read_only={0.read_only!r}'.format(self) + r += '' if self.lazy is None else ', lazy={0.lazy!r}'.format(self) + r += '' if self.raise_exceptions is None else ', raise_exceptions={0.raise_exceptions!r}'.format(self) + r += '' if (self.pool_name is None or self.pool_name == conf_default_pool_name) else ', pool_name={0.pool_name!r}'.format(self) + r += '' if self.pool_size is None else ', pool_size={0.pool_size!r}'.format(self) + r += '' if self.pool_lifetime is None else ', pool_lifetime={0.pool_lifetime!r}'.format(self) + r += '' if self.pool_keepalive is None else ', pool_keepalive={0.pool_keepalive!r}'.format(self) + r += '' if self.cred_store is None else (', cred_store=' + repr(self.cred_store)) + r += '' if self.fast_decoder is None else (', fast_decoder=' + 'True' if self.fast_decoder else 'False') + r += '' if self.auto_range is None else (', auto_range=' + ('True' if self.auto_range else 'False')) + r += '' if self.receive_timeout is None else ', receive_timeout={0.receive_timeout!r}'.format(self) + r += '' if self.empty_attributes is None else (', return_empty_attributes=' + 'True' if self.empty_attributes else 'False') + r += '' if self.auto_encode is None else (', auto_encode=' + ('True' if self.auto_encode else 'False')) + r += '' if self.auto_escape is None else (', auto_escape=' + ('True' if self.auto_escape else 'False')) + r += '' if self.use_referral_cache is None else (', use_referral_cache=' + ('True' if self.use_referral_cache else 'False')) + r += ')' + + return r + + @property + def stream(self): + """Used by the LDIFProducer strategy to accumulate the ldif-change operations with a single LDIF header + :return: reference to the response stream if defined in the strategy. + """ + return self.strategy.get_stream() if self.strategy.can_stream else None + + @stream.setter + def stream(self, value): + with self.connection_lock: + if self.strategy.can_stream: + self.strategy.set_stream(value) + + @property + def usage(self): + """Usage statistics for the connection. + :return: Usage object + """ + if not self._usage: + return None + if self.strategy.pooled: # update master connection usage from pooled connections + self._usage.reset() + for worker in self.strategy.pool.workers: + self._usage += worker.connection.usage + self._usage += self.strategy.pool.terminated_usage + return self._usage + + def __enter__(self): + with self.connection_lock: + self._context_state.append((self.bound, self.closed)) # save status out of context as a tuple in a list + if self.auto_bind != AUTO_BIND_NONE: + if self.auto_bind == AUTO_BIND_DEFAULT: + self.auto_bind = AUTO_BIND_NO_TLS + if self.closed: + self.open() + if not self.bound: + if not self.bind(): + raise LDAPBindError('unable to bind') + + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + with self.connection_lock: + context_bound, context_closed = self._context_state.pop() + if (not context_bound and self.bound) or self.stream: # restore status prior to entering context + try: + self.unbind() + except LDAPExceptionError: + pass + + if not context_closed and self.closed: + self.open() + + if exc_type is not None: + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', exc_type, self) + return False # re-raise LDAPExceptionError + + def bind(self, + read_server_info=True, + controls=None): + """Bind to ldap Server with the authentication method and the user defined in the connection + + :param read_server_info: reads info from server + :param controls: LDAP controls to send along with the bind operation + :type controls: list of tuple + :return: bool + + """ + if log_enabled(BASIC): + log(BASIC, 'start BIND operation via <%s>', self) + self.last_error = None + with self.connection_lock: + if self.lazy and not self._executing_deferred: + if self.strategy.pooled: + self.strategy.validate_bind(controls) + self._deferred_bind = True + self._bind_controls = controls + self.bound = True + if log_enabled(BASIC): + log(BASIC, 'deferring bind for <%s>', self) + else: + self._deferred_bind = False + self._bind_controls = None + if self.closed: # try to open connection if closed + self.open(read_server_info=False) + if self.authentication == ANONYMOUS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing anonymous BIND for <%s>', self) + if not self.strategy.pooled: + request = bind_operation(self.version, self.authentication, self.user, '', auto_encode=self.auto_encode) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'anonymous BIND request <%s> sent via <%s>', bind_request_to_dict(request), self) + response = self.post_send_single_response(self.send('bindRequest', request, controls)) + else: + response = self.strategy.validate_bind(controls) # only for REUSABLE + elif self.authentication == SIMPLE: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing simple BIND for <%s>', self) + if not self.strategy.pooled: + request = bind_operation(self.version, self.authentication, self.user, self.password, auto_encode=self.auto_encode) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'simple BIND request <%s> sent via <%s>', bind_request_to_dict(request), self) + response = self.post_send_single_response(self.send('bindRequest', request, controls)) + else: + response = self.strategy.validate_bind(controls) # only for REUSABLE + elif self.authentication == SASL: + if self.sasl_mechanism in SASL_AVAILABLE_MECHANISMS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing SASL BIND for <%s>', self) + if not self.strategy.pooled: + response = self.do_sasl_bind(controls) + else: + response = self.strategy.validate_bind(controls) # only for REUSABLE + else: + self.last_error = 'requested SASL mechanism not supported' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPSASLMechanismNotSupportedError(self.last_error) + elif self.authentication == NTLM: + if self.user and self.password and len(self.user.split('\\')) == 2: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing NTLM BIND for <%s>', self) + if not self.strategy.pooled: + response = self.do_ntlm_bind(controls) + else: + response = self.strategy.validate_bind(controls) # only for REUSABLE + else: # user or password missing + self.last_error = 'NTLM needs domain\\username and a password' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownAuthenticationMethodError(self.last_error) + else: + self.last_error = 'unknown authentication method' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownAuthenticationMethodError(self.last_error) + + if not self.strategy.sync and not self.strategy.pooled and self.authentication not in (SASL, NTLM): # get response if asynchronous except for SASL and NTLM that return the bind result even for asynchronous strategy + _, result = self.get_response(response) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async BIND response id <%s> received via <%s>', result, self) + elif self.strategy.sync: + result = self.result + if log_enabled(PROTOCOL): + log(PROTOCOL, 'BIND response <%s> received via <%s>', result, self) + elif self.strategy.pooled or self.authentication in (SASL, NTLM): # asynchronous SASL and NTLM or reusable strtegy get the bind result synchronously + result = response + else: + self.last_error = 'unknown authentication method' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownAuthenticationMethodError(self.last_error) + + if result is None: + # self.bound = True if self.strategy_type == REUSABLE else False + self.bound = False + elif result is True: + self.bound = True + elif result is False: + self.bound = False + else: + self.bound = True if result['result'] == RESULT_SUCCESS else False + if not self.bound and result and result['description'] and not self.last_error: + self.last_error = result['description'] + + if read_server_info and self.bound: + self.refresh_server_info() + self._entries = [] + + if log_enabled(BASIC): + log(BASIC, 'done BIND operation, result <%s>', self.bound) + + return self._prepare_return_value(self.bound, self.result) + + def rebind(self, + user=None, + password=None, + authentication=None, + sasl_mechanism=None, + sasl_credentials=None, + read_server_info=True, + controls=None + ): + + if log_enabled(BASIC): + log(BASIC, 'start (RE)BIND operation via <%s>', self) + self.last_error = None + with self.connection_lock: + if user: + self.user = user + if password is not None: + self.password = password + if not authentication and user: + self.authentication = SIMPLE + if authentication in [SIMPLE, ANONYMOUS, SASL, NTLM]: + self.authentication = authentication + elif authentication is not None: + self.last_error = 'unknown authentication method' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPUnknownAuthenticationMethodError(self.last_error) + if sasl_mechanism: + self.sasl_mechanism = sasl_mechanism + if sasl_credentials: + self.sasl_credentials = sasl_credentials + + # if self.authentication == SIMPLE and self.user and self.check_names: + # self.user = safe_dn(self.user) + # if log_enabled(EXTENDED): + # log(EXTENDED, 'user name sanitized to <%s> for rebind via <%s>', self.user, self) + + if not self.strategy.pooled: + try: + return self.bind(read_server_info, controls) + except LDAPSocketReceiveError: + self.last_error = 'Unable to rebind as a different user, furthermore the server abruptly closed the connection' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPBindError(self.last_error) + else: + self.strategy.pool.rebind_pool() + return self._prepare_return_value(True, self.result) + + def unbind(self, + controls=None): + """Unbind the connected user. Unbind implies closing session as per RFC4511 (4.3) + + :param controls: LDAP controls to send along with the bind operation + + """ + if log_enabled(BASIC): + log(BASIC, 'start UNBIND operation via <%s>', self) + + if self.use_referral_cache: + self.strategy.unbind_referral_cache() + + self.last_error = None + with self.connection_lock: + if self.lazy and not self._executing_deferred and (self._deferred_bind or self._deferred_open): # _clear deferred status + self.strategy.close() + self._deferred_open = False + self._deferred_bind = False + self._deferred_start_tls = False + elif not self.closed: + request = unbind_operation() + if log_enabled(PROTOCOL): + log(PROTOCOL, 'UNBIND request sent via <%s>', self) + self.send('unbindRequest', request, controls) + self.strategy.close() + + if log_enabled(BASIC): + log(BASIC, 'done UNBIND operation, result <%s>', True) + + return self._prepare_return_value(True) + + def search(self, + search_base, + search_filter, + search_scope=SUBTREE, + dereference_aliases=DEREF_ALWAYS, + attributes=None, + size_limit=0, + time_limit=0, + types_only=False, + get_operational_attributes=False, + controls=None, + paged_size=None, + paged_criticality=False, + paged_cookie=None, + auto_escape=None): + """ + Perform an ldap search: + + - If attributes is empty noRFC2696 with the specified size + - If paged is 0 and cookie is present the search is abandoned on + server attribute is returned + - If attributes is ALL_ATTRIBUTES all attributes are returned + - If paged_size is an int greater than 0 a simple paged search + is tried as described in + - Cookie is an opaque string received in the last paged search + and must be used on the next paged search response + - If lazy == True open and bind will be deferred until another + LDAP operation is performed + - If mssing_attributes == True then an attribute not returned by the server is set to None + - If auto_escape is set it overrides the Connection auto_escape + """ + conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')] + if log_enabled(BASIC): + log(BASIC, 'start SEARCH operation via <%s>', self) + + if self.check_names and search_base: + search_base = safe_dn(search_base) + if log_enabled(EXTENDED): + log(EXTENDED, 'search base sanitized to <%s> for SEARCH operation via <%s>', search_base, self) + + with self.connection_lock: + self._fire_deferred() + if not attributes: + attributes = [NO_ATTRIBUTES] + elif attributes == ALL_ATTRIBUTES: + attributes = [ALL_ATTRIBUTES] + + if isinstance(attributes, STRING_TYPES): + attributes = [attributes] + + if get_operational_attributes and isinstance(attributes, list): + attributes.append(ALL_OPERATIONAL_ATTRIBUTES) + elif get_operational_attributes and isinstance(attributes, tuple): + attributes += (ALL_OPERATIONAL_ATTRIBUTES, ) # concatenate tuple + + if isinstance(paged_size, int): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing paged search for %d items with cookie <%s> for <%s>', paged_size, escape_bytes(paged_cookie), self) + + if controls is None: + controls = [] + else: + # Copy the controls to prevent modifying the original object + controls = list(controls) + controls.append(paged_search_control(paged_criticality, paged_size, paged_cookie)) + + if self.server and self.server.schema and self.check_names: + for attribute_name in attributes: + if ';' in attribute_name: # remove tags + attribute_name_to_check = attribute_name.split(';')[0] + else: + attribute_name_to_check = attribute_name + if self.server.schema and attribute_name_to_check.lower() not in conf_attributes_excluded_from_check and attribute_name_to_check not in self.server.schema.attribute_types: + self.last_error = 'invalid attribute type ' + attribute_name_to_check + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPAttributeError(self.last_error) + + request = search_operation(search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + self.auto_escape if auto_escape is None else auto_escape, + self.auto_encode, + self.server.schema if self.server else None, + validator=self.server.custom_validator, + check_names=self.check_names) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'SEARCH request <%s> sent via <%s>', search_request_to_dict(request), self) + response = self.post_send_search(self.send('searchRequest', request, controls)) + self._entries = [] + + if isinstance(response, int): # asynchronous strategy + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async SEARCH response id <%s> received via <%s>', return_value, self) + else: + return_value = True if self.result['type'] == 'searchResDone' and len(response) > 0 else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(PROTOCOL): + for entry in response: + if entry['type'] == 'searchResEntry': + log(PROTOCOL, 'SEARCH response entry <%s> received via <%s>', entry, self) + elif entry['type'] == 'searchResRef': + log(PROTOCOL, 'SEARCH response reference <%s> received via <%s>', entry, self) + + if log_enabled(BASIC): + log(BASIC, 'done SEARCH operation, result <%s>', return_value) + + return self._prepare_return_value(return_value, response=True) + + def compare(self, + dn, + attribute, + value, + controls=None): + """ + Perform a compare operation + """ + conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')] + + if log_enabled(BASIC): + log(BASIC, 'start COMPARE operation via <%s>', self) + self.last_error = None + if self.check_names: + dn = safe_dn(dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'dn sanitized to <%s> for COMPARE operation via <%s>', dn, self) + + if self.server and self.server.schema and self.check_names: + if ';' in attribute: # remove tags for checking + attribute_name_to_check = attribute.split(';')[0] + else: + attribute_name_to_check = attribute + + if self.server.schema.attribute_types and attribute_name_to_check.lower() not in conf_attributes_excluded_from_check and attribute_name_to_check not in self.server.schema.attribute_types: + self.last_error = 'invalid attribute type ' + attribute_name_to_check + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPAttributeError(self.last_error) + + if isinstance(value, SEQUENCE_TYPES): # value can't be a sequence + self.last_error = 'value cannot be a sequence' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPInvalidValueError(self.last_error) + + with self.connection_lock: + self._fire_deferred() + request = compare_operation(dn, attribute, value, self.auto_encode, self.server.schema if self.server else None, validator=self.server.custom_validator if self.server else None, check_names=self.check_names) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'COMPARE request <%s> sent via <%s>', compare_request_to_dict(request), self) + response = self.post_send_single_response(self.send('compareRequest', request, controls)) + self._entries = [] + if isinstance(response, int): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async COMPARE response id <%s> received via <%s>', return_value, self) + else: + return_value = True if self.result['type'] == 'compareResponse' and self.result['result'] == RESULT_COMPARE_TRUE else False + if not return_value and self.result['result'] not in [RESULT_COMPARE_TRUE, RESULT_COMPARE_FALSE] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(PROTOCOL): + log(PROTOCOL, 'COMPARE response <%s> received via <%s>', response, self) + + if log_enabled(BASIC): + log(BASIC, 'done COMPARE operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def add(self, + dn, + object_class=None, + attributes=None, + controls=None): + """ + Add dn to the DIT, object_class is None, a class name or a list + of class names. + + Attributes is a dictionary in the form 'attr': 'val' or 'attr': + ['val1', 'val2', ...] for multivalued attributes + """ + conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')] + conf_classes_excluded_from_check = [v.lower() for v in get_config_parameter('CLASSES_EXCLUDED_FROM_CHECK')] + if log_enabled(BASIC): + log(BASIC, 'start ADD operation via <%s>', self) + self.last_error = None + _attributes = deepcopy(attributes) # dict could change when adding objectClass values + if self.check_names: + dn = safe_dn(dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'dn sanitized to <%s> for ADD operation via <%s>', dn, self) + + with self.connection_lock: + self._fire_deferred() + attr_object_class = [] + if object_class is None: + parm_object_class = [] + else: + parm_object_class = list(object_class) if isinstance(object_class, SEQUENCE_TYPES) else [object_class] + + object_class_attr_name = '' + if _attributes: + for attr in _attributes: + if attr.lower() == 'objectclass': + object_class_attr_name = attr + attr_object_class = list(_attributes[object_class_attr_name]) if isinstance(_attributes[object_class_attr_name], SEQUENCE_TYPES) else [_attributes[object_class_attr_name]] + break + else: + _attributes = dict() + + if not object_class_attr_name: + object_class_attr_name = 'objectClass' + + attr_object_class = [to_unicode(object_class) for object_class in attr_object_class] # converts objectclass to unicode in case of bytes value + _attributes[object_class_attr_name] = reduce(lambda x, y: x + [y] if y not in x else x, parm_object_class + attr_object_class, []) # remove duplicate ObjectClasses + + if not _attributes[object_class_attr_name]: + self.last_error = 'objectClass attribute is mandatory' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPObjectClassError(self.last_error) + + if self.server and self.server.schema and self.check_names: + for object_class_name in _attributes[object_class_attr_name]: + if object_class_name.lower() not in conf_classes_excluded_from_check and object_class_name not in self.server.schema.object_classes: + self.last_error = 'invalid object class ' + str(object_class_name) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPObjectClassError(self.last_error) + + for attribute_name in _attributes: + if ';' in attribute_name: # remove tags for checking + attribute_name_to_check = attribute_name.split(';')[0] + else: + attribute_name_to_check = attribute_name + + if attribute_name_to_check.lower() not in conf_attributes_excluded_from_check and attribute_name_to_check not in self.server.schema.attribute_types: + self.last_error = 'invalid attribute type ' + attribute_name_to_check + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPAttributeError(self.last_error) + + request = add_operation(dn, _attributes, self.auto_encode, self.server.schema if self.server else None, validator=self.server.custom_validator if self.server else None, check_names=self.check_names) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'ADD request <%s> sent via <%s>', add_request_to_dict(request), self) + response = self.post_send_single_response(self.send('addRequest', request, controls)) + self._entries = [] + + if isinstance(response, STRING_TYPES + (int, )): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async ADD response id <%s> received via <%s>', return_value, self) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'ADD response <%s> received via <%s>', response, self) + return_value = True if self.result['type'] == 'addResponse' and self.result['result'] == RESULT_SUCCESS else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(BASIC): + log(BASIC, 'done ADD operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def delete(self, + dn, + controls=None): + """ + Delete the entry identified by the DN from the DIB. + """ + if log_enabled(BASIC): + log(BASIC, 'start DELETE operation via <%s>', self) + self.last_error = None + if self.check_names: + dn = safe_dn(dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'dn sanitized to <%s> for DELETE operation via <%s>', dn, self) + + with self.connection_lock: + self._fire_deferred() + if self.read_only: + self.last_error = 'connection is read-only' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPConnectionIsReadOnlyError(self.last_error) + + request = delete_operation(dn) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'DELETE request <%s> sent via <%s>', delete_request_to_dict(request), self) + response = self.post_send_single_response(self.send('delRequest', request, controls)) + self._entries = [] + + if isinstance(response, STRING_TYPES + (int, )): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async DELETE response id <%s> received via <%s>', return_value, self) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'DELETE response <%s> received via <%s>', response, self) + return_value = True if self.result['type'] == 'delResponse' and self.result['result'] == RESULT_SUCCESS else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(BASIC): + log(BASIC, 'done DELETE operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def modify(self, + dn, + changes, + controls=None): + """ + Modify attributes of entry + + - changes is a dictionary in the form {'attribute1': change), 'attribute2': [change, change, ...], ...} + - change is (operation, [value1, value2, ...]) + - operation is 0 (MODIFY_ADD), 1 (MODIFY_DELETE), 2 (MODIFY_REPLACE), 3 (MODIFY_INCREMENT) + """ + conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')] + + if log_enabled(BASIC): + log(BASIC, 'start MODIFY operation via <%s>', self) + self.last_error = None + if self.check_names: + dn = safe_dn(dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'dn sanitized to <%s> for MODIFY operation via <%s>', dn, self) + + with self.connection_lock: + self._fire_deferred() + if self.read_only: + self.last_error = 'connection is read-only' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPConnectionIsReadOnlyError(self.last_error) + + if not isinstance(changes, dict): + self.last_error = 'changes must be a dictionary' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPChangeError(self.last_error) + + if not changes: + self.last_error = 'no changes in modify request' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPChangeError(self.last_error) + + changelist = dict() + for attribute_name in changes: + if self.server and self.server.schema and self.check_names: + if ';' in attribute_name: # remove tags for checking + attribute_name_to_check = attribute_name.split(';')[0] + else: + attribute_name_to_check = attribute_name + + if self.server.schema.attribute_types and attribute_name_to_check.lower() not in conf_attributes_excluded_from_check and attribute_name_to_check not in self.server.schema.attribute_types: + self.last_error = 'invalid attribute type ' + attribute_name_to_check + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPAttributeError(self.last_error) + change = changes[attribute_name] + if isinstance(change, SEQUENCE_TYPES) and change[0] in [MODIFY_ADD, MODIFY_DELETE, MODIFY_REPLACE, MODIFY_INCREMENT, 0, 1, 2, 3]: + if len(change) != 2: + self.last_error = 'malformed change' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPChangeError(self.last_error) + + changelist[attribute_name] = [change] # insert change in a list + else: + for change_operation in change: + if len(change_operation) != 2 or change_operation[0] not in [MODIFY_ADD, MODIFY_DELETE, MODIFY_REPLACE, MODIFY_INCREMENT, 0, 1, 2, 3]: + self.last_error = 'invalid change list' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPChangeError(self.last_error) + changelist[attribute_name] = change + request = modify_operation(dn, changelist, self.auto_encode, self.server.schema if self.server else None, validator=self.server.custom_validator if self.server else None, check_names=self.check_names) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'MODIFY request <%s> sent via <%s>', modify_request_to_dict(request), self) + response = self.post_send_single_response(self.send('modifyRequest', request, controls)) + self._entries = [] + + if isinstance(response, STRING_TYPES + (int, )): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async MODIFY response id <%s> received via <%s>', return_value, self) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'MODIFY response <%s> received via <%s>', response, self) + return_value = True if self.result['type'] == 'modifyResponse' and self.result['result'] == RESULT_SUCCESS else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(BASIC): + log(BASIC, 'done MODIFY operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def modify_dn(self, + dn, + relative_dn, + delete_old_dn=True, + new_superior=None, + controls=None): + """ + Modify DN of the entry or performs a move of the entry in the + DIT. + """ + if log_enabled(BASIC): + log(BASIC, 'start MODIFY DN operation via <%s>', self) + self.last_error = None + if self.check_names: + dn = safe_dn(dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'dn sanitized to <%s> for MODIFY DN operation via <%s>', dn, self) + relative_dn = safe_dn(relative_dn) + if log_enabled(EXTENDED): + log(EXTENDED, 'relative dn sanitized to <%s> for MODIFY DN operation via <%s>', relative_dn, self) + + with self.connection_lock: + self._fire_deferred() + if self.read_only: + self.last_error = 'connection is read-only' + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', self.last_error, self) + raise LDAPConnectionIsReadOnlyError(self.last_error) + + # if new_superior and not dn.startswith(relative_dn): # as per RFC4511 (4.9) + # self.last_error = 'DN cannot change while performing moving' + # if log_enabled(ERROR): + # log(ERROR, '%s for <%s>', self.last_error, self) + # raise LDAPChangeError(self.last_error) + + request = modify_dn_operation(dn, relative_dn, delete_old_dn, new_superior) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'MODIFY DN request <%s> sent via <%s>', modify_dn_request_to_dict(request), self) + response = self.post_send_single_response(self.send('modDNRequest', request, controls)) + self._entries = [] + + if isinstance(response, STRING_TYPES + (int, )): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async MODIFY DN response id <%s> received via <%s>', return_value, self) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'MODIFY DN response <%s> received via <%s>', response, self) + return_value = True if self.result['type'] == 'modDNResponse' and self.result['result'] == RESULT_SUCCESS else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(BASIC): + log(BASIC, 'done MODIFY DN operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def abandon(self, + message_id, + controls=None): + """ + Abandon the operation indicated by message_id + """ + if log_enabled(BASIC): + log(BASIC, 'start ABANDON operation via <%s>', self) + self.last_error = None + with self.connection_lock: + self._fire_deferred() + return_value = False + if self.strategy._outstanding or message_id == 0: + # only current operation should be abandoned, abandon, bind and unbind cannot ever be abandoned, + # messagiId 0 is invalid and should be used as a "ping" to keep alive the connection + if (self.strategy._outstanding and message_id in self.strategy._outstanding and self.strategy._outstanding[message_id]['type'] not in ['abandonRequest', 'bindRequest', 'unbindRequest']) or message_id == 0: + request = abandon_operation(message_id) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'ABANDON request: <%s> sent via <%s>', abandon_request_to_dict(request), self) + self.send('abandonRequest', request, controls) + self.result = None + self.response = None + self._entries = [] + return_value = True + else: + if log_enabled(ERROR): + log(ERROR, 'cannot abandon a Bind, an Unbind or an Abandon operation or message ID %s not found via <%s>', str(message_id), self) + + if log_enabled(BASIC): + log(BASIC, 'done ABANDON operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def extended(self, + request_name, + request_value=None, + controls=None, + no_encode=None): + """ + Performs an extended operation + """ + if log_enabled(BASIC): + log(BASIC, 'start EXTENDED operation via <%s>', self) + self.last_error = None + with self.connection_lock: + self._fire_deferred() + request = extended_operation(request_name, request_value, no_encode=no_encode) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'EXTENDED request <%s> sent via <%s>', extended_request_to_dict(request), self) + response = self.post_send_single_response(self.send('extendedReq', request, controls)) + self._entries = [] + if isinstance(response, int): + return_value = response + if log_enabled(PROTOCOL): + log(PROTOCOL, 'async EXTENDED response id <%s> received via <%s>', return_value, self) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'EXTENDED response <%s> received via <%s>', response, self) + return_value = True if self.result['type'] == 'extendedResp' and self.result['result'] == RESULT_SUCCESS else False + if not return_value and self.result['result'] not in [RESULT_SUCCESS] and not self.last_error: + self.last_error = self.result['description'] + + if log_enabled(BASIC): + log(BASIC, 'done EXTENDED operation, result <%s>', return_value) + + return self._prepare_return_value(return_value, response=True) + + def start_tls(self, read_server_info=True): # as per RFC4511. Removal of TLS is defined as MAY in RFC4511 so the client can't implement a generic stop_tls method0 + if log_enabled(BASIC): + log(BASIC, 'start START TLS operation via <%s>', self) + + with self.connection_lock: + return_value = False + self.result = None + + if not self.server.tls: + self.server.tls = Tls() + + if self.lazy and not self._executing_deferred: + self._deferred_start_tls = True + self.tls_started = True + return_value = True + if log_enabled(BASIC): + log(BASIC, 'deferring START TLS for <%s>', self) + else: + self._deferred_start_tls = False + if self.closed: + self.open() + if self.server.tls.start_tls(self) and self.strategy.sync: # for asynchronous connections _start_tls is run by the strategy + if read_server_info: + self.refresh_server_info() # refresh server info as per RFC4515 (3.1.5) + return_value = True + elif not self.strategy.sync: + return_value = True + + if log_enabled(BASIC): + log(BASIC, 'done START TLS operation, result <%s>', return_value) + + return self._prepare_return_value(return_value) + + def do_sasl_bind(self, + controls): + if log_enabled(BASIC): + log(BASIC, 'start SASL BIND operation via <%s>', self) + self.last_error = None + with self.connection_lock: + result = None + + if not self.sasl_in_progress: + self.sasl_in_progress = True + try: + if self.sasl_mechanism == EXTERNAL: + result = sasl_external(self, controls) + elif self.sasl_mechanism == DIGEST_MD5: + result = sasl_digest_md5(self, controls) + elif self.sasl_mechanism == GSSAPI: + from ..protocol.sasl.kerberos import sasl_gssapi # needs the gssapi package + result = sasl_gssapi(self, controls) + elif self.sasl_mechanism == 'PLAIN': + result = sasl_plain(self, controls) + finally: + self.sasl_in_progress = False + + if log_enabled(BASIC): + log(BASIC, 'done SASL BIND operation, result <%s>', result) + + return result + + def do_ntlm_bind(self, + controls): + if log_enabled(BASIC): + log(BASIC, 'start NTLM BIND operation via <%s>', self) + self.last_error = None + with self.connection_lock: + if not self.sasl_in_progress: + self.sasl_in_progress = True # ntlm is same of sasl authentication + try: + # additional import for NTLM + from ..utils.ntlm import NtlmClient + domain_name, user_name = self.user.split('\\', 1) + ntlm_client = NtlmClient(user_name=user_name, domain=domain_name, password=self.password) + + # as per https://msdn.microsoft.com/en-us/library/cc223501.aspx + # send a sicilyPackageDiscovery request (in the bindRequest) + request = bind_operation(self.version, 'SICILY_PACKAGE_DISCOVERY', ntlm_client) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'NTLM SICILY PACKAGE DISCOVERY request sent via <%s>', self) + response = self.post_send_single_response(self.send('bindRequest', request, controls)) + if not self.strategy.sync: + _, result = self.get_response(response) + else: + result = response[0] + if 'server_creds' in result: + sicily_packages = result['server_creds'].decode('ascii').split(';') + if 'NTLM' in sicily_packages: # NTLM available on server + request = bind_operation(self.version, 'SICILY_NEGOTIATE_NTLM', ntlm_client) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'NTLM SICILY NEGOTIATE request sent via <%s>', self) + response = self.post_send_single_response(self.send('bindRequest', request, controls)) + if not self.strategy.sync: + _, result = self.get_response(response) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'NTLM SICILY NEGOTIATE response <%s> received via <%s>', response[0], + self) + result = response[0] + + if result['result'] == RESULT_SUCCESS: + request = bind_operation(self.version, 'SICILY_RESPONSE_NTLM', ntlm_client, + result['server_creds']) + if log_enabled(PROTOCOL): + log(PROTOCOL, 'NTLM SICILY RESPONSE NTLM request sent via <%s>', self) + response = self.post_send_single_response(self.send('bindRequest', request, controls)) + if not self.strategy.sync: + _, result = self.get_response(response) + else: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'NTLM BIND response <%s> received via <%s>', response[0], self) + result = response[0] + else: + result = None + finally: + self.sasl_in_progress = False + + if log_enabled(BASIC): + log(BASIC, 'done SASL NTLM operation, result <%s>', result) + + return result + + def refresh_server_info(self): + # if self.strategy.no_real_dsa: # do not refresh for mock strategies + # return + + if not self.strategy.pooled: + with self.connection_lock: + if not self.closed: + if log_enabled(BASIC): + log(BASIC, 'refreshing server info for <%s>', self) + previous_response = self.response + previous_result = self.result + previous_entries = self._entries + self.server.get_info_from_server(self) + self.response = previous_response + self.result = previous_result + self._entries = previous_entries + else: + if log_enabled(BASIC): + log(BASIC, 'refreshing server info from pool for <%s>', self) + self.strategy.pool.get_info_from_server() + + def response_to_ldif(self, + search_result=None, + all_base64=False, + line_separator=None, + sort_order=None, + stream=None): + with self.connection_lock: + if search_result is None: + search_result = self.response + + if isinstance(search_result, SEQUENCE_TYPES): + ldif_lines = operation_to_ldif('searchResponse', search_result, all_base64, sort_order=sort_order) + ldif_lines = add_ldif_header(ldif_lines) + line_separator = line_separator or linesep + ldif_output = line_separator.join(ldif_lines) + if stream: + if stream.tell() == 0: + header = add_ldif_header(['-'])[0] + stream.write(prepare_for_stream(header + line_separator + line_separator)) + stream.write(prepare_for_stream(ldif_output + line_separator + line_separator)) + if log_enabled(BASIC): + log(BASIC, 'building LDIF output <%s> for <%s>', ldif_output, self) + return ldif_output + + return None + + def response_to_json(self, + raw=False, + search_result=None, + indent=4, + sort=True, + stream=None, + checked_attributes=True, + include_empty=True): + + with self.connection_lock: + if search_result is None: + search_result = self.response + + if isinstance(search_result, SEQUENCE_TYPES): + json_dict = dict() + json_dict['entries'] = [] + + for response in search_result: + if response['type'] == 'searchResEntry': + entry = dict() + + entry['dn'] = response['dn'] + if checked_attributes: + if not include_empty: + # needed for python 2.6 compatibility + entry['attributes'] = dict((key, response['attributes'][key]) for key in response['attributes'] if response['attributes'][key]) + else: + entry['attributes'] = dict(response['attributes']) + if raw: + if not include_empty: + # needed for python 2.6 compatibility + entry['raw_attributes'] = dict((key, response['raw_attributes'][key]) for key in response['raw_attributes'] if response['raw:attributes'][key]) + else: + entry['raw'] = dict(response['raw_attributes']) + json_dict['entries'].append(entry) + + if str is bytes: # Python 2 + check_json_dict(json_dict) + + json_output = json.dumps(json_dict, ensure_ascii=True, sort_keys=sort, indent=indent, check_circular=True, default=format_json, separators=(',', ': ')) + + if log_enabled(BASIC): + log(BASIC, 'building JSON output <%s> for <%s>', json_output, self) + if stream: + stream.write(json_output) + + return json_output + + def response_to_file(self, + target, + raw=False, + indent=4, + sort=True): + with self.connection_lock: + if self.response: + if isinstance(target, STRING_TYPES): + target = open(target, 'w+') + + if log_enabled(BASIC): + log(BASIC, 'writing response to file for <%s>', self) + + target.writelines(self.response_to_json(raw=raw, indent=indent, sort=sort)) + target.close() + + def _fire_deferred(self, read_info=None): + # if read_info is None reads the schema and server info if not present, if False doesn't read server info, if True reads always server info + with self.connection_lock: + if self.lazy and not self._executing_deferred: + self._executing_deferred = True + + if log_enabled(BASIC): + log(BASIC, 'executing deferred (open: %s, start_tls: %s, bind: %s) for <%s>', self._deferred_open, self._deferred_start_tls, self._deferred_bind, self) + try: + if self._deferred_open: + self.open(read_server_info=False) + if self._deferred_start_tls: + if not self.start_tls(read_server_info=False): + error = 'deferred start_tls not successful' + (' - ' + self.last_error if self.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.unbind() + raise LDAPStartTLSError(error) + if self._deferred_bind: + self.bind(read_server_info=False, controls=self._bind_controls) + if (read_info is None and (not self.server.info and self.server.get_info in [DSA, ALL]) or (not self.server.schema and self.server.get_info in [SCHEMA, ALL])) or read_info: + self.refresh_server_info() + except LDAPExceptionError as e: + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', e, self) + raise # re-raise LDAPExceptionError + finally: + self._executing_deferred = False + + @property + def entries(self): + if self.response: + if not self._entries: + self._entries = self._get_entries(self.response, self.request) + return self._entries + + def _get_entries(self, search_response, search_request): + with self.connection_lock: + from .. import ObjectDef, Reader + + # build a table of ObjectDefs, grouping the entries found in search_response for their attributes set, subset will be included in superset + attr_sets = [] + for response in search_response: + if response['type'] == 'searchResEntry': + resp_attr_set = set(response['attributes'].keys()) + if resp_attr_set not in attr_sets: + attr_sets.append(resp_attr_set) + attr_sets.sort(key=lambda x: -len(x)) # sorts the list in descending length order + unique_attr_sets = [] + for attr_set in attr_sets: + for unique_set in unique_attr_sets: + if unique_set >= attr_set: # checks if unique set is a superset of attr_set + break + else: # the attr_set is not a subset of any element in unique_attr_sets + unique_attr_sets.append(attr_set) + object_defs = [] + for attr_set in unique_attr_sets: + object_def = ObjectDef(schema=self.server.schema) + object_def += list(attr_set) # converts the set in a list to be added to the object definition + object_defs.append((attr_set, + object_def, + Reader(self, object_def, search_request['base'], search_request['filter'], attributes=attr_set) if self.strategy.sync else Reader(self, object_def, '', '', attributes=attr_set)) + ) # objects_defs contains a tuple with the set, the ObjectDef and a cursor + + entries = [] + for response in search_response: + if response['type'] == 'searchResEntry': + resp_attr_set = set(response['attributes'].keys()) + for object_def in object_defs: + if resp_attr_set <= object_def[0]: # finds the ObjectDef for the attribute set of this entry + entry = object_def[2]._create_entry(response) + entries.append(entry) + break + else: + self.last_error = 'attribute set not found for ' + str(resp_attr_set) + if log_enabled(ERROR): + log(ERROR, self.last_error, self) + raise LDAPObjectError(self.last_error) + + return entries diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/exceptions.py b/plugins/ldap-user-sync/vendor/ldap3/core/exceptions.py new file mode 100644 index 00000000..f5d1e864 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/exceptions.py @@ -0,0 +1,608 @@ +""" +""" + +# Created on 2014.05.14 +# +# 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 . + +from os import sep +from .results import RESULT_OPERATIONS_ERROR, RESULT_PROTOCOL_ERROR, RESULT_TIME_LIMIT_EXCEEDED, RESULT_SIZE_LIMIT_EXCEEDED, \ + RESULT_STRONGER_AUTH_REQUIRED, RESULT_REFERRAL, RESULT_ADMIN_LIMIT_EXCEEDED, RESULT_UNAVAILABLE_CRITICAL_EXTENSION, \ + RESULT_AUTH_METHOD_NOT_SUPPORTED, RESULT_UNDEFINED_ATTRIBUTE_TYPE, RESULT_NO_SUCH_ATTRIBUTE, \ + RESULT_SASL_BIND_IN_PROGRESS, RESULT_CONFIDENTIALITY_REQUIRED, RESULT_INAPPROPRIATE_MATCHING, \ + RESULT_CONSTRAINT_VIOLATION, \ + RESULT_ATTRIBUTE_OR_VALUE_EXISTS, RESULT_INVALID_ATTRIBUTE_SYNTAX, RESULT_NO_SUCH_OBJECT, RESULT_ALIAS_PROBLEM, \ + RESULT_INVALID_DN_SYNTAX, RESULT_ALIAS_DEREFERENCING_PROBLEM, RESULT_INVALID_CREDENTIALS, RESULT_LOOP_DETECTED, \ + RESULT_ENTRY_ALREADY_EXISTS, RESULT_LCUP_SECURITY_VIOLATION, RESULT_CANCELED, RESULT_E_SYNC_REFRESH_REQUIRED, \ + RESULT_NO_SUCH_OPERATION, RESULT_LCUP_INVALID_DATA, RESULT_OBJECT_CLASS_MODS_PROHIBITED, RESULT_NAMING_VIOLATION, \ + RESULT_INSUFFICIENT_ACCESS_RIGHTS, RESULT_OBJECT_CLASS_VIOLATION, RESULT_TOO_LATE, RESULT_CANNOT_CANCEL, \ + RESULT_LCUP_UNSUPPORTED_SCHEME, RESULT_BUSY, RESULT_AFFECT_MULTIPLE_DSAS, RESULT_UNAVAILABLE, \ + RESULT_NOT_ALLOWED_ON_NON_LEAF, \ + RESULT_UNWILLING_TO_PERFORM, RESULT_OTHER, RESULT_LCUP_RELOAD_REQUIRED, RESULT_ASSERTION_FAILED, \ + RESULT_AUTHORIZATION_DENIED, RESULT_LCUP_RESOURCES_EXHAUSTED, RESULT_NOT_ALLOWED_ON_RDN, \ + RESULT_INAPPROPRIATE_AUTHENTICATION +import socket + + +# LDAPException hierarchy +class LDAPException(Exception): + pass + + +class LDAPOperationResult(LDAPException): + def __new__(cls, result=None, description=None, dn=None, message=None, response_type=None, response=None): + if cls is LDAPOperationResult and result and result in exception_table: + exc = super(LDAPOperationResult, exception_table[result]).__new__( + exception_table[result]) # create an exception of the required result error + exc.result = result + exc.description = description + exc.dn = dn + exc.message = message + exc.type = response_type + exc.response = response + else: + exc = super(LDAPOperationResult, cls).__new__(cls) + return exc + + def __init__(self, result=None, description=None, dn=None, message=None, response_type=None, response=None): + self.result = result + self.description = description + self.dn = dn + self.message = message + self.type = response_type + self.response = response + + def __str__(self): + s = [self.__class__.__name__, + str(self.result) if self.result else None, + self.description if self.description else None, + self.dn if self.dn else None, + self.message if self.message else None, + self.type if self.type else None, + self.response if self.response else None] + + return ' - '.join([str(item) for item in s if s is not None]) + + def __repr__(self): + return self.__str__() + + +class LDAPOperationsErrorResult(LDAPOperationResult): + pass + + +class LDAPProtocolErrorResult(LDAPOperationResult): + pass + + +class LDAPTimeLimitExceededResult(LDAPOperationResult): + pass + + +class LDAPSizeLimitExceededResult(LDAPOperationResult): + pass + + +class LDAPAuthMethodNotSupportedResult(LDAPOperationResult): + pass + + +class LDAPStrongerAuthRequiredResult(LDAPOperationResult): + pass + + +class LDAPReferralResult(LDAPOperationResult): + pass + + +class LDAPAdminLimitExceededResult(LDAPOperationResult): + pass + + +class LDAPUnavailableCriticalExtensionResult(LDAPOperationResult): + pass + + +class LDAPConfidentialityRequiredResult(LDAPOperationResult): + pass + + +class LDAPSASLBindInProgressResult(LDAPOperationResult): + pass + + +class LDAPNoSuchAttributeResult(LDAPOperationResult): + pass + + +class LDAPUndefinedAttributeTypeResult(LDAPOperationResult): + pass + + +class LDAPInappropriateMatchingResult(LDAPOperationResult): + pass + + +class LDAPConstraintViolationResult(LDAPOperationResult): + pass + + +class LDAPAttributeOrValueExistsResult(LDAPOperationResult): + pass + + +class LDAPInvalidAttributeSyntaxResult(LDAPOperationResult): + pass + + +class LDAPNoSuchObjectResult(LDAPOperationResult): + pass + + +class LDAPAliasProblemResult(LDAPOperationResult): + pass + + +class LDAPInvalidDNSyntaxResult(LDAPOperationResult): + pass + + +class LDAPAliasDereferencingProblemResult(LDAPOperationResult): + pass + + +class LDAPInappropriateAuthenticationResult(LDAPOperationResult): + pass + + +class LDAPInvalidCredentialsResult(LDAPOperationResult): + pass + + +class LDAPInsufficientAccessRightsResult(LDAPOperationResult): + pass + + +class LDAPBusyResult(LDAPOperationResult): + pass + + +class LDAPUnavailableResult(LDAPOperationResult): + pass + + +class LDAPUnwillingToPerformResult(LDAPOperationResult): + pass + + +class LDAPLoopDetectedResult(LDAPOperationResult): + pass + + +class LDAPNamingViolationResult(LDAPOperationResult): + pass + + +class LDAPObjectClassViolationResult(LDAPOperationResult): + pass + + +class LDAPNotAllowedOnNotLeafResult(LDAPOperationResult): + pass + + +class LDAPNotAllowedOnRDNResult(LDAPOperationResult): + pass + + +class LDAPEntryAlreadyExistsResult(LDAPOperationResult): + pass + + +class LDAPObjectClassModsProhibitedResult(LDAPOperationResult): + pass + + +class LDAPAffectMultipleDSASResult(LDAPOperationResult): + pass + + +class LDAPOtherResult(LDAPOperationResult): + pass + + +class LDAPLCUPResourcesExhaustedResult(LDAPOperationResult): + pass + + +class LDAPLCUPSecurityViolationResult(LDAPOperationResult): + pass + + +class LDAPLCUPInvalidDataResult(LDAPOperationResult): + pass + + +class LDAPLCUPUnsupportedSchemeResult(LDAPOperationResult): + pass + + +class LDAPLCUPReloadRequiredResult(LDAPOperationResult): + pass + + +class LDAPCanceledResult(LDAPOperationResult): + pass + + +class LDAPNoSuchOperationResult(LDAPOperationResult): + pass + + +class LDAPTooLateResult(LDAPOperationResult): + pass + + +class LDAPCannotCancelResult(LDAPOperationResult): + pass + + +class LDAPAssertionFailedResult(LDAPOperationResult): + pass + + +class LDAPAuthorizationDeniedResult(LDAPOperationResult): + pass + + +class LDAPESyncRefreshRequiredResult(LDAPOperationResult): + pass + + +exception_table = {RESULT_OPERATIONS_ERROR: LDAPOperationsErrorResult, + RESULT_PROTOCOL_ERROR: LDAPProtocolErrorResult, + RESULT_TIME_LIMIT_EXCEEDED: LDAPTimeLimitExceededResult, + RESULT_SIZE_LIMIT_EXCEEDED: LDAPSizeLimitExceededResult, + RESULT_AUTH_METHOD_NOT_SUPPORTED: LDAPAuthMethodNotSupportedResult, + RESULT_STRONGER_AUTH_REQUIRED: LDAPStrongerAuthRequiredResult, + RESULT_REFERRAL: LDAPReferralResult, + RESULT_ADMIN_LIMIT_EXCEEDED: LDAPAdminLimitExceededResult, + RESULT_UNAVAILABLE_CRITICAL_EXTENSION: LDAPUnavailableCriticalExtensionResult, + RESULT_CONFIDENTIALITY_REQUIRED: LDAPConfidentialityRequiredResult, + RESULT_SASL_BIND_IN_PROGRESS: LDAPSASLBindInProgressResult, + RESULT_NO_SUCH_ATTRIBUTE: LDAPNoSuchAttributeResult, + RESULT_UNDEFINED_ATTRIBUTE_TYPE: LDAPUndefinedAttributeTypeResult, + RESULT_INAPPROPRIATE_MATCHING: LDAPInappropriateMatchingResult, + RESULT_CONSTRAINT_VIOLATION: LDAPConstraintViolationResult, + RESULT_ATTRIBUTE_OR_VALUE_EXISTS: LDAPAttributeOrValueExistsResult, + RESULT_INVALID_ATTRIBUTE_SYNTAX: LDAPInvalidAttributeSyntaxResult, + RESULT_NO_SUCH_OBJECT: LDAPNoSuchObjectResult, + RESULT_ALIAS_PROBLEM: LDAPAliasProblemResult, + RESULT_INVALID_DN_SYNTAX: LDAPInvalidDNSyntaxResult, + RESULT_ALIAS_DEREFERENCING_PROBLEM: LDAPAliasDereferencingProblemResult, + RESULT_INAPPROPRIATE_AUTHENTICATION: LDAPInappropriateAuthenticationResult, + RESULT_INVALID_CREDENTIALS: LDAPInvalidCredentialsResult, + RESULT_INSUFFICIENT_ACCESS_RIGHTS: LDAPInsufficientAccessRightsResult, + RESULT_BUSY: LDAPBusyResult, + RESULT_UNAVAILABLE: LDAPUnavailableResult, + RESULT_UNWILLING_TO_PERFORM: LDAPUnwillingToPerformResult, + RESULT_LOOP_DETECTED: LDAPLoopDetectedResult, + RESULT_NAMING_VIOLATION: LDAPNamingViolationResult, + RESULT_OBJECT_CLASS_VIOLATION: LDAPObjectClassViolationResult, + RESULT_NOT_ALLOWED_ON_NON_LEAF: LDAPNotAllowedOnNotLeafResult, + RESULT_NOT_ALLOWED_ON_RDN: LDAPNotAllowedOnRDNResult, + RESULT_ENTRY_ALREADY_EXISTS: LDAPEntryAlreadyExistsResult, + RESULT_OBJECT_CLASS_MODS_PROHIBITED: LDAPObjectClassModsProhibitedResult, + RESULT_AFFECT_MULTIPLE_DSAS: LDAPAffectMultipleDSASResult, + RESULT_OTHER: LDAPOtherResult, + RESULT_LCUP_RESOURCES_EXHAUSTED: LDAPLCUPResourcesExhaustedResult, + RESULT_LCUP_SECURITY_VIOLATION: LDAPLCUPSecurityViolationResult, + RESULT_LCUP_INVALID_DATA: LDAPLCUPInvalidDataResult, + RESULT_LCUP_UNSUPPORTED_SCHEME: LDAPLCUPUnsupportedSchemeResult, + RESULT_LCUP_RELOAD_REQUIRED: LDAPLCUPReloadRequiredResult, + RESULT_CANCELED: LDAPCanceledResult, + RESULT_NO_SUCH_OPERATION: LDAPNoSuchOperationResult, + RESULT_TOO_LATE: LDAPTooLateResult, + RESULT_CANNOT_CANCEL: LDAPCannotCancelResult, + RESULT_ASSERTION_FAILED: LDAPAssertionFailedResult, + RESULT_AUTHORIZATION_DENIED: LDAPAuthorizationDeniedResult, + RESULT_E_SYNC_REFRESH_REQUIRED: LDAPESyncRefreshRequiredResult} + + +class LDAPExceptionError(LDAPException): + pass + + +# configuration exceptions +class LDAPConfigurationError(LDAPExceptionError): + pass + + +class LDAPUnknownStrategyError(LDAPConfigurationError): + pass + + +class LDAPUnknownAuthenticationMethodError(LDAPConfigurationError): + pass + + +class LDAPSSLConfigurationError(LDAPConfigurationError): + pass + + +class LDAPDefinitionError(LDAPConfigurationError): + pass + + +class LDAPPackageUnavailableError(LDAPConfigurationError, ImportError): + pass + + +class LDAPConfigurationParameterError(LDAPConfigurationError): + pass + + +# abstract layer exceptions +class LDAPKeyError(LDAPExceptionError, KeyError, AttributeError): + pass + + +class LDAPObjectError(LDAPExceptionError, ValueError): + pass + + +class LDAPAttributeError(LDAPExceptionError, ValueError, TypeError): + pass + + +class LDAPCursorError(LDAPExceptionError): + pass + + +class LDAPCursorAttributeError(LDAPCursorError, AttributeError): + pass + + +class LDAPObjectDereferenceError(LDAPExceptionError): + pass + + +# security exceptions +class LDAPSSLNotSupportedError(LDAPExceptionError, ImportError): + pass + + +class LDAPInvalidTlsSpecificationError(LDAPExceptionError): + pass + + +class LDAPInvalidHashAlgorithmError(LDAPExceptionError, ValueError): + pass + +class LDAPSignatureVerificationFailedError(LDAPExceptionError): + pass + + +# connection exceptions +class LDAPBindError(LDAPExceptionError): + pass + + +class LDAPInvalidServerError(LDAPExceptionError): + pass + + +class LDAPSASLMechanismNotSupportedError(LDAPExceptionError): + pass + + +class LDAPConnectionIsReadOnlyError(LDAPExceptionError): + pass + + +class LDAPChangeError(LDAPExceptionError, ValueError): + pass + + +class LDAPServerPoolError(LDAPExceptionError): + pass + + +class LDAPServerPoolExhaustedError(LDAPExceptionError): + pass + + +class LDAPInvalidPortError(LDAPExceptionError): + pass + + +class LDAPStartTLSError(LDAPExceptionError): + pass + + +class LDAPCertificateError(LDAPExceptionError): + pass + + +class LDAPUserNameNotAllowedError(LDAPExceptionError): + pass + + +class LDAPUserNameIsMandatoryError(LDAPExceptionError): + pass + + +class LDAPPasswordIsMandatoryError(LDAPExceptionError): + pass + + +class LDAPInvalidFilterError(LDAPExceptionError): + pass + + +class LDAPInvalidScopeError(LDAPExceptionError, ValueError): + pass + + +class LDAPInvalidDereferenceAliasesError(LDAPExceptionError, ValueError): + pass + + +class LDAPInvalidValueError(LDAPExceptionError, ValueError): + pass + + +class LDAPControlError(LDAPExceptionError, ValueError): + pass + + +class LDAPExtensionError(LDAPExceptionError, ValueError): + pass + + +class LDAPLDIFError(LDAPExceptionError): + pass + + +class LDAPSchemaError(LDAPExceptionError): + pass + + +class LDAPSASLPrepError(LDAPExceptionError): + pass + + +class LDAPSASLBindInProgressError(LDAPExceptionError): + pass + + +class LDAPMetricsError(LDAPExceptionError): + pass + + +class LDAPObjectClassError(LDAPExceptionError): + pass + + +class LDAPInvalidDnError(LDAPExceptionError): + pass + + +class LDAPResponseTimeoutError(LDAPExceptionError): + pass + + +class LDAPTransactionError(LDAPExceptionError): + pass + + +class LDAPInfoError(LDAPExceptionError): + pass + + +# communication exceptions +class LDAPCommunicationError(LDAPExceptionError): + pass + + +class LDAPSocketOpenError(LDAPCommunicationError): + pass + + +class LDAPSocketCloseError(LDAPCommunicationError): + pass + + +class LDAPSocketReceiveError(LDAPCommunicationError, socket.error): + pass + + +class LDAPSocketSendError(LDAPCommunicationError, socket.error): + pass + + +class LDAPSessionTerminatedByServerError(LDAPCommunicationError): + pass + + +class LDAPUnknownResponseError(LDAPCommunicationError): + pass + + +class LDAPUnknownRequestError(LDAPCommunicationError): + pass + + +class LDAPReferralError(LDAPCommunicationError): + pass + + +# pooling exceptions +class LDAPConnectionPoolNameIsMandatoryError(LDAPExceptionError): + pass + + +class LDAPConnectionPoolNotStartedError(LDAPExceptionError): + pass + + +# restartable strategy +class LDAPMaximumRetriesError(LDAPExceptionError): + def __str__(self): + s = [] + if self.args: + if isinstance(self.args, tuple): + if len(self.args) > 0: + s.append('LDAPMaximumRetriesError: ' + str(self.args[0])) + if len(self.args) > 1: + s.append('Exception history:') + prev_exc = '' + for i, exc in enumerate(self.args[1]): # args[1] contains exception history + # if str(exc[1]) != prev_exc: + # s.append((str(i).rjust(5) + ' ' + str(exc[0]) + ': ' + str(exc[1]) + ' - ' + str(exc[2]))) + # prev_exc = str(exc[1]) + if str(exc) != prev_exc: + s.append((str(i).rjust(5) + ' ' + str(type(exc)) + ': ' + str(exc))) + prev_exc = str(exc) + if len(self.args) > 2: + s.append('Maximum number of retries reached: ' + str(self.args[2])) + else: + s = [LDAPExceptionError.__str__(self)] + + return sep.join(s) + + +# exception factories +def communication_exception_factory(exc_to_raise, exc): + """ + Generates a new exception class of the requested type (subclass of LDAPCommunication) merged with the exception raised by the interpreter + """ + if exc_to_raise.__name__ in [cls.__name__ for cls in LDAPCommunicationError.__subclasses__()]: + return type(exc_to_raise.__name__, (exc_to_raise, type(exc)), dict()) + else: + raise LDAPExceptionError('unable to generate exception type ' + str(exc_to_raise)) + + +def start_tls_exception_factory(exc): + """ + Generates a new exception class of the requested type merged with the exception raised by the interpreter + """ + return type(LDAPStartTLSError.__name__, (LDAPStartTLSError, type(exc)), dict()) diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/pooling.py b/plugins/ldap-user-sync/vendor/ldap3/core/pooling.py new file mode 100644 index 00000000..24a5b0fa --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/pooling.py @@ -0,0 +1,329 @@ +""" +""" + +# Created on 2014.03.14 +# +# 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 . + +from datetime import datetime, MINYEAR +from os import linesep +from random import randint +from time import sleep + +from .. import FIRST, ROUND_ROBIN, RANDOM, SEQUENCE_TYPES, STRING_TYPES, get_config_parameter +from .exceptions import LDAPUnknownStrategyError, LDAPServerPoolError, LDAPServerPoolExhaustedError +from .server import Server +from ..utils.log import log, log_enabled, ERROR, BASIC, NETWORK + +POOLING_STRATEGIES = [FIRST, ROUND_ROBIN, RANDOM] + + +class ServerState(object): + def __init__(self, server, last_checked_time, available): + self.server = server + self.last_checked_time = last_checked_time + self.available = available + + +class ServerPoolState(object): + def __init__(self, server_pool): + self.server_states = [] # each element is a ServerState + self.strategy = server_pool.strategy + self.server_pool = server_pool + self.last_used_server = 0 + self.refresh() + self.initialize_time = datetime.now() + + if log_enabled(BASIC): + log(BASIC, 'instantiated ServerPoolState: <%r>', self) + + def __str__(self): + s = 'servers: ' + linesep + if self.server_states: + for state in self.server_states: + s += str(state.server) + linesep + else: + s += 'None' + linesep + s += 'Pool strategy: ' + str(self.strategy) + linesep + s += ' - Last used server: ' + ('None' if self.last_used_server == -1 else str(self.server_states[self.last_used_server].server)) + + return s + + def refresh(self): + self.server_states = [] + for server in self.server_pool.servers: + self.server_states.append(ServerState(server, datetime(MINYEAR, 1, 1), True)) # server, smallest date ever, supposed available + self.last_used_server = randint(0, len(self.server_states) - 1) + + def get_current_server(self): + return self.server_states[self.last_used_server].server + + def get_server(self): + if self.server_states: + if self.server_pool.strategy == FIRST: + if self.server_pool.active: + # returns the first active server + self.last_used_server = self.find_active_server(starting=0) + else: + # returns always the first server - no pooling + self.last_used_server = 0 + elif self.server_pool.strategy == ROUND_ROBIN: + if self.server_pool.active: + # returns the next active server in a circular range + self.last_used_server = self.find_active_server(self.last_used_server + 1) + else: + # returns the next server in a circular range + self.last_used_server = self.last_used_server + 1 if (self.last_used_server + 1) < len(self.server_states) else 0 + elif self.server_pool.strategy == RANDOM: + if self.server_pool.active: + self.last_used_server = self.find_active_random_server() + else: + # returns a random server in the pool + self.last_used_server = randint(0, len(self.server_states) - 1) + else: + if log_enabled(ERROR): + log(ERROR, 'unknown server pooling strategy <%s>', self.server_pool.strategy) + raise LDAPUnknownStrategyError('unknown server pooling strategy') + if log_enabled(BASIC): + log(BASIC, 'server returned from Server Pool: <%s>', self.last_used_server) + return self.server_states[self.last_used_server].server + else: + if log_enabled(ERROR): + log(ERROR, 'no servers in Server Pool <%s>', self) + raise LDAPServerPoolError('no servers in server pool') + + def find_active_random_server(self): + counter = self.server_pool.active # can be True for "forever" or the number of cycles to try + while counter: + if log_enabled(NETWORK): + log(NETWORK, 'entering loop for finding active server in pool <%s>', self) + temp_list = self.server_states[:] # copy + while temp_list: + # pops a random server from a temp list and checks its + # availability, if not available tries another one + server_state = temp_list.pop(randint(0, len(temp_list) - 1)) + if not server_state.available: # server is offline + if (isinstance(self.server_pool.exhaust, bool) and self.server_pool.exhaust) or (datetime.now() - server_state.last_checked_time).seconds < self.server_pool.exhaust: # keeps server offline + if log_enabled(NETWORK): + log(NETWORK, 'server <%s> excluded from checking because it is offline', server_state.server) + continue + if log_enabled(NETWORK): + log(NETWORK, 'server <%s> reinserted in pool', server_state.server) + server_state.last_checked_time = datetime.now() + if log_enabled(NETWORK): + log(NETWORK, 'checking server <%s> for availability', server_state.server) + if server_state.server.check_availability(): + # returns a random active server in the pool + server_state.available = True + return self.server_states.index(server_state) + else: + server_state.available = False + if not isinstance(self.server_pool.active, bool): + counter -= 1 + if log_enabled(ERROR): + log(ERROR, 'no random active server available in Server Pool <%s> after maximum number of tries', self) + raise LDAPServerPoolExhaustedError('no random active server available in server pool after maximum number of tries') + + def find_active_server(self, starting): + conf_pool_timeout = get_config_parameter('POOLING_LOOP_TIMEOUT') + counter = self.server_pool.active # can be True for "forever" or the number of cycles to try + if starting >= len(self.server_states): + starting = 0 + + while counter: + if log_enabled(NETWORK): + log(NETWORK, 'entering loop number <%s> for finding active server in pool <%s>', counter, self) + index = -1 + pool_size = len(self.server_states) + while index < pool_size - 1: + index += 1 + offset = index + starting if index + starting < pool_size else index + starting - pool_size + server_state = self.server_states[offset] + if not server_state.available: # server is offline + if (isinstance(self.server_pool.exhaust, bool) and self.server_pool.exhaust) or (datetime.now() - server_state.last_checked_time).seconds < self.server_pool.exhaust: # keeps server offline + if log_enabled(NETWORK): + if isinstance(self.server_pool.exhaust, bool): + log(NETWORK, 'server <%s> excluded from checking because is offline', server_state.server) + else: + log(NETWORK, 'server <%s> excluded from checking because is offline for %d seconds', server_state.server, (self.server_pool.exhaust - (datetime.now() - server_state.last_checked_time).seconds)) + continue + if log_enabled(NETWORK): + log(NETWORK, 'server <%s> reinserted in pool', server_state.server) + server_state.last_checked_time = datetime.now() + if log_enabled(NETWORK): + log(NETWORK, 'checking server <%s> for availability', server_state.server) + if server_state.server.check_availability(): + server_state.available = True + return offset + else: + server_state.available = False # sets server offline + + if not isinstance(self.server_pool.active, bool): + counter -= 1 + if log_enabled(NETWORK): + log(NETWORK, 'waiting for %d seconds before retrying pool servers cycle', conf_pool_timeout) + sleep(conf_pool_timeout) + + if log_enabled(ERROR): + log(ERROR, 'no active server available in Server Pool <%s> after maximum number of tries', self) + raise LDAPServerPoolExhaustedError('no active server available in server pool after maximum number of tries') + + def __len__(self): + return len(self.server_states) + + +class ServerPool(object): + def __init__(self, + servers=None, + pool_strategy=ROUND_ROBIN, + active=True, + exhaust=False, + single_state=True): + + if pool_strategy not in POOLING_STRATEGIES: + if log_enabled(ERROR): + log(ERROR, 'unknown pooling strategy <%s>', pool_strategy) + raise LDAPUnknownStrategyError('unknown pooling strategy') + if exhaust and not active: + if log_enabled(ERROR): + log(ERROR, 'cannot instantiate pool with exhaust and not active') + raise LDAPServerPoolError('pools can be exhausted only when checking for active servers') + self.servers = [] + self.pool_states = dict() + self.active = active + self.exhaust = exhaust + self.single = single_state + self._pool_state = None # used for storing the global state of the pool + if isinstance(servers, SEQUENCE_TYPES + (Server, )): + self.add(servers) + elif isinstance(servers, STRING_TYPES): + self.add(Server(servers)) + self.strategy = pool_strategy + + if log_enabled(BASIC): + log(BASIC, 'instantiated ServerPool: <%r>', self) + + def __str__(self): + s = 'servers: ' + linesep + if self.servers: + for server in self.servers: + s += str(server) + linesep + else: + s += 'None' + linesep + s += 'Pool strategy: ' + str(self.strategy) + s += ' - ' + 'active: ' + (str(self.active) if self.active else 'False') + s += ' - ' + 'exhaust pool: ' + (str(self.exhaust) if self.exhaust else 'False') + return s + + def __repr__(self): + r = 'ServerPool(servers=' + if self.servers: + r += '[' + for server in self.servers: + r += server.__repr__() + ', ' + r = r[:-2] + ']' + else: + r += 'None' + r += ', pool_strategy={0.strategy!r}'.format(self) + r += ', active={0.active!r}'.format(self) + r += ', exhaust={0.exhaust!r}'.format(self) + r += ')' + + return r + + def __len__(self): + return len(self.servers) + + def __getitem__(self, item): + return self.servers[item] + + def __iter__(self): + return self.servers.__iter__() + + def add(self, servers): + if isinstance(servers, Server): + if servers not in self.servers: + self.servers.append(servers) + elif isinstance(servers, STRING_TYPES): + self.servers.append(Server(servers)) + elif isinstance(servers, SEQUENCE_TYPES): + for server in servers: + if isinstance(server, Server): + self.servers.append(server) + elif isinstance(server, STRING_TYPES): + self.servers.append(Server(server)) + else: + if log_enabled(ERROR): + log(ERROR, 'element must be a server in Server Pool <%s>', self) + raise LDAPServerPoolError('server in ServerPool must be a Server') + else: + if log_enabled(ERROR): + log(ERROR, 'server must be a Server of a list of Servers when adding to Server Pool <%s>', self) + raise LDAPServerPoolError('server must be a Server or a list of Server') + + if self.single: + if self._pool_state: + self._pool_state.refresh() + else: + for connection in self.pool_states: + # notifies connections using this pool to refresh + self.pool_states[connection].refresh() + + def remove(self, server): + if server in self.servers: + self.servers.remove(server) + else: + if log_enabled(ERROR): + log(ERROR, 'server %s to be removed not in Server Pool <%s>', server, self) + raise LDAPServerPoolError('server not in server pool') + + if self.single: + if self._pool_state: + self._pool_state.refresh() + else: + for connection in self.pool_states: + # notifies connections using this pool to refresh + self.pool_states[connection].refresh() + + def initialize(self, connection): + # registers pool_state in ServerPool object + if self.single: + if not self._pool_state: + self._pool_state = ServerPoolState(self) + self.pool_states[connection] = self._pool_state + else: + self.pool_states[connection] = ServerPoolState(self) + + def get_server(self, connection): + if connection in self.pool_states: + return self.pool_states[connection].get_server() + else: + if log_enabled(ERROR): + log(ERROR, 'connection <%s> not in Server Pool State <%s>', connection, self) + raise LDAPServerPoolError('connection not in ServerPoolState') + + def get_current_server(self, connection): + if connection in self.pool_states: + return self.pool_states[connection].get_current_server() + else: + if log_enabled(ERROR): + log(ERROR, 'connection <%s> not in Server Pool State <%s>', connection, self) + raise LDAPServerPoolError('connection not in ServerPoolState') diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/rdns.py b/plugins/ldap-user-sync/vendor/ldap3/core/rdns.py new file mode 100644 index 00000000..b3bbe6ac --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/rdns.py @@ -0,0 +1,68 @@ +""" Utilities and constants related to reverse dns lookup """ + +# Created on 2020.09.16 +# +# Author: Azaria Zornberg +# +# Copyright 2020 Giovanni Cannata +# Copyright 2020 Azaria Zornberg +# +# 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 . + +import socket + + +class ReverseDnsSetting(object): + OFF = 0, + REQUIRE_RESOLVE_ALL_ADDRESSES = 1, + REQUIRE_RESOLVE_IP_ADDRESSES_ONLY = 2, + OPTIONAL_RESOLVE_ALL_ADDRESSES = 3, + OPTIONAL_RESOLVE_IP_ADDRESSES_ONLY = 4, + SUPPORTED_VALUES = {OFF, REQUIRE_RESOLVE_ALL_ADDRESSES, REQUIRE_RESOLVE_IP_ADDRESSES_ONLY, + OPTIONAL_RESOLVE_ALL_ADDRESSES, OPTIONAL_RESOLVE_IP_ADDRESSES_ONLY} + + +def get_hostname_by_addr(addr, success_required=True): + """ Resolve the hostname for an ip address. If success is required, raise an exception if a hostname cannot + be resolved for the address. + Returns the hostname resolved for the address. + If success is not required, returns None for addresses that do not resolve to hostnames. + """ + try: + return socket.gethostbyaddr(addr)[0] + except Exception as ex: + # if we need to succeed, just re-raise + if success_required: + raise + return None + + +def is_ip_addr(addr): + """Returns True if an address is an ipv4 address or an ipv6 address based on format. False otherwise.""" + for addr_type in [socket.AF_INET, socket.AF_INET6]: + try: + socket.inet_pton(addr_type, addr) # not present on python 2.7 on Windows + return True + except AttributeError: # not present on Windows, always valid + if '.' in addr and any([c.isalpha() for c in addr.replace('.', '')]): # not an IPv4 address, probably an hostname + return False + else: # do not check for ipv6 + return True + except OSError: + pass + + return False diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/results.py b/plugins/ldap-user-sync/vendor/ldap3/core/results.py new file mode 100644 index 00000000..be5da2c3 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/results.py @@ -0,0 +1,137 @@ +""" +""" + +# Created on 2016.08.31 +# +# 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 . + + +# result codes +RESULT_SUCCESS = 0 +RESULT_OPERATIONS_ERROR = 1 +RESULT_PROTOCOL_ERROR = 2 +RESULT_TIME_LIMIT_EXCEEDED = 3 +RESULT_SIZE_LIMIT_EXCEEDED = 4 +RESULT_COMPARE_FALSE = 5 +RESULT_COMPARE_TRUE = 6 +RESULT_AUTH_METHOD_NOT_SUPPORTED = 7 +RESULT_STRONGER_AUTH_REQUIRED = 8 +RESULT_RESERVED = 9 +RESULT_REFERRAL = 10 +RESULT_ADMIN_LIMIT_EXCEEDED = 11 +RESULT_UNAVAILABLE_CRITICAL_EXTENSION = 12 +RESULT_CONFIDENTIALITY_REQUIRED = 13 +RESULT_SASL_BIND_IN_PROGRESS = 14 +RESULT_NO_SUCH_ATTRIBUTE = 16 +RESULT_UNDEFINED_ATTRIBUTE_TYPE = 17 +RESULT_INAPPROPRIATE_MATCHING = 18 +RESULT_CONSTRAINT_VIOLATION = 19 +RESULT_ATTRIBUTE_OR_VALUE_EXISTS = 20 +RESULT_INVALID_ATTRIBUTE_SYNTAX = 21 +RESULT_NO_SUCH_OBJECT = 32 +RESULT_ALIAS_PROBLEM = 33 +RESULT_INVALID_DN_SYNTAX = 34 +RESULT_ALIAS_DEREFERENCING_PROBLEM = 36 +RESULT_INAPPROPRIATE_AUTHENTICATION = 48 +RESULT_INVALID_CREDENTIALS = 49 +RESULT_INSUFFICIENT_ACCESS_RIGHTS = 50 +RESULT_BUSY = 51 +RESULT_UNAVAILABLE = 52 +RESULT_UNWILLING_TO_PERFORM = 53 +RESULT_LOOP_DETECTED = 54 +RESULT_NAMING_VIOLATION = 64 +RESULT_OBJECT_CLASS_VIOLATION = 65 +RESULT_NOT_ALLOWED_ON_NON_LEAF = 66 +RESULT_NOT_ALLOWED_ON_RDN = 67 +RESULT_ENTRY_ALREADY_EXISTS = 68 +RESULT_OBJECT_CLASS_MODS_PROHIBITED = 69 +RESULT_AFFECT_MULTIPLE_DSAS = 71 +RESULT_OTHER = 80 +RESULT_LCUP_RESOURCES_EXHAUSTED = 113 +RESULT_LCUP_SECURITY_VIOLATION = 114 +RESULT_LCUP_INVALID_DATA = 115 +RESULT_LCUP_UNSUPPORTED_SCHEME = 116 +RESULT_LCUP_RELOAD_REQUIRED = 117 +RESULT_CANCELED = 118 +RESULT_NO_SUCH_OPERATION = 119 +RESULT_TOO_LATE = 120 +RESULT_CANNOT_CANCEL = 121 +RESULT_ASSERTION_FAILED = 122 +RESULT_AUTHORIZATION_DENIED = 123 +RESULT_E_SYNC_REFRESH_REQUIRED = 4096 + +RESULT_CODES = { + RESULT_SUCCESS: 'success', + RESULT_OPERATIONS_ERROR: 'operationsError', + RESULT_PROTOCOL_ERROR: 'protocolError', + RESULT_TIME_LIMIT_EXCEEDED: 'timeLimitExceeded', + RESULT_SIZE_LIMIT_EXCEEDED: 'sizeLimitExceeded', + RESULT_COMPARE_FALSE: 'compareFalse', + RESULT_COMPARE_TRUE: 'compareTrue', + RESULT_AUTH_METHOD_NOT_SUPPORTED: 'authMethodNotSupported', + RESULT_RESERVED: 'reserved', + RESULT_STRONGER_AUTH_REQUIRED: 'strongerAuthRequired', + RESULT_REFERRAL: 'referral', + RESULT_ADMIN_LIMIT_EXCEEDED: 'adminLimitExceeded', + RESULT_UNAVAILABLE_CRITICAL_EXTENSION: 'unavailableCriticalExtension', + RESULT_CONFIDENTIALITY_REQUIRED: 'confidentialityRequired', + RESULT_SASL_BIND_IN_PROGRESS: 'saslBindInProgress', + RESULT_NO_SUCH_ATTRIBUTE: 'noSuchAttribute', + RESULT_UNDEFINED_ATTRIBUTE_TYPE: 'undefinedAttributeType', + RESULT_INAPPROPRIATE_MATCHING: 'inappropriateMatching', + RESULT_CONSTRAINT_VIOLATION: 'constraintViolation', + RESULT_ATTRIBUTE_OR_VALUE_EXISTS: 'attributeOrValueExists', + RESULT_INVALID_ATTRIBUTE_SYNTAX: 'invalidAttributeSyntax', + RESULT_NO_SUCH_OBJECT: 'noSuchObject', + RESULT_ALIAS_PROBLEM: 'aliasProblem', + RESULT_INVALID_DN_SYNTAX: 'invalidDNSyntax', + RESULT_ALIAS_DEREFERENCING_PROBLEM: 'aliasDereferencingProblem', + RESULT_INAPPROPRIATE_AUTHENTICATION: 'inappropriateAuthentication', + RESULT_INVALID_CREDENTIALS: 'invalidCredentials', + RESULT_INSUFFICIENT_ACCESS_RIGHTS: 'insufficientAccessRights', + RESULT_BUSY: 'busy', + RESULT_UNAVAILABLE: 'unavailable', + RESULT_UNWILLING_TO_PERFORM: 'unwillingToPerform', + RESULT_LOOP_DETECTED: 'loopDetected', + RESULT_NAMING_VIOLATION: 'namingViolation', + RESULT_OBJECT_CLASS_VIOLATION: 'objectClassViolation', + RESULT_NOT_ALLOWED_ON_NON_LEAF: 'notAllowedOnNonLeaf', + RESULT_NOT_ALLOWED_ON_RDN: 'notAllowedOnRDN', + RESULT_ENTRY_ALREADY_EXISTS: 'entryAlreadyExists', + RESULT_OBJECT_CLASS_MODS_PROHIBITED: 'objectClassModsProhibited', + RESULT_AFFECT_MULTIPLE_DSAS: 'affectMultipleDSAs', + RESULT_OTHER: 'other', + RESULT_LCUP_RESOURCES_EXHAUSTED: 'lcupResourcesExhausted', + RESULT_LCUP_SECURITY_VIOLATION: 'lcupSecurityViolation', + RESULT_LCUP_INVALID_DATA: 'lcupInvalidData', + RESULT_LCUP_UNSUPPORTED_SCHEME: 'lcupUnsupportedScheme', + RESULT_LCUP_RELOAD_REQUIRED: 'lcupReloadRequired', + RESULT_CANCELED: 'canceled', + RESULT_NO_SUCH_OPERATION: 'noSuchOperation', + RESULT_TOO_LATE: 'tooLate', + RESULT_CANNOT_CANCEL: 'cannotCancel', + RESULT_ASSERTION_FAILED: 'assertionFailed', + RESULT_AUTHORIZATION_DENIED: 'authorizationDenied', + RESULT_E_SYNC_REFRESH_REQUIRED: 'e-syncRefreshRequired' +} + +# do not raise exception for (in raise_exceptions connection mode) +DO_NOT_RAISE_EXCEPTIONS = [RESULT_SUCCESS, RESULT_COMPARE_FALSE, RESULT_COMPARE_TRUE, RESULT_REFERRAL, RESULT_SASL_BIND_IN_PROGRESS, RESULT_SIZE_LIMIT_EXCEEDED, RESULT_TIME_LIMIT_EXCEEDED] diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/server.py b/plugins/ldap-user-sync/vendor/ldap3/core/server.py new file mode 100644 index 00000000..41ff2afa --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/server.py @@ -0,0 +1,682 @@ +""" +""" + +# Created on 2014.05.31 +# +# 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 . + +import socket +from threading import Lock +from datetime import datetime, MINYEAR + +from .. import DSA, SCHEMA, ALL, BASE, get_config_parameter, OFFLINE_EDIR_8_8_8, OFFLINE_EDIR_9_1_4, OFFLINE_AD_2012_R2, OFFLINE_SLAPD_2_4, OFFLINE_DS389_1_3_3, SEQUENCE_TYPES, IP_SYSTEM_DEFAULT, IP_V4_ONLY, IP_V6_ONLY, IP_V4_PREFERRED, IP_V6_PREFERRED, STRING_TYPES +from .exceptions import LDAPInvalidServerError, LDAPDefinitionError, LDAPInvalidPortError, LDAPInvalidTlsSpecificationError, LDAPSocketOpenError, LDAPInfoError +from ..protocol.formatters.standard import format_attribute_values +from ..protocol.rfc4511 import LDAP_MAX_INT +from ..protocol.rfc4512 import SchemaInfo, DsaInfo +from .tls import Tls +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, NETWORK +from ..utils.conv import to_unicode +from ..utils.port_validators import check_port, check_port_and_port_list + +try: + from urllib.parse import unquote # Python 3 +except ImportError: + from urllib import unquote # Python 2 + +try: # try to discover if unix sockets are available for LDAP over IPC (ldapi:// scheme) + # noinspection PyUnresolvedReferences + from socket import AF_UNIX + unix_socket_available = True +except ImportError: + unix_socket_available = False + + +class Server(object): + """ + LDAP Server definition class + + Allowed_referral_hosts can be None (default), or a list of tuples of + allowed servers ip address or names to contact while redirecting + search to referrals. + + The second element of the tuple is a boolean to indicate if + authentication to that server is allowed; if False only anonymous + bind will be used. + + Per RFC 4516. Use [('*', False)] to allow any host with anonymous + bind, use [('*', True)] to allow any host with same authentication of + Server. + """ + + _message_counter = 0 + _message_id_lock = Lock() # global lock for message_id shared by all Server objects + + def __init__(self, + host, + port=None, + use_ssl=False, + allowed_referral_hosts=None, + get_info=SCHEMA, + tls=None, + formatter=None, + connect_timeout=None, + mode=IP_V6_PREFERRED, + validator=None): + + self.ipc = False + url_given = False + host = host.strip() + if host.lower().startswith('ldap://'): + self.host = host[7:] + use_ssl = False + url_given = True + elif host.lower().startswith('ldaps://'): + self.host = host[8:] + use_ssl = True + url_given = True + elif host.lower().startswith('ldapi://') and unix_socket_available: + self.ipc = True + use_ssl = False + url_given = True + elif host.lower().startswith('ldapi://') and not unix_socket_available: + raise LDAPSocketOpenError('LDAP over IPC not available - UNIX sockets non present') + else: + self.host = host + + if self.ipc: + if str is bytes: # Python 2 + self.host = unquote(host[7:]).decode('utf-8') + else: # Python 3 + self.host = unquote(host[7:]) # encoding defaults to utf-8 in python3 + self.port = None + elif ':' in self.host and self.host.count(':') == 1: + hostname, _, hostport = self.host.partition(':') + try: + port = int(hostport) or port + except ValueError: + if log_enabled(ERROR): + log(ERROR, 'port <%s> must be an integer', port) + raise LDAPInvalidPortError('port must be an integer') + self.host = hostname + elif url_given and self.host.startswith('['): + hostname, sep, hostport = self.host[1:].partition(']') + if sep != ']' or not self._is_ipv6(hostname): + if log_enabled(ERROR): + log(ERROR, 'invalid IPv6 server address for <%s>', self.host) + raise LDAPInvalidServerError() + if len(hostport): + if not hostport.startswith(':'): + if log_enabled(ERROR): + log(ERROR, 'invalid URL in server name for <%s>', self.host) + raise LDAPInvalidServerError('invalid URL in server name') + if not hostport[1:].isdecimal(): + if log_enabled(ERROR): + log(ERROR, 'port must be an integer for <%s>', self.host) + raise LDAPInvalidPortError('port must be an integer') + port = int(hostport[1:]) + self.host = hostname + elif not url_given and self._is_ipv6(self.host): + pass + elif self.host.count(':') > 1: + if log_enabled(ERROR): + log(ERROR, 'invalid server address for <%s>', self.host) + raise LDAPInvalidServerError() + + if not self.ipc: + self.host.rstrip('/') + if not use_ssl and not port: + port = 389 + elif use_ssl and not port: + port = 636 + + port_err = check_port(port) + if port_err: + if log_enabled(ERROR): + log(ERROR, port_err) + raise LDAPInvalidPortError(port_err) + self.port = port + + if allowed_referral_hosts is None: # defaults to any server with authentication + allowed_referral_hosts = [('*', True)] + + if isinstance(allowed_referral_hosts, SEQUENCE_TYPES): + self.allowed_referral_hosts = [] + for referral_host in allowed_referral_hosts: + if isinstance(referral_host, tuple): + if isinstance(referral_host[1], bool): + self.allowed_referral_hosts.append(referral_host) + elif isinstance(allowed_referral_hosts, tuple): + if isinstance(allowed_referral_hosts[1], bool): + self.allowed_referral_hosts = [allowed_referral_hosts] + else: + self.allowed_referral_hosts = [] + + self.ssl = True if use_ssl else False + if tls and not isinstance(tls, Tls): + if log_enabled(ERROR): + log(ERROR, 'invalid tls specification: <%s>', tls) + raise LDAPInvalidTlsSpecificationError('invalid Tls object') + + self.tls = Tls() if self.ssl and not tls else tls + + if not self.ipc: + if self._is_ipv6(self.host): + self.name = ('ldaps' if self.ssl else 'ldap') + '://[' + self.host + ']:' + str(self.port) + else: + self.name = ('ldaps' if self.ssl else 'ldap') + '://' + self.host + ':' + str(self.port) + else: + self.name = host + + self.get_info = get_info + self._dsa_info = None + self._schema_info = None + self.dit_lock = Lock() + self.custom_formatter = formatter + self.custom_validator = validator + self._address_info = [] # property self.address_info resolved at open time (or when check_availability is called) + self._address_info_resolved_time = datetime(MINYEAR, 1, 1) # smallest date ever + self.current_address = None + self.connect_timeout = connect_timeout + self.mode = mode + + self.get_info_from_server(None) # load offline schema if needed + + if log_enabled(BASIC): + log(BASIC, 'instantiated Server: <%r>', self) + + @staticmethod + def _is_ipv6(host): + try: + socket.inet_pton(socket.AF_INET6, host) + except (socket.error, AttributeError, ValueError): + return False + return True + + def __str__(self): + if self.host: + s = self.name + (' - ssl' if self.ssl else ' - cleartext') + (' - unix socket' if self.ipc else '') + else: + s = object.__str__(self) + return s + + def __repr__(self): + r = 'Server(host={0.host!r}, port={0.port!r}, use_ssl={0.ssl!r}'.format(self) + r += '' if not self.allowed_referral_hosts else ', allowed_referral_hosts={0.allowed_referral_hosts!r}'.format(self) + r += '' if self.tls is None else ', tls={0.tls!r}'.format(self) + r += '' if not self.get_info else ', get_info={0.get_info!r}'.format(self) + r += '' if not self.connect_timeout else ', connect_timeout={0.connect_timeout!r}'.format(self) + r += '' if not self.mode else ', mode={0.mode!r}'.format(self) + r += ')' + + return r + + @property + def address_info(self): + conf_refresh_interval = get_config_parameter('ADDRESS_INFO_REFRESH_TIME') + if not self._address_info or (datetime.now() - self._address_info_resolved_time).seconds > conf_refresh_interval: + # converts addresses tuple to list and adds a 6th parameter for availability (None = not checked, True = available, False=not available) and a 7th parameter for the checking time + addresses = None + try: + if self.ipc: + addresses = [(socket.AF_UNIX, socket.SOCK_STREAM, 0, None, self.host, None)] + else: + if self.mode == IP_V4_ONLY: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) + elif self.mode == IP_V6_ONLY: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) + else: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) + except (socket.gaierror, AttributeError): + pass + + if not addresses: # if addresses not found or raised an exception (for example for bad flags) tries again without flags + try: + if self.mode == IP_V4_ONLY: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) + elif self.mode == IP_V6_ONLY: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP) + else: + addresses = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.IPPROTO_TCP) + except socket.gaierror: + pass + + if addresses: + self._address_info = [list(address) + [None, None] for address in addresses] + self._address_info_resolved_time = datetime.now() + else: + self._address_info = [] + self._address_info_resolved_time = datetime(MINYEAR, 1, 1) # smallest date + + if log_enabled(BASIC): + for address in self._address_info: + log(BASIC, 'address for <%s> resolved as <%r>', self, address[:-2]) + return self._address_info + + def update_availability(self, address, available): + cont = 0 + while cont < len(self._address_info): + if self.address_info[cont] == address: + self._address_info[cont][5] = True if available else False + self._address_info[cont][6] = datetime.now() + break + cont += 1 + + def reset_availability(self): + for address in self._address_info: + address[5] = None + address[6] = None + + def check_availability(self, source_address=None, source_port=None, source_port_list=None): + """ + Tries to open, connect and close a socket to specified address and port to check availability. + Timeout in seconds is specified in CHECK_AVAILABITY_TIMEOUT if not specified in + the Server object. + If specified, use a specific address, port, or list of possible ports, when attempting to check availability. + NOTE: This will only consider multiple ports from the source port list if the first ones we try to bind to are + already in use. This will not attempt using different ports in the list if the server is unavailable, + as that could result in the runtime of check_availability significantly exceeding the connection timeout. + """ + source_port_err = check_port_and_port_list(source_port, source_port_list) + if source_port_err: + if log_enabled(ERROR): + log(ERROR, source_port_err) + raise LDAPInvalidPortError(source_port_err) + + # using an empty string to bind a socket means "use the default as if this wasn't provided" because socket + # binding requires that you pass something for the ip if you want to pass a specific port + bind_address = source_address if source_address is not None else '' + # using 0 as the source port to bind a socket means "use the default behavior of picking a random port from + # all ports as if this wasn't provided" because socket binding requires that you pass something for the port + # if you want to pass a specific ip + candidate_bind_ports = [0] + + # if we have either a source port or source port list, convert that into our candidate list + if source_port is not None: + candidate_bind_ports = [source_port] + elif source_port_list is not None: + candidate_bind_ports = source_port_list[:] + + conf_availability_timeout = get_config_parameter('CHECK_AVAILABILITY_TIMEOUT') + available = False + self.reset_availability() + for address in self.candidate_addresses(): + available = True + try: + temp_socket = socket.socket(*address[:3]) + + # Go through our candidate bind ports and try to bind our socket to our source address with them. + # if no source address or ports were specified, this will have the same success/fail result as if we + # tried to connect to the remote server without binding locally first. + # This is actually a little bit better, as it lets us distinguish the case of "issue binding the socket + # locally" from "remote server is unavailable" with more clarity, though this will only really be an + # issue when no source address/port is specified if the system checking server availability is running + # as a very unprivileged user. + last_bind_exc = None + socket_bind_succeeded = False + for bind_port in candidate_bind_ports: + try: + temp_socket.bind((bind_address, bind_port)) + socket_bind_succeeded = True + break + except Exception as bind_ex: + last_bind_exc = bind_ex + if log_enabled(NETWORK): + log(NETWORK, 'Unable to bind to local address <%s> with source port <%s> due to <%s>', + bind_address, bind_port, bind_ex) + if not socket_bind_succeeded: + if log_enabled(ERROR): + log(ERROR, 'Unable to locally bind to local address <%s> with any of the source ports <%s> due to <%s>', + bind_address, candidate_bind_ports, last_bind_exc) + raise LDAPSocketOpenError('Unable to bind socket locally to address {} with any of the source ports {} due to {}' + .format(bind_address, candidate_bind_ports, last_bind_exc)) + + if self.connect_timeout: + temp_socket.settimeout(self.connect_timeout) + else: + temp_socket.settimeout(conf_availability_timeout) # set timeout for checking availability to default + try: + temp_socket.connect(address[4]) + except socket.error: + available = False + finally: + try: + temp_socket.shutdown(socket.SHUT_RDWR) + except socket.error: + available = False + finally: + temp_socket.close() + except socket.gaierror: + available = False + + if available: + if log_enabled(BASIC): + log(BASIC, 'server <%s> available at <%r>', self, address) + self.update_availability(address, True) + break # if an available address is found exits immediately + else: + self.update_availability(address, False) + if log_enabled(ERROR): + log(ERROR, 'server <%s> not available at <%r>', self, address) + + return available + + @staticmethod + def next_message_id(): + """ + LDAP messageId is unique for all connections to same server + """ + with Server._message_id_lock: + Server._message_counter += 1 + if Server._message_counter >= LDAP_MAX_INT: + Server._message_counter = 1 + if log_enabled(PROTOCOL): + log(PROTOCOL, 'new message id <%d> generated', Server._message_counter) + + return Server._message_counter + + def _get_dsa_info(self, connection): + """ + Retrieve DSE operational attribute as per RFC4512 (5.1). + """ + if connection.strategy.no_real_dsa: # do not try for mock strategies + return + + if not connection.strategy.pooled: # in pooled strategies get_dsa_info is performed by the worker threads + result = connection.search(search_base='', + search_filter='(objectClass=*)', + search_scope=BASE, + attributes=['altServer', # requests specific dsa info attributes + 'namingContexts', + 'supportedControl', + 'supportedExtension', + 'supportedFeatures', + 'supportedCapabilities', + 'supportedLdapVersion', + 'supportedSASLMechanisms', + 'vendorName', + 'vendorVersion', + 'subschemaSubentry', + '*', + '+'], # requests all remaining attributes (other), + get_operational_attributes=True) + + if connection.strategy.thread_safe: + status, result, response, _ = result + else: + status = result + result = connection.result + response = connection.response + + with self.dit_lock: + if connection.strategy.sync: # sync request + self._dsa_info = DsaInfo(response[0]['attributes'], response[0]['raw_attributes']) if status else self._dsa_info + elif status: # asynchronous request, must check if attributes in response + results, _ = connection.get_response(status) + if len(results) == 1 and 'attributes' in results[0] and 'raw_attributes' in results[0]: + self._dsa_info = DsaInfo(results[0]['attributes'], results[0]['raw_attributes']) + + if log_enabled(BASIC): + log(BASIC, 'DSA info read for <%s> via <%s>', self, connection) + + def _get_schema_info(self, connection, entry=''): + """ + Retrieve schema from subschemaSubentry DSE attribute, per RFC + 4512 (4.4 and 5.1); entry = '' means DSE. + """ + if connection.strategy.no_real_dsa: # do not try for mock strategies + return + + schema_entry = None + if self._dsa_info and entry == '': # subschemaSubentry already present in dsaInfo + if isinstance(self._dsa_info.schema_entry, SEQUENCE_TYPES): + schema_entry = self._dsa_info.schema_entry[0] if self._dsa_info.schema_entry else None + else: + schema_entry = self._dsa_info.schema_entry if self._dsa_info.schema_entry else None + else: + result = connection.search(entry, '(objectClass=*)', BASE, attributes=['subschemaSubentry'], get_operational_attributes=True) + if connection.strategy.thread_safe: + status, result, response, _ = result + else: + status = result + result = connection.result + response = connection.response + if connection.strategy.sync: # sync request + if status and 'subschemaSubentry' in response[0]['raw_attributes']: + if len(response[0]['raw_attributes']['subschemaSubentry']) > 0: + schema_entry = response[0]['raw_attributes']['subschemaSubentry'][0] + else: # asynchronous request, must check if subschemaSubentry in attributes + results, _ = connection.get_response(status) + if len(results) == 1 and 'raw_attributes' in results[0] and 'subschemaSubentry' in results[0]['attributes']: + if len(results[0]['raw_attributes']['subschemaSubentry']) > 0: + schema_entry = results[0]['raw_attributes']['subschemaSubentry'][0] + + if schema_entry and not connection.strategy.pooled: # in pooled strategies get_schema_info is performed by the worker threads + if isinstance(schema_entry, bytes) and str is not bytes: # Python 3 + schema_entry = to_unicode(schema_entry, from_server=True) + result = connection.search(schema_entry, + search_filter='(objectClass=subschema)', + search_scope=BASE, + attributes=['objectClasses', # requests specific subschema attributes + 'attributeTypes', + 'ldapSyntaxes', + 'matchingRules', + 'matchingRuleUse', + 'dITContentRules', + 'dITStructureRules', + 'nameForms', + 'createTimestamp', + 'modifyTimestamp', + '*'], # requests all remaining attributes (other) + get_operational_attributes=True + ) + if connection.strategy.thread_safe: + status, result, response, _ = result + else: + status = result + result = connection.result + response = connection.response + with self.dit_lock: + self._schema_info = None + if status: + if connection.strategy.sync: # sync request + self._schema_info = SchemaInfo(schema_entry, response[0]['attributes'], response[0]['raw_attributes']) + else: # asynchronous request, must check if attributes in response + results, result = connection.get_response(status) + if len(results) == 1 and 'attributes' in results[0] and 'raw_attributes' in results[0]: + self._schema_info = SchemaInfo(schema_entry, results[0]['attributes'], results[0]['raw_attributes']) + if self._schema_info and not self._schema_info.is_valid(): # flaky servers can return an empty schema, checks if it is so and set schema to None + self._schema_info = None + if self._schema_info: # if schema is valid tries to apply formatter to the "other" dict with raw values for schema and info + for attribute in self._schema_info.other: + self._schema_info.other[attribute] = format_attribute_values(self._schema_info, attribute, self._schema_info.raw[attribute], self.custom_formatter) + if self._dsa_info: # try to apply formatter to the "other" dict with dsa info raw values + for attribute in self._dsa_info.other: + self._dsa_info.other[attribute] = format_attribute_values(self._schema_info, attribute, self._dsa_info.raw[attribute], self.custom_formatter) + if log_enabled(BASIC): + log(BASIC, 'schema read for <%s> via <%s>', self, connection) + + def get_info_from_server(self, connection): + """ + reads info from DSE and from subschema + """ + if connection and not connection.closed: + if self.get_info in [DSA, ALL]: + self._get_dsa_info(connection) + if self.get_info in [SCHEMA, ALL]: + self._get_schema_info(connection) + elif self.get_info == OFFLINE_EDIR_8_8_8: + from ..protocol.schemas.edir888 import edir_8_8_8_schema, edir_8_8_8_dsa_info + self.attach_schema_info(SchemaInfo.from_json(edir_8_8_8_schema)) + self.attach_dsa_info(DsaInfo.from_json(edir_8_8_8_dsa_info)) + elif self.get_info == OFFLINE_EDIR_9_1_4: + from ..protocol.schemas.edir914 import edir_9_1_4_schema, edir_9_1_4_dsa_info + self.attach_schema_info(SchemaInfo.from_json(edir_9_1_4_schema)) + self.attach_dsa_info(DsaInfo.from_json(edir_9_1_4_dsa_info)) + elif self.get_info == OFFLINE_AD_2012_R2: + from ..protocol.schemas.ad2012R2 import ad_2012_r2_schema, ad_2012_r2_dsa_info + self.attach_schema_info(SchemaInfo.from_json(ad_2012_r2_schema)) + self.attach_dsa_info(DsaInfo.from_json(ad_2012_r2_dsa_info)) + elif self.get_info == OFFLINE_SLAPD_2_4: + from ..protocol.schemas.slapd24 import slapd_2_4_schema, slapd_2_4_dsa_info + self.attach_schema_info(SchemaInfo.from_json(slapd_2_4_schema)) + self.attach_dsa_info(DsaInfo.from_json(slapd_2_4_dsa_info)) + elif self.get_info == OFFLINE_DS389_1_3_3: + from ..protocol.schemas.ds389 import ds389_1_3_3_schema, ds389_1_3_3_dsa_info + self.attach_schema_info(SchemaInfo.from_json(ds389_1_3_3_schema)) + self.attach_dsa_info(DsaInfo.from_json(ds389_1_3_3_dsa_info)) + + def attach_dsa_info(self, dsa_info=None): + if isinstance(dsa_info, DsaInfo): + self._dsa_info = dsa_info + if log_enabled(BASIC): + log(BASIC, 'attached DSA info to Server <%s>', self) + + def attach_schema_info(self, dsa_schema=None): + if isinstance(dsa_schema, SchemaInfo): + self._schema_info = dsa_schema + if log_enabled(BASIC): + log(BASIC, 'attached schema info to Server <%s>', self) + + @property + def info(self): + return self._dsa_info + + @property + def schema(self): + return self._schema_info + + @staticmethod + def from_definition(host, dsa_info, dsa_schema, port=None, use_ssl=False, formatter=None, validator=None): + """ + Define a dummy server with preloaded schema and info + :param host: host name + :param dsa_info: DsaInfo preloaded object or a json formatted string or a file name + :param dsa_schema: SchemaInfo preloaded object or a json formatted string or a file name + :param port: fake port + :param use_ssl: use_ssl + :param formatter: custom formatters + :return: Server object + """ + if isinstance(host, SEQUENCE_TYPES): + dummy = Server(host=host[0], port=port, use_ssl=use_ssl, formatter=formatter, validator=validator, get_info=ALL) # for ServerPool object + else: + dummy = Server(host=host, port=port, use_ssl=use_ssl, formatter=formatter, validator=validator, get_info=ALL) + if isinstance(dsa_info, DsaInfo): + dummy._dsa_info = dsa_info + elif isinstance(dsa_info, STRING_TYPES): + try: + dummy._dsa_info = DsaInfo.from_json(dsa_info) # tries to use dsa_info as a json configuration string + except Exception: + dummy._dsa_info = DsaInfo.from_file(dsa_info) # tries to use dsa_info as a file name + + if not dummy.info: + if log_enabled(ERROR): + log(ERROR, 'invalid DSA info for %s', host) + raise LDAPDefinitionError('invalid dsa info') + + if isinstance(dsa_schema, SchemaInfo): + dummy._schema_info = dsa_schema + elif isinstance(dsa_schema, STRING_TYPES): + try: + dummy._schema_info = SchemaInfo.from_json(dsa_schema) + except Exception: + dummy._schema_info = SchemaInfo.from_file(dsa_schema) + + if not dummy.schema: + if log_enabled(ERROR): + log(ERROR, 'invalid schema info for %s', host) + raise LDAPDefinitionError('invalid schema info') + + if log_enabled(BASIC): + log(BASIC, 'created server <%s> from definition', dummy) + + return dummy + + def candidate_addresses(self): + conf_reset_availability_timeout = get_config_parameter('RESET_AVAILABILITY_TIMEOUT') + if self.ipc: + candidates = self.address_info + if log_enabled(BASIC): + log(BASIC, 'candidate address for <%s>: <%s> with mode UNIX_SOCKET', self, self.name) + else: + # checks reset availability timeout + for address in self.address_info: + if address[6] and ((datetime.now() - address[6]).seconds > conf_reset_availability_timeout): + address[5] = None + address[6] = None + + # selects server address based on server mode and availability (in address[5]) + addresses = self.address_info[:] # copy to avoid refreshing while searching candidates + candidates = [] + if addresses: + if self.mode == IP_SYSTEM_DEFAULT: + candidates.append(addresses[0]) + elif self.mode == IP_V4_ONLY: + candidates = [address for address in addresses if address[0] == socket.AF_INET and (address[5] or address[5] is None)] + elif self.mode == IP_V6_ONLY: + candidates = [address for address in addresses if address[0] == socket.AF_INET6 and (address[5] or address[5] is None)] + elif self.mode == IP_V4_PREFERRED: + candidates = [address for address in addresses if address[0] == socket.AF_INET and (address[5] or address[5] is None)] + candidates += [address for address in addresses if address[0] == socket.AF_INET6 and (address[5] or address[5] is None)] + elif self.mode == IP_V6_PREFERRED: + candidates = [address for address in addresses if address[0] == socket.AF_INET6 and (address[5] or address[5] is None)] + candidates += [address for address in addresses if address[0] == socket.AF_INET and (address[5] or address[5] is None)] + else: + if log_enabled(ERROR): + log(ERROR, 'invalid server mode for <%s>', self) + raise LDAPInvalidServerError('invalid server mode') + + if log_enabled(BASIC): + for candidate in candidates: + log(BASIC, 'obtained candidate address for <%s>: <%r> with mode %s', self, candidate[:-2], self.mode) + return candidates + + def _check_info_property(self, kind, name): + if not self._dsa_info: + raise LDAPInfoError('server info not loaded') + + if kind == 'control': + properties = self.info.supported_controls + elif kind == 'extension': + properties = self.info.supported_extensions + elif kind == 'feature': + properties = self.info.supported_features + else: + raise LDAPInfoError('invalid info category') + + for prop in properties: + if name == prop[0] or (prop[2] and name.lower() == prop[2].lower()): # checks oid and description + return True + + return False + + def has_control(self, control): + return self._check_info_property('control', control) + + def has_extension(self, extension): + return self._check_info_property('extension', extension) + + def has_feature(self, feature): + return self._check_info_property('feature', feature) + + + diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/timezone.py b/plugins/ldap-user-sync/vendor/ldap3/core/timezone.py new file mode 100644 index 00000000..f46d8f26 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/timezone.py @@ -0,0 +1,56 @@ +""" +""" + +# Created on 2015.01.07 +# +# 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 . + +from datetime import timedelta, tzinfo + + +# from python standard library docs +class OffsetTzInfo(tzinfo): + """Fixed offset in minutes east from UTC""" + + def __init__(self, offset, name): + self.offset = offset + self.name = name + self._offset = timedelta(minutes=offset) + + def __str__(self): + return self.name + + def __repr__(self): + + return 'OffsetTzInfo(offset={0.offset!r}, name={0.name!r})'.format(self) + + def utcoffset(self, dt): + return self._offset + + def tzname(self, dt): + return self.name + + # noinspection PyMethodMayBeStatic + def dst(self, dt): + return timedelta(0) + + def __getinitargs__(self): # for pickling/unpickling + return self.offset, self.name diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py new file mode 100644 index 00000000..ca8592b3 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -0,0 +1,327 @@ +""" +""" + +# Created on 2013.08.05 +# +# 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 . + +from .exceptions import LDAPSSLNotSupportedError, LDAPSSLConfigurationError, LDAPCertificateError, start_tls_exception_factory, LDAPStartTLSError +from .. import SEQUENCE_TYPES +from ..utils.log import log, log_enabled, ERROR, BASIC, NETWORK + +try: + # noinspection PyUnresolvedReferences + import ssl +except ImportError: + if log_enabled(ERROR): + log(ERROR, 'SSL not supported in this Python interpreter') + raise LDAPSSLNotSupportedError('SSL not supported in this Python interpreter') + +try: + from ssl import match_hostname, CertificateError # backport for python2 missing ssl functionalities +except ImportError: + from ..utils.tls_backport import CertificateError + from ..utils.tls_backport import match_hostname + if log_enabled(BASIC): + log(BASIC, 'using tls_backport') + +try: # try to use SSLContext + # noinspection PyUnresolvedReferences + from ssl import create_default_context, Purpose # defined in Python 3.4 and Python 2.7.9 + use_ssl_context = True +except ImportError: + use_ssl_context = False + if log_enabled(BASIC): + log(BASIC, 'SSLContext unavailable') + +from os import path + + +# noinspection PyProtectedMember +class Tls(object): + """ + tls/ssl configuration for Server object + Starting from python 2.7.9 and python 3.4 uses the SSLContext object + that tries to read the CAs defined at system level + ca_certs_path and ca_certs_data are valid only when using SSLContext + local_private_key_password is valid only when using SSLContext + ssl_options is valid only when using SSLContext + sni is the server name for Server Name Indication (when available) + """ + + def __init__(self, + local_private_key_file=None, + local_certificate_file=None, + validate=ssl.CERT_NONE, + version=None, + ssl_options=None, + ca_certs_file=None, + valid_names=None, + ca_certs_path=None, + ca_certs_data=None, + local_private_key_password=None, + ciphers=None, + sni=None): + if ssl_options is None: + ssl_options = [] + self.ssl_options = ssl_options + if validate in [ssl.CERT_NONE, ssl.CERT_OPTIONAL, ssl.CERT_REQUIRED]: + self.validate = validate + elif validate: + if log_enabled(ERROR): + log(ERROR, 'invalid validate parameter <%s>', validate) + raise LDAPSSLConfigurationError('invalid validate parameter') + if ca_certs_file and path.exists(ca_certs_file): + self.ca_certs_file = ca_certs_file + elif ca_certs_file: + if log_enabled(ERROR): + log(ERROR, 'invalid CA public key file <%s>', ca_certs_file) + raise LDAPSSLConfigurationError('invalid CA public key file') + else: + self.ca_certs_file = None + + if ca_certs_path and use_ssl_context and path.exists(ca_certs_path): + self.ca_certs_path = ca_certs_path + elif ca_certs_path and not use_ssl_context: + if log_enabled(ERROR): + log(ERROR, 'cannot use CA public keys path, SSLContext not available') + raise LDAPSSLNotSupportedError('cannot use CA public keys path, SSLContext not available') + elif ca_certs_path: + if log_enabled(ERROR): + log(ERROR, 'invalid CA public keys path <%s>', ca_certs_path) + raise LDAPSSLConfigurationError('invalid CA public keys path') + else: + self.ca_certs_path = None + + if ca_certs_data and use_ssl_context: + self.ca_certs_data = ca_certs_data + elif ca_certs_data: + if log_enabled(ERROR): + log(ERROR, 'cannot use CA data, SSLContext not available') + raise LDAPSSLNotSupportedError('cannot use CA data, SSLContext not available') + else: + self.ca_certs_data = None + + if local_private_key_password and use_ssl_context: + self.private_key_password = local_private_key_password + elif local_private_key_password: + if log_enabled(ERROR): + log(ERROR, 'cannot use local private key password, SSLContext not available') + raise LDAPSSLNotSupportedError('cannot use local private key password, SSLContext is not available') + else: + self.private_key_password = None + + self.version = version + self.private_key_file = local_private_key_file + self.certificate_file = local_certificate_file + self.valid_names = valid_names + self.ciphers = ciphers + self.sni = sni + + if log_enabled(BASIC): + log(BASIC, 'instantiated Tls: <%r>' % self) + + def __str__(self): + s = [ + 'protocol: ' + str(self.version), + 'client private key: ' + ('present ' if self.private_key_file else 'not present'), + 'client certificate: ' + ('present ' if self.certificate_file else 'not present'), + 'private key password: ' + ('present ' if self.private_key_password else 'not present'), + 'CA certificates file: ' + ('present ' if self.ca_certs_file else 'not present'), + 'CA certificates path: ' + ('present ' if self.ca_certs_path else 'not present'), + 'CA certificates data: ' + ('present ' if self.ca_certs_data else 'not present'), + 'verify mode: ' + str(self.validate), + 'valid names: ' + str(self.valid_names), + 'ciphers: ' + str(self.ciphers), + 'sni: ' + str(self.sni) + ] + return ' - '.join(s) + + def __repr__(self): + r = '' if self.private_key_file is None else ', local_private_key_file={0.private_key_file!r}'.format(self) + r += '' if self.certificate_file is None else ', local_certificate_file={0.certificate_file!r}'.format(self) + r += '' if self.validate is None else ', validate={0.validate!r}'.format(self) + r += '' if self.version is None else ', version={0.version!r}'.format(self) + r += '' if self.ca_certs_file is None else ', ca_certs_file={0.ca_certs_file!r}'.format(self) + r += '' if self.ca_certs_path is None else ', ca_certs_path={0.ca_certs_path!r}'.format(self) + r += '' if self.ca_certs_data is None else ', ca_certs_data={0.ca_certs_data!r}'.format(self) + r += '' if self.ciphers is None else ', ciphers={0.ciphers!r}'.format(self) + r += '' if self.sni is None else ', sni={0.sni!r}'.format(self) + r = 'Tls(' + r[2:] + ')' + return r + + def wrap_socket(self, connection, do_handshake=False): + """ + Adds TLS to the connection socket + """ + if use_ssl_context: + if self.version is None: # uses the default ssl context for reasonable security + ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH, + cafile=self.ca_certs_file, + capath=self.ca_certs_path, + cadata=self.ca_certs_data) + else: # code from create_default_context in the Python standard library 3.5.1, creates a ssl context with the specificd protocol version + ssl_context = ssl.SSLContext(self.version) + if self.ca_certs_file or self.ca_certs_path or self.ca_certs_data: + ssl_context.load_verify_locations(self.ca_certs_file, self.ca_certs_path, self.ca_certs_data) + elif self.validate != ssl.CERT_NONE: + ssl_context.load_default_certs(Purpose.SERVER_AUTH) + + if self.certificate_file: + ssl_context.load_cert_chain(self.certificate_file, keyfile=self.private_key_file, password=self.private_key_password) + ssl_context.check_hostname = False + ssl_context.verify_mode = self.validate + for option in self.ssl_options: + ssl_context.options |= option + + if self.ciphers: + try: + ssl_context.set_ciphers(self.ciphers) + except ssl.SSLError: + pass + + if self.sni: + wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake, server_hostname=self.sni) + else: + wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake) + if log_enabled(NETWORK): + log(NETWORK, 'socket wrapped with SSL using SSLContext for <%s>', connection) + else: + if self.version is None and hasattr(ssl, 'PROTOCOL_SSLv23'): + self.version = ssl.PROTOCOL_SSLv23 + if self.ciphers: + try: + + wrapped_socket = ssl.wrap_socket(connection.socket, + keyfile=self.private_key_file, + certfile=self.certificate_file, + server_side=False, + cert_reqs=self.validate, + ssl_version=self.version, + ca_certs=self.ca_certs_file, + do_handshake_on_connect=do_handshake, + ciphers=self.ciphers) + except ssl.SSLError: + raise + except TypeError: # in python2.6 no ciphers argument is present, failback to self.ciphers=None + self.ciphers = None + + if not self.ciphers: + wrapped_socket = ssl.wrap_socket(connection.socket, + keyfile=self.private_key_file, + certfile=self.certificate_file, + server_side=False, + cert_reqs=self.validate, + ssl_version=self.version, + ca_certs=self.ca_certs_file, + do_handshake_on_connect=do_handshake) + if log_enabled(NETWORK): + log(NETWORK, 'socket wrapped with SSL for <%s>', connection) + + if do_handshake and (self.validate == ssl.CERT_REQUIRED or self.validate == ssl.CERT_OPTIONAL): + check_hostname(wrapped_socket, connection.server.host, self.valid_names) + + connection.socket = wrapped_socket + return + + def start_tls(self, connection): + if connection.server.ssl: # ssl already established at server level + return False + + if (connection.tls_started and not connection._executing_deferred) or connection.strategy._outstanding or connection.sasl_in_progress: + # Per RFC 4513 (3.1.1) + if log_enabled(ERROR): + log(ERROR, "can't start tls because operations are in progress for <%s>", self) + return False + connection.starting_tls = True + if log_enabled(BASIC): + log(BASIC, 'starting tls for <%s>', connection) + if not connection.strategy.sync: + connection._awaiting_for_async_start_tls = True # some flaky servers (OpenLDAP) doesn't return the extended response name in response + result = connection.extended('1.3.6.1.4.1.1466.20037') + if not connection.strategy.sync: + # asynchronous - _start_tls must be executed by the strategy + response = connection.get_response(result) + if response != (None, None): + if log_enabled(BASIC): + log(BASIC, 'tls started for <%s>', connection) + return True + else: + if log_enabled(BASIC): + log(BASIC, 'tls not started for <%s>', connection) + return False + else: + if connection.result['description'] not in ['success']: + # startTLS failed + connection.last_error = 'startTLS failed - ' + str(connection.result['description']) + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', connection.last_error, connection) + raise LDAPStartTLSError(connection.last_error) + if log_enabled(BASIC): + log(BASIC, 'tls started for <%s>', connection) + return self._start_tls(connection) + + def _start_tls(self, connection): + try: + self.wrap_socket(connection, do_handshake=True) + except Exception as e: + connection.last_error = 'wrap socket error: ' + str(e) + if log_enabled(ERROR): + log(ERROR, 'error <%s> wrapping socket for TLS in <%s>', connection.last_error, connection) + raise start_tls_exception_factory(e)(connection.last_error) + finally: + connection.starting_tls = False + + if connection.usage: + connection._usage.wrapped_sockets += 1 + connection.tls_started = True + return True + + +def check_hostname(sock, server_name, additional_names): + server_certificate = sock.getpeercert() + if log_enabled(NETWORK): + log(NETWORK, 'certificate found for %s: %s', sock, server_certificate) + if additional_names: + host_names = [server_name] + (additional_names if isinstance(additional_names, SEQUENCE_TYPES) else [additional_names]) + else: + host_names = [server_name] + + for host_name in host_names: + if not host_name: + continue + elif host_name == '*': + if log_enabled(NETWORK): + log(NETWORK, 'certificate matches * wildcard') + return # valid + + try: + match_hostname(server_certificate, host_name) # raise CertificateError if certificate doesn't match server name + if log_enabled(NETWORK): + log(NETWORK, 'certificate matches host name <%s>', host_name) + return # valid + except CertificateError as e: + if log_enabled(NETWORK): + log(NETWORK, str(e)) + + if log_enabled(ERROR): + log(ERROR, "hostname doesn't match certificate") + raise LDAPCertificateError("certificate %s doesn't match any name in %s " % (server_certificate, str(host_names))) diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/usage.py b/plugins/ldap-user-sync/vendor/ldap3/core/usage.py new file mode 100644 index 00000000..09693579 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/core/usage.py @@ -0,0 +1,229 @@ +""" +""" + +# Created on 2014.03.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 . + +from datetime import datetime, timedelta +from os import linesep + +from .exceptions import LDAPMetricsError +from ..utils.log import log, log_enabled, ERROR, BASIC + + +class ConnectionUsage(object): + """ + Collect statistics on connection usage + """ + + def reset(self): + self.open_sockets = 0 + self.closed_sockets = 0 + self.wrapped_sockets = 0 + self.bytes_transmitted = 0 + self.bytes_received = 0 + self.messages_transmitted = 0 + self.messages_received = 0 + self.operations = 0 + self.abandon_operations = 0 + self.add_operations = 0 + self.bind_operations = 0 + self.compare_operations = 0 + self.delete_operations = 0 + self.extended_operations = 0 + self.modify_operations = 0 + self.modify_dn_operations = 0 + self.search_operations = 0 + self.unbind_operations = 0 + self.referrals_received = 0 + self.referrals_followed = 0 + self.referrals_connections = 0 + self.restartable_failures = 0 + self.restartable_successes = 0 + self.servers_from_pool = 0 + if log_enabled(BASIC): + log(BASIC, 'reset usage metrics') + + def __init__(self): + self.initial_connection_start_time = None + self.open_socket_start_time = None + self.connection_stop_time = None + self.last_transmitted_time = None + self.last_received_time = None + self.open_sockets = 0 + self.closed_sockets = 0 + self.wrapped_sockets = 0 + self.bytes_transmitted = 0 + self.bytes_received = 0 + self.messages_transmitted = 0 + self.messages_received = 0 + self.operations = 0 + self.abandon_operations = 0 + self.add_operations = 0 + self.bind_operations = 0 + self.compare_operations = 0 + self.delete_operations = 0 + self.extended_operations = 0 + self.modify_operations = 0 + self.modify_dn_operations = 0 + self.search_operations = 0 + self.unbind_operations = 0 + self.referrals_received = 0 + self.referrals_followed = 0 + self.referrals_connections = 0 + self.restartable_failures = 0 + self.restartable_successes = 0 + self.servers_from_pool = 0 + + if log_enabled(BASIC): + log(BASIC, 'instantiated Usage object') + + def __repr__(self): + r = 'Connection Usage:' + linesep + r += ' Time: [elapsed: ' + str(self.elapsed_time) + ']' + linesep + r += ' Initial start time: ' + (str(self.initial_connection_start_time.isoformat()) if self.initial_connection_start_time else '') + linesep + r += ' Open socket time: ' + (str(self.open_socket_start_time.isoformat()) if self.open_socket_start_time else '') + linesep + r += ' Last transmitted time: ' + (str(self.last_transmitted_time.isoformat()) if self.last_transmitted_time else '') + linesep + r += ' Last received time: ' + (str(self.last_received_time.isoformat()) if self.last_received_time else '') + linesep + r += ' Close socket time: ' + (str(self.connection_stop_time.isoformat()) if self.connection_stop_time else '') + linesep + r += ' Server:' + linesep + r += ' Servers from pool: ' + str(self.servers_from_pool) + linesep + r += ' Sockets open: ' + str(self.open_sockets) + linesep + r += ' Sockets closed: ' + str(self.closed_sockets) + linesep + r += ' Sockets wrapped: ' + str(self.wrapped_sockets) + linesep + r += ' Bytes: ' + str(self.bytes_transmitted + self.bytes_received) + linesep + r += ' Transmitted: ' + str(self.bytes_transmitted) + linesep + r += ' Received: ' + str(self.bytes_received) + linesep + r += ' Messages: ' + str(self.messages_transmitted + self.messages_received) + linesep + r += ' Transmitted: ' + str(self.messages_transmitted) + linesep + r += ' Received: ' + str(self.messages_received) + linesep + r += ' Operations: ' + str(self.operations) + linesep + r += ' Abandon: ' + str(self.abandon_operations) + linesep + r += ' Bind: ' + str(self.bind_operations) + linesep + r += ' Add: ' + str(self.add_operations) + linesep + r += ' Compare: ' + str(self.compare_operations) + linesep + r += ' Delete: ' + str(self.delete_operations) + linesep + r += ' Extended: ' + str(self.extended_operations) + linesep + r += ' Modify: ' + str(self.modify_operations) + linesep + r += ' ModifyDn: ' + str(self.modify_dn_operations) + linesep + r += ' Search: ' + str(self.search_operations) + linesep + r += ' Unbind: ' + str(self.unbind_operations) + linesep + r += ' Referrals: ' + linesep + r += ' Received: ' + str(self.referrals_received) + linesep + r += ' Followed: ' + str(self.referrals_followed) + linesep + r += ' Connections: ' + str(self.referrals_connections) + linesep + r += ' Restartable tries: ' + str(self.restartable_failures + self.restartable_successes) + linesep + r += ' Failed restarts: ' + str(self.restartable_failures) + linesep + r += ' Successful restarts: ' + str(self.restartable_successes) + linesep + return r + + def __str__(self): + return self.__repr__() + + def __iadd__(self, other): + if not isinstance(other, ConnectionUsage): + raise LDAPMetricsError('unable to add to ConnectionUsage') + + self.open_sockets += other.open_sockets + self.closed_sockets += other.closed_sockets + self.wrapped_sockets += other.wrapped_sockets + self.bytes_transmitted += other.bytes_transmitted + self.bytes_received += other.bytes_received + self.messages_transmitted += other.messages_transmitted + self.messages_received += other.messages_received + self.operations += other.operations + self.abandon_operations += other.abandon_operations + self.add_operations += other.add_operations + self.bind_operations += other.bind_operations + self.compare_operations += other.compare_operations + self.delete_operations += other.delete_operations + self.extended_operations += other.extended_operations + self.modify_operations += other.modify_operations + self.modify_dn_operations += other.modify_dn_operations + self.search_operations += other.search_operations + self.unbind_operations += other.unbind_operations + self.referrals_received += other.referrals_received + self.referrals_followed += other.referrals_followed + self.referrals_connections += other.referrals_connections + self.restartable_failures += other.restartable_failures + self.restartable_successes += other.restartable_successes + self.servers_from_pool += other.servers_from_pool + return self + + def update_transmitted_message(self, message, length): + self.last_transmitted_time = datetime.now() + self.bytes_transmitted += length + self.operations += 1 + self.messages_transmitted += 1 + if message['type'] == 'abandonRequest': + self.abandon_operations += 1 + elif message['type'] == 'addRequest': + self.add_operations += 1 + elif message['type'] == 'bindRequest': + self.bind_operations += 1 + elif message['type'] == 'compareRequest': + self.compare_operations += 1 + elif message['type'] == 'delRequest': + self.delete_operations += 1 + elif message['type'] == 'extendedReq': + self.extended_operations += 1 + elif message['type'] == 'modifyRequest': + self.modify_operations += 1 + elif message['type'] == 'modDNRequest': + self.modify_dn_operations += 1 + elif message['type'] == 'searchRequest': + self.search_operations += 1 + elif message['type'] == 'unbindRequest': + self.unbind_operations += 1 + else: + if log_enabled(ERROR): + log(ERROR, 'unable to collect usage for unknown message type <%s>', message['type']) + raise LDAPMetricsError('unable to collect usage for unknown message type') + + def update_received_message(self, length): + self.last_received_time = datetime.now() + self.bytes_received += length + self.messages_received += 1 + + def start(self, reset=True): + if reset: + self.reset() + self.open_socket_start_time = datetime.now() + self.connection_stop_time = None + if not self.initial_connection_start_time: + self.initial_connection_start_time = self.open_socket_start_time + + if log_enabled(BASIC): + log(BASIC, 'start collecting usage metrics') + + def stop(self): + if self.open_socket_start_time: + self.connection_stop_time = datetime.now() + if log_enabled(BASIC): + log(BASIC, 'stop collecting usage metrics') + + @property + def elapsed_time(self): + if self.connection_stop_time: + return self.connection_stop_time - self.open_socket_start_time + else: + return (datetime.now() - self.open_socket_start_time) if self.open_socket_start_time else timedelta(0) diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/extend/__init__.py new file mode 100644 index 00000000..b359be58 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/__init__.py @@ -0,0 +1,334 @@ +""" +""" + +# 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 . + +from os import linesep + +from .. import SUBTREE, DEREF_ALWAYS, ALL_ATTRIBUTES, DEREF_NEVER +from .microsoft.dirSync import DirSync +from .microsoft.modifyPassword import ad_modify_password +from .microsoft.unlockAccount import ad_unlock_account +from .microsoft.addMembersToGroups import ad_add_members_to_groups +from .microsoft.removeMembersFromGroups import ad_remove_members_from_groups +from .microsoft.persistentSearch import ADPersistentSearch +from .novell.partition_entry_count import PartitionEntryCount +from .novell.replicaInfo import ReplicaInfo +from .novell.listReplicas import ListReplicas +from .novell.getBindDn import GetBindDn +from .novell.nmasGetUniversalPassword import NmasGetUniversalPassword +from .novell.nmasSetUniversalPassword import NmasSetUniversalPassword +from .novell.startTransaction import StartTransaction +from .novell.endTransaction import EndTransaction +from .novell.addMembersToGroups import edir_add_members_to_groups +from .novell.removeMembersFromGroups import edir_remove_members_from_groups +from .novell.checkGroupsMemberships import edir_check_groups_memberships +from .standard.whoAmI import WhoAmI +from .standard.modifyPassword import ModifyPassword +from .standard.PagedSearch import paged_search_generator, paged_search_accumulator +from .standard.PersistentSearch import PersistentSearch + + +class ExtendedOperationContainer(object): + def __init__(self, connection): + self._connection = connection + + def __repr__(self): + return linesep.join([' ' + element for element in dir(self) if element[0] != '_']) + + def __str__(self): + return self.__repr__() + + +class StandardExtendedOperations(ExtendedOperationContainer): + def who_am_i(self, controls=None): + return WhoAmI(self._connection, + controls).send() + + def modify_password(self, + user=None, + old_password=None, + new_password=None, + hash_algorithm=None, + salt=None, + controls=None): + + return ModifyPassword(self._connection, + user, + old_password, + new_password, + hash_algorithm, + salt, + controls).send() + + def paged_search(self, + search_base, + search_filter, + search_scope=SUBTREE, + dereference_aliases=DEREF_ALWAYS, + attributes=None, + size_limit=0, + time_limit=0, + types_only=False, + get_operational_attributes=False, + controls=None, + paged_size=100, + paged_criticality=False, + generator=True): + + if generator: + return paged_search_generator(self._connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + get_operational_attributes, + controls, + paged_size, + paged_criticality) + else: + return paged_search_accumulator(self._connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + get_operational_attributes, + controls, + paged_size, + paged_criticality) + + def persistent_search(self, + search_base='', + search_filter='(objectclass=*)', + search_scope=SUBTREE, + dereference_aliases=DEREF_NEVER, + attributes=ALL_ATTRIBUTES, + size_limit=0, + time_limit=0, + controls=None, + changes_only=True, + show_additions=True, + show_deletions=True, + show_modifications=True, + show_dn_modifications=True, + notifications=True, + streaming=True, + callback=None + ): + events_type = 0 + if show_additions: + events_type += 1 + if show_deletions: + events_type += 2 + if show_modifications: + events_type += 4 + if show_dn_modifications: + events_type += 8 + + if callback: + streaming = False + return PersistentSearch(self._connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + controls, + changes_only, + events_type, + notifications, + streaming, + callback) + + def funnel_search(self, + search_base='', + search_filter='', + search_scope=SUBTREE, + dereference_aliases=DEREF_NEVER, + attributes=ALL_ATTRIBUTES, + size_limit=0, + time_limit=0, + controls=None, + streaming=False, + callback=None + ): + return PersistentSearch(self._connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + controls, + None, + None, + None, + streaming, + callback) + + +class NovellExtendedOperations(ExtendedOperationContainer): + def get_bind_dn(self, controls=None): + return GetBindDn(self._connection, + controls).send() + + def get_universal_password(self, user, controls=None): + return NmasGetUniversalPassword(self._connection, + user, + controls).send() + + def set_universal_password(self, user, new_password=None, controls=None): + return NmasSetUniversalPassword(self._connection, + user, + new_password, + controls).send() + + def list_replicas(self, server_dn, controls=None): + return ListReplicas(self._connection, + server_dn, + controls).send() + + def partition_entry_count(self, partition_dn, controls=None): + return PartitionEntryCount(self._connection, + partition_dn, + controls).send() + + def replica_info(self, server_dn, partition_dn, controls=None): + return ReplicaInfo(self._connection, + server_dn, + partition_dn, + controls).send() + + def start_transaction(self, controls=None): + return StartTransaction(self._connection, + controls).send() + + def end_transaction(self, commit=True, controls=None): # attach the groupingControl to commit, None to abort transaction + return EndTransaction(self._connection, + commit, + controls).send() + + def add_members_to_groups(self, members, groups, fix=True, transaction=True): + return edir_add_members_to_groups(self._connection, + members_dn=members, + groups_dn=groups, + fix=fix, + transaction=transaction) + + def remove_members_from_groups(self, members, groups, fix=True, transaction=True): + return edir_remove_members_from_groups(self._connection, + members_dn=members, + groups_dn=groups, + fix=fix, + transaction=transaction) + + def check_groups_memberships(self, members, groups, fix=False, transaction=True): + return edir_check_groups_memberships(self._connection, + members_dn=members, + groups_dn=groups, + fix=fix, + transaction=transaction) + + +class MicrosoftExtendedOperations(ExtendedOperationContainer): + def dir_sync(self, + sync_base, + sync_filter='(objectclass=*)', + attributes=ALL_ATTRIBUTES, + cookie=None, + object_security=False, + ancestors_first=True, + public_data_only=False, + incremental_values=True, + max_length=2147483647, + hex_guid=False): + return DirSync(self._connection, + sync_base=sync_base, + sync_filter=sync_filter, + attributes=attributes, + cookie=cookie, + object_security=object_security, + ancestors_first=ancestors_first, + public_data_only=public_data_only, + incremental_values=incremental_values, + max_length=max_length, + hex_guid=hex_guid) + + def modify_password(self, user, new_password, old_password=None, controls=None): + return ad_modify_password(self._connection, + user, + new_password, + old_password, + controls) + + def unlock_account(self, user): + return ad_unlock_account(self._connection, + user) + + def add_members_to_groups(self, members, groups, fix=True): + return ad_add_members_to_groups(self._connection, + members_dn=members, + groups_dn=groups, + fix=fix) + + def remove_members_from_groups(self, members, groups, fix=True): + return ad_remove_members_from_groups(self._connection, + members_dn=members, + groups_dn=groups, + fix=fix) + + def persistent_search(self, + search_base='', + search_scope=SUBTREE, + attributes=ALL_ATTRIBUTES, + streaming=True, + callback=None + ): + + if callback: + streaming = False + return ADPersistentSearch(self._connection, + search_base, + search_scope, + attributes, + streaming, + callback) + + +class ExtendedOperationsRoot(ExtendedOperationContainer): + def __init__(self, connection): + ExtendedOperationContainer.__init__(self, connection) # calls super + self.standard = StandardExtendedOperations(self._connection) + self.novell = NovellExtendedOperations(self._connection) + self.microsoft = MicrosoftExtendedOperations(self._connection) diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/addMembersToGroups.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/addMembersToGroups.py new file mode 100644 index 00000000..fb6528a5 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/addMembersToGroups.py @@ -0,0 +1,98 @@ +""" +""" + +# Created on 2016.12.26 +# +# 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 . + +from ... import SEQUENCE_TYPES, MODIFY_ADD, BASE, DEREF_NEVER +from ...core.exceptions import LDAPInvalidDnError, LDAPOperationsErrorResult +from ...utils.dn import safe_dn + + +def ad_add_members_to_groups(connection, + members_dn, + groups_dn, + fix=True, + raise_error=False): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to add to groups + :param groups_dn: the list of groups where members are to be added + :param fix: checks for group existence and already assigned members + :param raise_error: If the operation fails it raises an error instead of returning False + :return: a boolean where True means that the operation was successful and False means an error has happened + Establishes users-groups relations following the Active Directory rules: users are added to the member attribute of groups. + Raises LDAPInvalidDnError if members or groups are not found in the DIT. + """ + + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + if connection.check_names: # builds new lists with sanitized dn + members_dn = [safe_dn(member_dn) for member_dn in members_dn] + groups_dn = [safe_dn(group_dn) for group_dn in groups_dn] + + error = False + for group in groups_dn: + if fix: # checks for existance of group and for already assigned members + result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member']) + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = connection.response + result = connection.result + + if not result['description'] == 'success': + raise LDAPInvalidDnError(group + ' not found') + + existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else [] + existing_members = [element.lower() for element in existing_members] + else: + existing_members = [] + + changes = dict() + member_to_add = [element for element in members_dn if element.lower() not in existing_members] + if member_to_add: + changes['member'] = (MODIFY_ADD, member_to_add) + if changes: + result = connection.modify(group, changes) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + result_error_params = ['result', 'description', 'dn', 'message'] + if raise_error: + raise LDAPOperationsErrorResult([(k, v) for k, v in result.items() if k in result_error_params]) + break + + return not error # returns True if no error is raised in the LDAP operations diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/dirSync.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/dirSync.py new file mode 100644 index 00000000..9778371c --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/dirSync.py @@ -0,0 +1,94 @@ +""" +""" + +# Created on 2015.10.21 +# +# 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 . + +from ...core.exceptions import LDAPExtensionError +from ...protocol.microsoft import dir_sync_control, extended_dn_control, show_deleted_control +from ... import SUBTREE, DEREF_NEVER +from ...utils.dn import safe_dn + + +class DirSync(object): + def __init__(self, + connection, + sync_base, + sync_filter, + attributes, + cookie, + object_security, + ancestors_first, + public_data_only, + incremental_values, + max_length, + hex_guid + ): + self.connection = connection + if self.connection.check_names and sync_base: + self. base = safe_dn(sync_base) + else: + self.base = sync_base + self.filter = sync_filter + self.attributes = attributes + self.cookie = cookie + self.object_security = object_security + self.ancestors_first = ancestors_first + self.public_data_only = public_data_only + self.incremental_values = incremental_values + self.max_length = max_length + self.hex_guid = hex_guid + self.more_results = True + + def loop(self): + result = self.connection.search(search_base=self.base, + search_filter=self.filter, + search_scope=SUBTREE, + attributes=self.attributes, + dereference_aliases=DEREF_NEVER, + controls=[dir_sync_control(criticality=True, + object_security=self.object_security, + ancestors_first=self.ancestors_first, + public_data_only=self.public_data_only, + incremental_values=self.incremental_values, + max_length=self.max_length, cookie=self.cookie), + extended_dn_control(criticality=False, hex_format=self.hex_guid), + show_deleted_control(criticality=False)] + ) + if not self.connection.strategy.sync: + response, result = self.connection.get_response(result) + else: + if self.connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = self.connection.response + result = self.connection.result + + if result['description'] == 'success' and 'controls' in result and '1.2.840.113556.1.4.841' in result['controls']: + self.more_results = result['controls']['1.2.840.113556.1.4.841']['value']['more_results'] + self.cookie = result['controls']['1.2.840.113556.1.4.841']['value']['cookie'] + return response + elif 'controls' in result: + raise LDAPExtensionError('Missing DirSync control in response from server') + else: + raise LDAPExtensionError('error %r in DirSync' % result) + diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/modifyPassword.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/modifyPassword.py new file mode 100644 index 00000000..ed8d58a7 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/modifyPassword.py @@ -0,0 +1,75 @@ +""" +""" + +# Created on 2015.11.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 . + + +from ... import MODIFY_REPLACE, MODIFY_DELETE, MODIFY_ADD +from ...utils.log import log, log_enabled, PROTOCOL +from ...core.results import RESULT_SUCCESS +from ...utils.dn import safe_dn +from ...utils.conv import to_unicode + + +def ad_modify_password(connection, user_dn, new_password, old_password, controls=None): + # old password must be None to reset password with sufficient privileges + if connection.check_names: + user_dn = safe_dn(user_dn) + if str is bytes: # python2, converts to unicode + new_password = to_unicode(new_password) + if old_password: + old_password = to_unicode(old_password) + + encoded_new_password = ('"%s"' % new_password).encode('utf-16-le') + + if old_password: # normal users must specify old and new password + encoded_old_password = ('"%s"' % old_password).encode('utf-16-le') + result = connection.modify(user_dn, + {'unicodePwd': [(MODIFY_DELETE, [encoded_old_password]), + (MODIFY_ADD, [encoded_new_password])]}, + controls) + else: # admin users can reset password without sending the old one + result = connection.modify(user_dn, + {'unicodePwd': [(MODIFY_REPLACE, [encoded_new_password])]}, + controls) + + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + + # change successful, returns True + if result['result'] == RESULT_SUCCESS: + return True + + # change was not successful, raises exception if raise_exception = True in connection or returns the operation result, error code is in result['result'] + if connection.raise_exceptions: + from ...core.exceptions import LDAPOperationResult + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + return False diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/persistentSearch.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/persistentSearch.py new file mode 100644 index 00000000..455bedca --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/persistentSearch.py @@ -0,0 +1,117 @@ +""" +""" + +# Created on 2016.07.08 +# +# 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 . + +try: + from queue import Empty +except ImportError: # Python 2 + # noinspection PyUnresolvedReferences + from Queue import Empty + +from ...core.exceptions import LDAPExtensionError +from ...utils.dn import safe_dn +from ...protocol.microsoft import persistent_search_control + + +class ADPersistentSearch(object): + def __init__(self, + connection, + search_base, + search_scope, + attributes, + streaming, + callback + ): + if connection.strategy.sync: + raise LDAPExtensionError('Persistent Search needs an asynchronous streaming connection') + + if connection.check_names and search_base: + search_base = safe_dn(search_base) + + self.connection = connection + self.message_id = None + self.base = search_base + self.scope = search_scope + self.attributes = attributes + self.controls = [persistent_search_control()] + + # this is the only filter permitted by AD persistent search + self.filter = '(objectClass=*)' + + self.connection.strategy.streaming = streaming + if callback and callable(callback): + self.connection.strategy.callback = callback + elif callback: + raise LDAPExtensionError('callback is not callable') + + self.start() + + def start(self): + if self.message_id: # persistent search already started + return + + if not self.connection.bound: + self.connection.bind() + + with self.connection.strategy.async_lock: + self.message_id = self.connection.search(search_base=self.base, + search_filter=self.filter, + search_scope=self.scope, + attributes=self.attributes, + controls=self.controls) + self.connection.strategy.persistent_search_message_id = self.message_id + + def stop(self, unbind=True): + self.connection.abandon(self.message_id) + if unbind: + self.connection.unbind() + if self.message_id in self.connection.strategy._responses: + del self.connection.strategy._responses[self.message_id] + if hasattr(self.connection.strategy, '_requests') and self.message_id in self.connection.strategy._requests: # asynchronous strategy has a dict of request that could be returned by get_response() + del self.connection.strategy._requests[self.message_id] + self.connection.strategy.persistent_search_message_id = None + self.message_id = None + + def next(self, block=False, timeout=None): + if not self.connection.strategy.streaming and not self.connection.strategy.callback: + try: + return self.connection.strategy.events.get(block, timeout) + except Empty: + return None + + raise LDAPExtensionError('Persistent search is not accumulating events in queue') + + def funnel(self, block=False, timeout=None): + done = False + while not done: + try: + entry = self.connection.strategy.events.get(block, timeout) + except Empty: + yield None + if entry['type'] == 'searchResEntry': + yield entry + else: + done = True + + yield entry diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/removeMembersFromGroups.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/removeMembersFromGroups.py new file mode 100644 index 00000000..86b799a8 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/removeMembersFromGroups.py @@ -0,0 +1,99 @@ +""" +""" + +# Created on 2016.12.26 +# +# 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 . + +from ...core.exceptions import LDAPInvalidDnError, LDAPOperationsErrorResult +from ... import SEQUENCE_TYPES, MODIFY_DELETE, BASE, DEREF_NEVER +from ...utils.dn import safe_dn + + +def ad_remove_members_from_groups(connection, + members_dn, + groups_dn, + fix, + raise_error=False): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to remove from groups + :param groups_dn: the list of groups where members are to be removed + :param fix: checks for group existence and existing members + :param raise_error: If the operation fails it raises an error instead of returning False + :return: a boolean where True means that the operation was successful and False means an error has happened + Removes users-groups relations following the Activwe Directory rules: users are removed from groups' member attribute + + """ + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + if connection.check_names: # builds new lists with sanitized dn + members_dn = [safe_dn(member_dn) for member_dn in members_dn] + groups_dn = [safe_dn(group_dn) for group_dn in groups_dn] + + error = False + + for group in groups_dn: + if fix: # checks for existance of group and for already assigned members + result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = connection.response + result = connection.result + + if not result['description'] == 'success': + raise LDAPInvalidDnError(group + ' not found') + + existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else [] + else: + existing_members = members_dn + + existing_members = [element.lower() for element in existing_members] + changes = dict() + member_to_remove = [element for element in members_dn if element.lower() in existing_members] + if member_to_remove: + changes['member'] = (MODIFY_DELETE, member_to_remove) + if changes: + result = connection.modify(group, changes) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + result_error_params = ['result', 'description', 'dn', 'message'] + if raise_error: + raise LDAPOperationsErrorResult([(k, v) for k, v in result.items() if k in result_error_params]) + break + + return not error diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/unlockAccount.py b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/unlockAccount.py new file mode 100644 index 00000000..e59216d6 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/microsoft/unlockAccount.py @@ -0,0 +1,57 @@ +""" +""" + +# Created on 2016.11.01 +# +# 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 . + + +from ... import MODIFY_REPLACE +from ...utils.log import log, log_enabled, PROTOCOL +from ...core.results import RESULT_SUCCESS +from ...utils.dn import safe_dn + + +def ad_unlock_account(connection, user_dn, controls=None): + if connection.check_names: + user_dn = safe_dn(user_dn) + result = connection.modify(user_dn, {'lockoutTime': [(MODIFY_REPLACE, ['0'])]}, controls) + + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + + # change successful, returns True + if result['result'] == RESULT_SUCCESS: + return True + + # change was not successful, raises exception if raise_exception = True in connection or returns the operation result, error code is in result['result'] + if connection.raise_exceptions: + from ...core.exceptions import LDAPOperationResult + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + return result diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/addMembersToGroups.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/addMembersToGroups.py new file mode 100644 index 00000000..7c89cdc6 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/addMembersToGroups.py @@ -0,0 +1,167 @@ +""" +""" + +# Created on 2016.04.16 +# +# 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 . +from ...core.exceptions import LDAPInvalidDnError +from ... import SEQUENCE_TYPES, MODIFY_ADD, BASE, DEREF_NEVER +from ...utils.dn import safe_dn + + +def edir_add_members_to_groups(connection, + members_dn, + groups_dn, + fix, + transaction): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to add to groups + :param groups_dn: the list of groups where members are to be added + :param fix: checks for inconsistences in the users-groups relation and fixes them + :param transaction: activates an LDAP transaction + :return: a boolean where True means that the operation was successful and False means an error has happened + Establishes users-groups relations following the eDirectory rules: groups are added to securityEquals and groupMembership + attributes in the member object while members are added to member and equivalentToMe attributes in the group object. + Raises LDAPInvalidDnError if members or groups are not found in the DIT. + """ + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + transaction_control = None + error = False + + if connection.check_names: # builds new lists with sanitized dn + safe_members_dn = [] + safe_groups_dn = [] + for member_dn in members_dn: + safe_members_dn.append(safe_dn(member_dn)) + for group_dn in groups_dn: + safe_groups_dn.append(safe_dn(group_dn)) + + members_dn = safe_members_dn + groups_dn = safe_groups_dn + + if transaction: + transaction_control = connection.extend.novell.start_transaction() + + if not error: + for member in members_dn: + if fix: # checks for existance of member and for already assigned groups + result = connection.search(member, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['securityEquals', 'groupMembership']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + result = connection.result + response = connection.response + + if not result['description'] == 'success': + raise LDAPInvalidDnError(member + ' not found') + + existing_security_equals = response[0]['attributes']['securityEquals'] if 'securityEquals' in response[0]['attributes'] else [] + existing_group_membership = response[0]['attributes']['groupMembership'] if 'groupMembership' in response[0]['attributes'] else [] + existing_security_equals = [element.lower() for element in existing_security_equals] + existing_group_membership = [element.lower() for element in existing_group_membership] + else: + existing_security_equals = [] + existing_group_membership = [] + changes = dict() + security_equals_to_add = [element for element in groups_dn if element.lower() not in existing_security_equals] + group_membership_to_add = [element for element in groups_dn if element.lower() not in existing_group_membership] + if security_equals_to_add: + changes['securityEquals'] = (MODIFY_ADD, security_equals_to_add) + if group_membership_to_add: + changes['groupMembership'] = (MODIFY_ADD, group_membership_to_add) + if changes: + result = connection.modify(member, changes, controls=[transaction_control] if transaction else None) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + break + + if not error: + for group in groups_dn: + if fix: # checks for existance of group and for already assigned members + result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member', 'equivalentToMe']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + result = connection.result + response = connection.response + + if not result['description'] == 'success': + raise LDAPInvalidDnError(group + ' not found') + + existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else [] + existing_equivalent_to_me = response[0]['attributes']['equivalentToMe'] if 'equivalentToMe' in response[0]['attributes'] else [] + existing_members = [element.lower() for element in existing_members] + existing_equivalent_to_me = [element.lower() for element in existing_equivalent_to_me] + else: + existing_members = [] + existing_equivalent_to_me = [] + + changes = dict() + member_to_add = [element for element in members_dn if element.lower() not in existing_members] + equivalent_to_me_to_add = [element for element in members_dn if element.lower() not in existing_equivalent_to_me] + if member_to_add: + changes['member'] = (MODIFY_ADD, member_to_add) + if equivalent_to_me_to_add: + changes['equivalentToMe'] = (MODIFY_ADD, equivalent_to_me_to_add) + if changes: + result = connection.modify(group, changes, controls=[transaction_control] if transaction else None) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + break + + if transaction: + if error: # aborts transaction in case of error in the modify operations + result = connection.extend.novell.end_transaction(commit=False, controls=[transaction_control]) + else: + result = connection.extend.novell.end_transaction(commit=True, controls=[transaction_control]) + + if result['description'] != 'success': + error = True + + return not error # returns True if no error is raised in the LDAP operations diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/checkGroupsMemberships.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/checkGroupsMemberships.py new file mode 100644 index 00000000..98464ac3 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/checkGroupsMemberships.py @@ -0,0 +1,180 @@ +""" +""" + +# Created on 2016.05.14 +# +# 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 . + + +from .addMembersToGroups import edir_add_members_to_groups +from ...core.exceptions import LDAPInvalidDnError +from ... import SEQUENCE_TYPES, BASE, DEREF_NEVER +from ...utils.dn import safe_dn + + +def _check_members_have_memberships(connection, + members_dn, + groups_dn): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to add to groups + :param groups_dn: the list of groups where members are to be added + :return: two booleans. The first when True means that all members have membership in all groups, The second when True means that + there are inconsistences in the securityEquals attribute + Checks user's group membership. + Raises LDAPInvalidDNError if member is not found in the DIT. + """ + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + partial = False # True when a member has groupMembership but doesn't have securityEquals + for member in members_dn: + result = connection.search(member, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['groupMembership', 'securityEquals']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + result = connection.result + response = connection.response + + if not result['description'] == 'success': # member not found in DIT + raise LDAPInvalidDnError(member + ' not found') + + existing_security_equals = response[0]['attributes']['securityEquals'] if 'securityEquals' in response[0]['attributes'] else [] + existing_group_membership = response[0]['attributes']['groupMembership'] if 'groupMembership' in response[0]['attributes'] else [] + existing_security_equals = [element.lower() for element in existing_security_equals] + existing_group_membership = [element.lower() for element in existing_group_membership] + + for group in groups_dn: + if group.lower() not in existing_group_membership: + return False, False + if group.lower() not in existing_security_equals: + partial = True + + return True, partial + + +def _check_groups_contain_members(connection, + groups_dn, + members_dn): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to add to groups + :param groups_dn: the list of groups where members are to be added + :return: two booleans. The first when True means that all members have membership in all groups, The second when True means that + there are inconsistences in the EquivalentToMe attribute + Checks if groups have members in their 'member' attribute. + Raises LDAPInvalidDNError if member is not found in the DIT. + """ + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + partial = False # True when a group has member but doesn't have equivalentToMe + for group in groups_dn: + result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member', 'equivalentToMe']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + result = connection.result + response = connection.response + + if not result['description'] == 'success': + raise LDAPInvalidDnError(group + ' not found') + + existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else [] + existing_equivalent_to_me = response[0]['attributes']['equivalentToMe'] if 'equivalentToMe' in response[0]['attributes'] else [] + existing_members = [element.lower() for element in existing_members] + existing_equivalent_to_me = [element.lower() for element in existing_equivalent_to_me] + for member in members_dn: + if member.lower() not in existing_members: + return False, False + if member.lower() not in existing_equivalent_to_me: + partial = True + + return True, partial + + +def edir_check_groups_memberships(connection, + members_dn, + groups_dn, + fix, + transaction): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to check + :param groups_dn: the list of groups to check + :param fix: checks for inconsistences in the users-groups relation and fixes them + :param transaction: activates an LDAP transaction when fixing + :return: a boolean where True means that the operation was successful and False means an error has happened + Checks and fixes users-groups relations following the eDirectory rules: groups are checked against 'groupMembership' + attribute in the member object while members are checked against 'member' attribute in the group object. + Raises LDAPInvalidDnError if members or groups are not found in the DIT. + """ + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if connection.check_names: # builds new lists with sanitized dn + safe_members_dn = [] + safe_groups_dn = [] + for member_dn in members_dn: + safe_members_dn.append(safe_dn(member_dn)) + for group_dn in groups_dn: + safe_groups_dn.append(safe_dn(group_dn)) + + members_dn = safe_members_dn + groups_dn = safe_groups_dn + + try: + members_have_memberships, partial_member_security = _check_members_have_memberships(connection, members_dn, groups_dn) + groups_contain_members, partial_group_security = _check_groups_contain_members(connection, groups_dn, members_dn) + except LDAPInvalidDnError: + return False + + if not members_have_memberships and not groups_contain_members: + return False + + if fix: # fix any inconsistences + if (members_have_memberships and not groups_contain_members) \ + or (groups_contain_members and not members_have_memberships) \ + or partial_group_security \ + or partial_member_security: + + for member in members_dn: + for group in groups_dn: + edir_add_members_to_groups(connection, member, group, True, transaction) + + return True diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/endTransaction.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/endTransaction.py new file mode 100644 index 00000000..7624678a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/endTransaction.py @@ -0,0 +1,58 @@ +""" +""" + +# Created on 2016.04.14 +# +# 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 . + +from ...extend.operation import ExtendedOperation +from ...protocol.novell import EndGroupTypeRequestValue, EndGroupTypeResponseValue, Sequence +from ...utils.asn1 import decoder + + +class EndTransaction(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.103.2' + self.response_name = '2.16.840.1.113719.1.27.103.2' + self.request_value = EndGroupTypeRequestValue() + self.asn1_spec = EndGroupTypeResponseValue() + + def __init__(self, connection, commit=True, controls=None): + if controls and len(controls) == 1: + group_cookie = decoder.decode(controls[0][2], asn1Spec=Sequence())[0][0] # get the cookie from the built groupingControl + else: + group_cookie = None + controls = None + + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + if group_cookie: + self.request_value['endGroupCookie'] = group_cookie # transactionGroupingType + if not commit: + self.request_value['endGroupValue'] = '' # an empty endGroupValue means abort transaction + + def populate_result(self): + try: + self.result['value'] = self.decoded_response['endGroupValue'] + except TypeError: + self.result['value'] = None + + def set_response(self): + self.response_value = self.result diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/getBindDn.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/getBindDn.py new file mode 100644 index 00000000..eb739adb --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/getBindDn.py @@ -0,0 +1,41 @@ +""" +""" + +# Created on 2014.04.30 +# +# 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 . + +from ...protocol.novell import Identity +from ...extend.operation import ExtendedOperation + + +class GetBindDn(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.100.31' + self.response_name = '2.16.840.1.113719.1.27.100.32' + self.response_attribute = 'identity' + self.asn1_spec = Identity() + + def populate_result(self): + try: + self.result['identity'] = str(self.decoded_response) if self.decoded_response else None + except TypeError: + self.result['identity'] = None diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/listReplicas.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/listReplicas.py new file mode 100644 index 00000000..b5533ff7 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/listReplicas.py @@ -0,0 +1,50 @@ +""" +""" + +# Created on 2014.07.03 +# +# 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 . + +from ...extend.operation import ExtendedOperation +from ...protocol.novell import ReplicaList +from ...protocol.rfc4511 import LDAPDN +from ...utils.dn import safe_dn + + +class ListReplicas(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.100.19' + self.response_name = '2.16.840.1.113719.1.27.100.20' + self.request_value = LDAPDN() + self.asn1_spec = ReplicaList() + self.response_attribute = 'replicas' + + def __init__(self, connection, server_dn, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + if connection.check_names: + server_dn = safe_dn(server_dn) + self.request_value = LDAPDN(server_dn) + + def populate_result(self): + try: + self.result['replicas'] = [str(replica) for replica in self.decoded_response] if self.decoded_response else None + except TypeError: + self.result['replicas'] = None diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasGetUniversalPassword.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasGetUniversalPassword.py new file mode 100644 index 00000000..427c554f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasGetUniversalPassword.py @@ -0,0 +1,56 @@ +""" +""" + +# Created on 2014.07.03 +# +# 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 . + +from ...extend.operation import ExtendedOperation +from ...protocol.novell import NmasGetUniversalPasswordRequestValue, NmasGetUniversalPasswordResponseValue, NMAS_LDAP_EXT_VERSION +from ...utils.dn import safe_dn + + +class NmasGetUniversalPassword(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.39.42.100.13' + self.response_name = '2.16.840.1.113719.1.39.42.100.14' + self.request_value = NmasGetUniversalPasswordRequestValue() + self.asn1_spec = NmasGetUniversalPasswordResponseValue() + self.response_attribute = 'password' + + def __init__(self, connection, user, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + + if connection.check_names: + user = safe_dn(user) + + self.request_value['nmasver'] = NMAS_LDAP_EXT_VERSION + self.request_value['reqdn'] = user + + def populate_result(self): + if self.decoded_response: + self.result['nmasver'] = int(self.decoded_response['nmasver']) + self.result['error'] = int(self.decoded_response['err']) + try: + + self.result['password'] = str(self.decoded_response['passwd']) if self.decoded_response['passwd'].hasValue() else None + except TypeError: + self.result['password'] = None diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasSetUniversalPassword.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasSetUniversalPassword.py new file mode 100644 index 00000000..65ae45af --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/nmasSetUniversalPassword.py @@ -0,0 +1,52 @@ +""" +""" + +# Created on 2014.07.03 +# +# 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 . + +from ...extend.operation import ExtendedOperation +from ...protocol.novell import NmasSetUniversalPasswordRequestValue, NmasSetUniversalPasswordResponseValue, NMAS_LDAP_EXT_VERSION +from ...utils.dn import safe_dn + + +class NmasSetUniversalPassword(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.39.42.100.11' + self.response_name = '2.16.840.1.113719.1.39.42.100.12' + self.request_value = NmasSetUniversalPasswordRequestValue() + self.asn1_spec = NmasSetUniversalPasswordResponseValue() + self.response_attribute = 'password' + + def __init__(self, connection, user, new_password, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + if connection.check_names and user: + user = safe_dn(user) + + self.request_value['nmasver'] = NMAS_LDAP_EXT_VERSION + if user: + self.request_value['reqdn'] = user + if new_password: + self.request_value['new_passwd'] = new_password + + def populate_result(self): + self.result['nmasver'] = int(self.decoded_response['nmasver']) + self.result['error'] = int(self.decoded_response['err']) diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/partition_entry_count.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/partition_entry_count.py new file mode 100644 index 00000000..d031245c --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/partition_entry_count.py @@ -0,0 +1,57 @@ +""" +""" + +# Created on 2014.08.05 +# +# 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 . + +from pyasn1.type.univ import Integer + +from ...core.exceptions import LDAPExtensionError +from ..operation import ExtendedOperation +from ...protocol.rfc4511 import LDAPDN +from ...utils.asn1 import decoder +from ...utils.dn import safe_dn + + +class PartitionEntryCount(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.100.13' + self.response_name = '2.16.840.1.113719.1.27.100.14' + self.request_value = LDAPDN() + self.response_attribute = 'entry_count' + + def __init__(self, connection, partition_dn, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + if connection.check_names: + partition_dn = safe_dn(partition_dn) + self.request_value = LDAPDN(partition_dn) + + def populate_result(self): + substrate = self.decoded_response + try: + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['entry_count'] = int(decoded) + except Exception: + raise LDAPExtensionError('unable to decode substrate') + + if substrate: + raise LDAPExtensionError('unknown substrate remaining') diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/removeMembersFromGroups.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/removeMembersFromGroups.py new file mode 100644 index 00000000..ff063a63 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/removeMembersFromGroups.py @@ -0,0 +1,170 @@ +""" +""" + +# Created on 2016.04.17 +# +# 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 . +from ...core.exceptions import LDAPInvalidDnError +from ... import SEQUENCE_TYPES, MODIFY_DELETE, BASE, DEREF_NEVER +from ...utils.dn import safe_dn + + +def edir_remove_members_from_groups(connection, + members_dn, + groups_dn, + fix, + transaction): + """ + :param connection: a bound Connection object + :param members_dn: the list of members to remove from groups + :param groups_dn: the list of groups where members are to be removed + :param fix: checks for inconsistences in the users-groups relation and fixes them + :param transaction: activates an LDAP transaction + :return: a boolean where True means that the operation was successful and False means an error has happened + Removes users-groups relations following the eDirectory rules: groups are removed from securityEquals and groupMembership + attributes in the member object while members are removed from member and equivalentToMe attributes in the group object. + Raises LDAPInvalidDnError if members or groups are not found in the DIT. + + """ + if not isinstance(members_dn, SEQUENCE_TYPES): + members_dn = [members_dn] + + if not isinstance(groups_dn, SEQUENCE_TYPES): + groups_dn = [groups_dn] + + if connection.check_names: # builds new lists with sanitized dn + safe_members_dn = [] + safe_groups_dn = [] + for member_dn in members_dn: + safe_members_dn.append(safe_dn(member_dn)) + for group_dn in groups_dn: + safe_groups_dn.append(safe_dn(group_dn)) + + members_dn = safe_members_dn + groups_dn = safe_groups_dn + + transaction_control = None + error = False + + if transaction: + transaction_control = connection.extend.novell.start_transaction() + + if not error: + for member in members_dn: + if fix: # checks for existance of member and for already assigned groups + result = connection.search(member, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['securityEquals', 'groupMembership']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = connection.response + result = connection.result + + if not result['description'] == 'success': + raise LDAPInvalidDnError(member + ' not found') + + existing_security_equals = response[0]['attributes']['securityEquals'] if 'securityEquals' in response[0]['attributes'] else [] + existing_group_membership = response[0]['attributes']['groupMembership'] if 'groupMembership' in response[0]['attributes'] else [] + else: + existing_security_equals = groups_dn + existing_group_membership = groups_dn + existing_security_equals = [element.lower() for element in existing_security_equals] + existing_group_membership = [element.lower() for element in existing_group_membership] + + changes = dict() + security_equals_to_remove = [element for element in groups_dn if element.lower() in existing_security_equals] + group_membership_to_remove = [element for element in groups_dn if element.lower() in existing_group_membership] + if security_equals_to_remove: + changes['securityEquals'] = (MODIFY_DELETE, security_equals_to_remove) + if group_membership_to_remove: + changes['groupMembership'] = (MODIFY_DELETE, group_membership_to_remove) + if changes: + result = connection.modify(member, changes, controls=[transaction_control] if transaction else None) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + break + + if not error: + for group in groups_dn: + if fix: # checks for existance of group and for already assigned members + result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member', 'equivalentToMe']) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = connection.response + result = connection.result + + if not result['description'] == 'success': + raise LDAPInvalidDnError(group + ' not found') + + existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else [] + existing_equivalent_to_me = response[0]['attributes']['equivalentToMe'] if 'equivalentToMe' in response[0]['attributes'] else [] + else: + existing_members = members_dn + existing_equivalent_to_me = members_dn + + existing_members = [element.lower() for element in existing_members] + existing_equivalent_to_me = [element.lower() for element in existing_equivalent_to_me] + + changes = dict() + member_to_remove = [element for element in members_dn if element.lower() in existing_members] + equivalent_to_me_to_remove = [element for element in members_dn if element.lower() in existing_equivalent_to_me] + if member_to_remove: + changes['member'] = (MODIFY_DELETE, member_to_remove) + if equivalent_to_me_to_remove: + changes['equivalentToMe'] = (MODIFY_DELETE, equivalent_to_me_to_remove) + if changes: + result = connection.modify(group, changes, controls=[transaction_control] if transaction else None) + if not connection.strategy.sync: + _, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, _, _ = result + else: + result = connection.result + if result['description'] != 'success': + error = True + break + + if transaction: + if error: # aborts transaction in case of error in the modify operations + result = connection.extend.novell.end_transaction(commit=False, controls=[transaction_control]) + else: + result = connection.extend.novell.end_transaction(commit=True, controls=[transaction_control]) + + if result['description'] != 'success': + error = True + + return not error # return True if no error is raised in the LDAP operations diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/replicaInfo.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/replicaInfo.py new file mode 100644 index 00000000..54a33172 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/replicaInfo.py @@ -0,0 +1,79 @@ +""" +""" + +# Created on 2014.08.07 +# +# 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 . + +from datetime import datetime + +from pyasn1.type.univ import Integer + +from ...core.exceptions import LDAPExtensionError +from ...protocol.novell import LDAPDN, ReplicaInfoRequestValue +from ..operation import ExtendedOperation +from ...utils.asn1 import decoder +from ...utils.dn import safe_dn + + +class ReplicaInfo(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.100.17' + self.response_name = '2.16.840.1.113719.1.27.100.18' + # self.asn1_spec = ReplicaInfoResponseValue() + self.request_value = ReplicaInfoRequestValue() + self.response_attribute = 'partition_dn' + + def __init__(self, connection, server_dn, partition_dn, controls=None): + if connection.check_names: + if server_dn: + server_dn = safe_dn(server_dn) + if partition_dn: + partition_dn = safe_dn(partition_dn) + + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + self.request_value['server_dn'] = server_dn + self.request_value['partition_dn'] = partition_dn + + def populate_result(self): + substrate = self.decoded_response + try: + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['partition_id'] = int(decoded) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['replica_state'] = int(decoded) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['modification_time'] = datetime.utcfromtimestamp(int(decoded)) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['purge_time'] = datetime.utcfromtimestamp(int(decoded)) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['local_partition_id'] = int(decoded) + decoded, substrate = decoder.decode(substrate, asn1Spec=LDAPDN()) + self.result['partition_dn'] = str(decoded) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['replica_type'] = int(decoded) + decoded, substrate = decoder.decode(substrate, asn1Spec=Integer()) + self.result['flags'] = int(decoded) + except Exception: + raise LDAPExtensionError('unable to decode substrate') + + if substrate: + raise LDAPExtensionError('unknown substrate remaining') diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/novell/startTransaction.py b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/startTransaction.py new file mode 100644 index 00000000..6e5a4a4f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/novell/startTransaction.py @@ -0,0 +1,56 @@ +""" +""" + +# Created on 2016.04.14 +# +# 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 . + +from ...extend.operation import ExtendedOperation +from ...protocol.novell import CreateGroupTypeRequestValue, CreateGroupTypeResponseValue, GroupingControlValue +from ...protocol.controls import build_control + + +class StartTransaction(ExtendedOperation): + def config(self): + self.request_name = '2.16.840.1.113719.1.27.103.1' + self.response_name = '2.16.840.1.113719.1.27.103.1' + self.request_value = CreateGroupTypeRequestValue() + self.asn1_spec = CreateGroupTypeResponseValue() + + def __init__(self, connection, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + self.request_value['createGroupType'] = '2.16.840.1.113719.1.27.103.7' # transactionGroupingType + + def populate_result(self): + self.result['cookie'] = int(self.decoded_response['createGroupCookie']) + try: + self.result['value'] = self.decoded_response['createGroupValue'] + except TypeError: + self.result['value'] = None + + def set_response(self): + try: + grouping_cookie_value = GroupingControlValue() + grouping_cookie_value['groupingCookie'] = self.result['cookie'] + self.response_value = build_control('2.16.840.1.113719.1.27.103.7', True, grouping_cookie_value, encode_control_value=True) # groupingControl + except TypeError: + self.response_value = None + diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/operation.py b/plugins/ldap-user-sync/vendor/ldap3/extend/operation.py new file mode 100644 index 00000000..6e5f2d79 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/operation.py @@ -0,0 +1,98 @@ +""" +""" + +# Created on 2014.07.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 . + +from ..core.results import RESULT_SUCCESS +from ..core.exceptions import LDAPExtensionError +from ..utils.asn1 import decoder + + +class ExtendedOperation(object): + def __init__(self, connection, controls=None): + self.connection = connection + self.decoded_response = None + self.result = None + self.asn1_spec = None # if None the response_value is returned without encoding + self.request_name = None + self.response_name = None + self.request_value = None + self.response_value = None + self.response_attribute = None + self.controls = controls + self.config() + + def send(self): + if self.connection.check_names and self.connection.server.info is not None and self.connection.server.info.supported_extensions is not None: # checks if extension is supported + for request_name in self.connection.server.info.supported_extensions: + if request_name[0] == self.request_name: + break + else: + raise LDAPExtensionError('extension not in DSA list of supported extensions') + + resp = self.connection.extended(self.request_name, self.request_value, self.controls) + if not self.connection.strategy.sync: + _, result = self.connection.get_response(resp) + else: + if self.connection.strategy.thread_safe: + _, result, _, _ = resp + else: + result = self.connection.result + self.result = result + self.decode_response(result) + self.populate_result() + self.set_response() + return self.response_value + + def populate_result(self): + pass + + def decode_response(self, response=None): + if not response: + response = self.result + if not response: + return None + if response['result'] not in [RESULT_SUCCESS]: + if self.connection.raise_exceptions: + raise LDAPExtensionError('extended operation error: ' + response['description'] + ' - ' + response['message']) + else: + return None + if not self.response_name or response['responseName'] == self.response_name: + if response['responseValue']: + if self.asn1_spec is not None: + decoded, unprocessed = decoder.decode(response['responseValue'], asn1Spec=self.asn1_spec) + if unprocessed: + raise LDAPExtensionError('error decoding extended response value') + self.decoded_response = decoded + else: + self.decoded_response = response['responseValue'] + else: + raise LDAPExtensionError('invalid response name received') + + def set_response(self): + self.response_value = self.result[self.response_attribute] if self.result and self.response_attribute in self.result else None + if not self.connection.strategy.thread_safe: + self.connection.response = self.response_value + + def config(self): + pass diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PagedSearch.py b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PagedSearch.py new file mode 100644 index 00000000..3e96fb48 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PagedSearch.py @@ -0,0 +1,146 @@ +""" +""" + +# Created on 2014.07.08 +# +# 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 . + +from ... import SUBTREE, DEREF_ALWAYS +from ...utils.dn import safe_dn +from ...core.results import DO_NOT_RAISE_EXCEPTIONS, RESULT_SIZE_LIMIT_EXCEEDED +from ...core.exceptions import LDAPOperationResult +from ...utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, NETWORK, EXTENDED + + +def paged_search_generator(connection, + search_base, + search_filter, + search_scope=SUBTREE, + dereference_aliases=DEREF_ALWAYS, + attributes=None, + size_limit=0, + time_limit=0, + types_only=False, + get_operational_attributes=False, + controls=None, + paged_size=100, + paged_criticality=False): + if connection.check_names and search_base: + search_base = safe_dn(search_base) + + responses = [] + original_connection = None + original_auto_referrals = connection.auto_referrals + connection.auto_referrals = False # disable auto referrals because it cannot handle paged searches + cookie = True # performs search operation at least one time + cachekey = None # for referrals cache + while cookie: + result = connection.search(search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + get_operational_attributes, + controls, + paged_size, + paged_criticality, + None if cookie is True else cookie) + + if not connection.strategy.sync: + response, result = connection.get_response(result) + else: + if connection.strategy.thread_safe: + _, result, response, _ = result + else: + response = connection.response + result = connection.result + + if result['referrals'] and original_auto_referrals: # if rererrals are returned start over the loop with a new connection to the referral + if not original_connection: + original_connection = connection + _, connection, cachekey = connection.strategy.create_referral_connection(result['referrals']) # change connection to a valid referrals + continue + + responses.extend(response) + try: + cookie = result['controls']['1.2.840.113556.1.4.319']['value']['cookie'] + except KeyError: + cookie = None + + if connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'paged search operation result <%s> for <%s>', result, connection) + if result['result'] == RESULT_SIZE_LIMIT_EXCEEDED: + while responses: + yield responses.pop() + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + while responses: + yield responses.pop() + + if original_connection: + connection = original_connection + if connection.use_referral_cache and cachekey: + connection.strategy.referral_cache[cachekey] = connection + else: + connection.unbind() + + connection.auto_referrals = original_auto_referrals + connection.response = None + + +def paged_search_accumulator(connection, + search_base, + search_filter, + search_scope=SUBTREE, + dereference_aliases=DEREF_ALWAYS, + attributes=None, + size_limit=0, + time_limit=0, + types_only=False, + get_operational_attributes=False, + controls=None, + paged_size=100, + paged_criticality=False): + if connection.check_names and search_base: + search_base = safe_dn(search_base) + + responses = [] + for response in paged_search_generator(connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + get_operational_attributes, + controls, + paged_size, + paged_criticality): + responses.append(response) + + connection.response = responses + return responses diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PersistentSearch.py b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PersistentSearch.py new file mode 100644 index 00000000..1ca33a90 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/PersistentSearch.py @@ -0,0 +1,137 @@ +""" +""" + +# Created on 2016.07.08 +# +# 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 . + +try: + from queue import Empty +except ImportError: # Python 2 + # noinspection PyUnresolvedReferences + from Queue import Empty + +from ...core.exceptions import LDAPExtensionError +from ...protocol.persistentSearch import persistent_search_control +from ... import SEQUENCE_TYPES +from ...utils.dn import safe_dn + + +class PersistentSearch(object): + def __init__(self, + connection, + search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + controls, + changes_only, + events_type, + notifications, + streaming, + callback + ): + if connection.strategy.sync: + raise LDAPExtensionError('Persistent Search needs an asynchronous streaming connection') + + if connection.check_names and search_base: + search_base = safe_dn(search_base) + + self.connection = connection + self.changes_only = changes_only + self.notifications = notifications + self.message_id = None + self.base = search_base + self.filter = search_filter + self.scope = search_scope + self.dereference_aliases = dereference_aliases + self.attributes = attributes + self.size_limit = size_limit + self.time_limit = time_limit + self.connection.strategy.streaming = streaming + if callback and callable(callback): + self.connection.strategy.callback = callback + elif callback: + raise LDAPExtensionError('callback is not callable') + + if not isinstance(controls, SEQUENCE_TYPES): + self.controls = [] + else: + self.controls = controls + + if events_type and changes_only and notifications: + self.controls.append(persistent_search_control(events_type, changes_only, notifications)) + self.start() + + def start(self): + if self.message_id: # persistent search already started + return + + if not self.connection.bound: + self.connection.bind() + + with self.connection.strategy.async_lock: + self.message_id = self.connection.search(search_base=self.base, + search_filter=self.filter, + search_scope=self.scope, + dereference_aliases=self.dereference_aliases, + attributes=self.attributes, + size_limit=self.size_limit, + time_limit=self.time_limit, + controls=self.controls) + self.connection.strategy.persistent_search_message_id = self.message_id + + def stop(self, unbind=True): + self.connection.abandon(self.message_id) + if unbind: + self.connection.unbind() + if self.message_id in self.connection.strategy._responses: + del self.connection.strategy._responses[self.message_id] + if hasattr(self.connection.strategy, '_requests') and self.message_id in self.connection.strategy._requests: # asynchronous strategy has a dict of request that could be returned by get_response() + del self.connection.strategy._requests[self.message_id] + self.connection.strategy.persistent_search_message_id = None + self.message_id = None + + def next(self, block=False, timeout=None): + if not self.connection.strategy.streaming and not self.connection.strategy.callback: + try: + return self.connection.strategy.events.get(block, timeout) + except Empty: + return None + + raise LDAPExtensionError('Persistent search is not accumulating events in queue') + + def funnel(self, block=False, timeout=None): + done = False + while not done: + try: + entry = self.connection.strategy.events.get(block, timeout) + except Empty: + yield None + if entry['type'] == 'searchResEntry': + yield entry + else: + done = True + + yield entry diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/standard/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/standard/modifyPassword.py b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/modifyPassword.py new file mode 100644 index 00000000..786db7eb --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/modifyPassword.py @@ -0,0 +1,72 @@ +""" +""" + +# Created on 2014.04.30 +# +# 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 . + +from ... import HASHED_NONE +from ...extend.operation import ExtendedOperation +from ...protocol.rfc3062 import PasswdModifyRequestValue, PasswdModifyResponseValue +from ...utils.hashed import hashed +from ...protocol.sasl.sasl import validate_simple_password +from ...utils.dn import safe_dn +from ...core.results import RESULT_SUCCESS + +# implements RFC3062 + + +class ModifyPassword(ExtendedOperation): + def config(self): + self.request_name = '1.3.6.1.4.1.4203.1.11.1' + self.request_value = PasswdModifyRequestValue() + self.asn1_spec = PasswdModifyResponseValue() + self.response_attribute = 'new_password' + + def __init__(self, connection, user=None, old_password=None, new_password=None, hash_algorithm=None, salt=None, controls=None): + ExtendedOperation.__init__(self, connection, controls) # calls super __init__() + if user: + if connection.check_names: + user = safe_dn(user) + self.request_value['userIdentity'] = user + if old_password: + if not isinstance(old_password, bytes): # bytes are returned raw, as per RFC (4.2) + old_password = validate_simple_password(old_password, True) + self.request_value['oldPasswd'] = old_password + if new_password: + if not isinstance(new_password, bytes): # bytes are returned raw, as per RFC (4.2) + new_password = validate_simple_password(new_password, True) + if hash_algorithm is None or hash_algorithm == HASHED_NONE: + self.request_value['newPasswd'] = new_password + else: + self.request_value['newPasswd'] = hashed(hash_algorithm, new_password, salt) + + def populate_result(self): + try: + self.result[self.response_attribute] = str(self.decoded_response['genPasswd']) + except TypeError: # optional field can be absent, so returns True if operation is successful else False + if self.result['result'] == RESULT_SUCCESS: + self.result[self.response_attribute] = True + else: # change was not successful, raises exception if raise_exception = True in connection or returns the operation result, error code is in result['result'] + self.result[self.response_attribute] = False + if self.connection.raise_exceptions: + from ...core.exceptions import LDAPOperationResult + raise LDAPOperationResult(result=self.result['result'], description=self.result['description'], dn=self.result['dn'], message=self.result['message'], response_type=self.result['type']) diff --git a/plugins/ldap-user-sync/vendor/ldap3/extend/standard/whoAmI.py b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/whoAmI.py new file mode 100644 index 00000000..ee609ce0 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/extend/standard/whoAmI.py @@ -0,0 +1,40 @@ +""" +""" + +# Created on 2014.04.30 +# +# 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 . + +# implements RFC4532 +from ...extend.operation import ExtendedOperation +from ...utils.conv import to_unicode + + +class WhoAmI(ExtendedOperation): + def config(self): + self.request_name = '1.3.6.1.4.1.4203.1.11.3' + self.response_attribute = 'authzid' + + def populate_result(self): + try: + self.result['authzid'] = to_unicode(self.decoded_response) if self.decoded_response else None + except TypeError: + self.result['authzid'] = self.decoded_response if self.decoded_response else None diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/operation/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/abandon.py b/plugins/ldap-user-sync/vendor/ldap3/operation/abandon.py new file mode 100644 index 00000000..07ea8f77 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/abandon.py @@ -0,0 +1,36 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from ..protocol.rfc4511 import AbandonRequest, MessageID + + +def abandon_operation(msg_id): + # AbandonRequest ::= [APPLICATION 16] MessageID + request = AbandonRequest(MessageID(msg_id)) + return request + + +def abandon_request_to_dict(request): + return {'messageId': str(request)} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/add.py b/plugins/ldap-user-sync/vendor/ldap3/operation/add.py new file mode 100644 index 00000000..cf15e71a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/add.py @@ -0,0 +1,72 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from .. import SEQUENCE_TYPES +from ..protocol.rfc4511 import AddRequest, LDAPDN, AttributeList, Attribute, AttributeDescription, ResultCode, Vals +from ..protocol.convert import referrals_to_list, attributes_to_dict, validate_attribute_value, prepare_for_sending + + +def add_operation(dn, + attributes, + auto_encode, + schema=None, + validator=None, + check_names=False): + # AddRequest ::= [APPLICATION 8] SEQUENCE { + # entry LDAPDN, + # attributes AttributeList } + # + # attributes is a dictionary in the form 'attribute': ['val1', 'val2', 'valN'] + attribute_list = AttributeList() + for pos, attribute in enumerate(attributes): + attribute_list[pos] = Attribute() + attribute_list[pos]['type'] = AttributeDescription(attribute) + vals = Vals() # changed from ValsAtLeast1() for allowing empty member value in groups + if isinstance(attributes[attribute], SEQUENCE_TYPES): + for index, value in enumerate(attributes[attribute]): + vals.setComponentByPosition(index, prepare_for_sending(validate_attribute_value(schema, attribute, value, auto_encode, validator, check_names))) + else: + vals.setComponentByPosition(0, prepare_for_sending(validate_attribute_value(schema, attribute, attributes[attribute], auto_encode, validator, check_names))) + + attribute_list[pos]['vals'] = vals + + request = AddRequest() + request['entry'] = LDAPDN(dn) + request['attributes'] = attribute_list + + return request + + +def add_request_to_dict(request): + return {'entry': str(request['entry']), + 'attributes': attributes_to_dict(request['attributes'])} + + +def add_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'dn': str(response['matchedDN']), + 'message': str(response['diagnosticMessage']), + 'referrals': referrals_to_list(response['referral'])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/bind.py b/plugins/ldap-user-sync/vendor/ldap3/operation/bind.py new file mode 100644 index 00000000..4365c38f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/bind.py @@ -0,0 +1,160 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from .. import SIMPLE, ANONYMOUS, SASL, STRING_TYPES +from ..core.results import RESULT_CODES +from ..core.exceptions import LDAPUserNameIsMandatoryError, LDAPPasswordIsMandatoryError, LDAPUnknownAuthenticationMethodError, LDAPUserNameNotAllowedError +from ..protocol.sasl.sasl import validate_simple_password +from ..protocol.rfc4511 import Version, AuthenticationChoice, Simple, BindRequest, ResultCode, SaslCredentials, BindResponse, \ + LDAPDN, LDAPString, Referral, ServerSaslCreds, SicilyPackageDiscovery, SicilyNegotiate, SicilyResponse +from ..protocol.convert import authentication_choice_to_dict, referrals_to_list +from ..utils.conv import to_unicode, to_raw + +# noinspection PyUnresolvedReferences +def bind_operation(version, + authentication, + name='', + password=None, + sasl_mechanism=None, + sasl_credentials=None, + auto_encode=False): + # BindRequest ::= [APPLICATION 0] SEQUENCE { + # version INTEGER (1 .. 127), + # name LDAPDN, + # authentication AuthenticationChoice } + request = BindRequest() + request['version'] = Version(version) + if name is None: + name = '' + if isinstance(name, STRING_TYPES): + request['name'] = to_unicode(name) if auto_encode else name + if authentication == SIMPLE: + if not name: + raise LDAPUserNameIsMandatoryError('user name is mandatory in simple bind') + if password: + request['authentication'] = AuthenticationChoice().setComponentByName('simple', Simple(validate_simple_password(password))) + else: + raise LDAPPasswordIsMandatoryError('password is mandatory in simple bind') + elif authentication == SASL: + sasl_creds = SaslCredentials() + sasl_creds['mechanism'] = sasl_mechanism + if sasl_credentials is not None: + sasl_creds['credentials'] = sasl_credentials + # else: + # sasl_creds['credentials'] = None + request['authentication'] = AuthenticationChoice().setComponentByName('sasl', sasl_creds) + elif authentication == ANONYMOUS: + if name: + raise LDAPUserNameNotAllowedError('user name not allowed in anonymous bind') + request['name'] = '' + request['authentication'] = AuthenticationChoice().setComponentByName('simple', Simple('')) + elif authentication == 'SICILY_PACKAGE_DISCOVERY': # https://msdn.microsoft.com/en-us/library/cc223501.aspx + request['name'] = '' + request['authentication'] = AuthenticationChoice().setComponentByName('sicilyPackageDiscovery', SicilyPackageDiscovery('')) + elif authentication == 'SICILY_NEGOTIATE_NTLM': # https://msdn.microsoft.com/en-us/library/cc223501.aspx + request['name'] = 'NTLM' + request['authentication'] = AuthenticationChoice().setComponentByName('sicilyNegotiate', SicilyNegotiate(name.create_negotiate_message())) # ntlm client in self.name + elif authentication == 'SICILY_RESPONSE_NTLM': # https://msdn.microsoft.com/en-us/library/cc223501.aspx + name.parse_challenge_message(password) # server_creds returned by server in password + server_creds = name.create_authenticate_message() + if server_creds: + request['name'] = '' + request['authentication'] = AuthenticationChoice().setComponentByName('sicilyResponse', SicilyResponse(server_creds)) + else: + request = None + else: + raise LDAPUnknownAuthenticationMethodError('unknown authentication method') + + return request + + +def bind_request_to_dict(request): + return {'version': int(request['version']), + 'name': str(request['name']), + 'authentication': authentication_choice_to_dict(request['authentication'])} + + +def bind_response_operation(result_code, + matched_dn='', + diagnostic_message='', + referral=None, + server_sasl_credentials=None): + # BindResponse ::= [APPLICATION 1] SEQUENCE { + # COMPONENTS OF LDAPResult, + # serverSaslCreds [7] OCTET STRING OPTIONAL } + response = BindResponse() + response['resultCode'] = ResultCode(result_code) + response['matchedDN'] = LDAPDN(matched_dn) + response['diagnosticMessage'] = LDAPString(diagnostic_message) + if referral: + response['referral'] = Referral(referral) + + if server_sasl_credentials: + response['serverSaslCreds'] = ServerSaslCreds(server_sasl_credentials) + + return response + + +def bind_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'dn': str(response['matchedDN']), + 'message': str(response['diagnosticMessage']), + 'referrals': referrals_to_list(response['referral']) if response['referral'] is not None and response['referral'].hasValue() else [], + 'saslCreds': bytes(response['serverSaslCreds']) if response['serverSaslCreds'] is not None and response['serverSaslCreds'].hasValue() else None} + + +def sicily_bind_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'server_creds': bytes(response['matchedDN']), + 'error_message': str(response['diagnosticMessage'])} + + +def bind_response_to_dict_fast(response): + response_dict = dict() + response_dict['result'] = int(response[0][3]) # resultCode + response_dict['description'] = RESULT_CODES[response_dict['result']] + response_dict['dn'] = to_unicode(response[1][3], from_server=True) # matchedDN + response_dict['message'] = to_unicode(response[2][3], from_server=True) # diagnosticMessage + response_dict['referrals'] = None # referrals + response_dict['saslCreds'] = None # saslCreds + for r in response[3:]: + if r[2] == 3: # referrals + response_dict['referrals'] = referrals_to_list(r[3]) # referrals + else: + response_dict['saslCreds'] = bytes(r[3]) # saslCreds + + return response_dict + + +def sicily_bind_response_to_dict_fast(response): + response_dict = dict() + response_dict['result'] = int(response[0][3]) # resultCode + response_dict['description'] = RESULT_CODES[response_dict['result']] + response_dict['server_creds'] = bytes(response[1][3]) # server_creds + response_dict['error_message'] = to_unicode(response[2][3], from_server=True) # error_message + + return response_dict diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/compare.py b/plugins/ldap-user-sync/vendor/ldap3/operation/compare.py new file mode 100644 index 00000000..9aca8f60 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/compare.py @@ -0,0 +1,64 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from ..protocol.convert import validate_attribute_value, prepare_for_sending +from ..protocol.rfc4511 import CompareRequest, AttributeValueAssertion, AttributeDescription, LDAPDN, AssertionValue, ResultCode +from ..operation.search import ava_to_dict +from ..operation.bind import referrals_to_list + + +def compare_operation(dn, + attribute, + value, + auto_encode, + schema=None, + validator=None, + check_names=False): + # CompareRequest ::= [APPLICATION 14] SEQUENCE { + # entry LDAPDN, + # ava AttributeValueAssertion } + ava = AttributeValueAssertion() + ava['attributeDesc'] = AttributeDescription(attribute) + ava['assertionValue'] = AssertionValue(prepare_for_sending(validate_attribute_value(schema, attribute, value, auto_encode, validator, check_names=check_names))) + + request = CompareRequest() + request['entry'] = LDAPDN(dn) + request['ava'] = ava + + return request + + +def compare_request_to_dict(request): + ava = ava_to_dict(request['ava']) + return {'entry': str(request['entry']), + 'attribute': ava['attribute'], + 'value': ava['value']} + + +def compare_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'dn': str(response['matchedDN']), 'message': str(response['diagnosticMessage']), + 'referrals': referrals_to_list(response['referral'])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/delete.py b/plugins/ldap-user-sync/vendor/ldap3/operation/delete.py new file mode 100644 index 00000000..269c7f74 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/delete.py @@ -0,0 +1,46 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from ..protocol.rfc4511 import DelRequest, LDAPDN, ResultCode +from ..operation.bind import referrals_to_list + + +def delete_operation(dn): + # DelRequest ::= [APPLICATION 10] LDAPDN + request = DelRequest(LDAPDN(dn)) + + return request + + +def delete_request_to_dict(request): + return {'entry': str(request)} + + +def delete_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'dn': str(response['matchedDN']), + 'message': str(response['diagnosticMessage']), + 'referrals': referrals_to_list(response['referral'])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/extended.py b/plugins/ldap-user-sync/vendor/ldap3/operation/extended.py new file mode 100644 index 00000000..91155836 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/extended.py @@ -0,0 +1,109 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from pyasn1.type.univ import OctetString +from pyasn1.type.base import Asn1Item + +from ..core.results import RESULT_CODES +from ..protocol.rfc4511 import ExtendedRequest, RequestName, ResultCode, RequestValue +from ..protocol.convert import referrals_to_list +from ..utils.asn1 import encode +from ..utils.conv import to_unicode + +# ExtendedRequest ::= [APPLICATION 23] SEQUENCE { +# requestName [0] LDAPOID, +# requestValue [1] OCTET STRING OPTIONAL } + + +def extended_operation(request_name, + request_value=None, + no_encode=None): + request = ExtendedRequest() + request['requestName'] = RequestName(request_name) + if request_value and isinstance(request_value, Asn1Item): + request['requestValue'] = RequestValue(encode(request_value)) + elif str is not bytes and isinstance(request_value, (bytes, bytearray)): # in Python 3 doesn't try to encode a byte value + request['requestValue'] = request_value + elif request_value and no_encode: # doesn't encode the value + request['requestValue'] = request_value + elif request_value: # tries to encode as a octet string + request['requestValue'] = RequestValue(encode(OctetString(str(request_value)))) + + # elif request_value is not None: + # raise LDAPExtensionError('unable to encode value for extended operation') + return request + + +def extended_request_to_dict(request): + # return {'name': str(request['requestName']), 'value': bytes(request['requestValue']) if request['requestValue'] else None} + return {'name': str(request['requestName']), 'value': bytes(request['requestValue']) if 'requestValue' in request and request['requestValue'] is not None and request['requestValue'].hasValue() else None} + +def extended_response_to_dict(response): + return {'result': int(response['resultCode']), + 'dn': str(response['matchedDN']), + 'message': str(response['diagnosticMessage']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'referrals': referrals_to_list(response['referral']), + 'responseName': str(response['responseName']) if response['responseName'] is not None and response['responseName'].hasValue() else str(), + 'responseValue': bytes(response['responseValue']) if response['responseValue'] is not None and response['responseValue'].hasValue() else bytes()} + + +def intermediate_response_to_dict(response): + return {'responseName': str(response['responseName']), + 'responseValue': bytes(response['responseValue']) if response['responseValue'] else bytes()} + + +def extended_response_to_dict_fast(response): + response_dict = dict() + response_dict['result'] = int(response[0][3]) # resultCode + response_dict['description'] = RESULT_CODES[response_dict['result']] + response_dict['dn'] = to_unicode(response[1][3], from_server=True) # matchedDN + response_dict['message'] = to_unicode(response[2][3], from_server=True) # diagnosticMessage + response_dict['referrals'] = None # referrals + response_dict['responseName'] = None # referrals + response_dict['responseValue'] = None # responseValue + + for r in response[3:]: + if r[2] == 3: # referrals + response_dict['referrals'] = referrals_to_list(r[3]) # referrals + elif r[2] == 10: # responseName + response_dict['responseName'] = to_unicode(r[3], from_server=True) + response_dict['responseValue'] = b'' # responseValue could be empty + + else: # responseValue (11) + response_dict['responseValue'] = bytes(r[3]) + + return response_dict + + +def intermediate_response_to_dict_fast(response): + response_dict = dict() + for r in response: + if r[2] == 0: # responseName + response_dict['responseName'] = to_unicode(r[3], from_server=True) + else: # responseValue (1) + response_dict['responseValue'] = bytes(r[3]) + + return response_dict diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/modify.py b/plugins/ldap-user-sync/vendor/ldap3/operation/modify.py new file mode 100644 index 00000000..ed1d04ec --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/modify.py @@ -0,0 +1,96 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from .. import SEQUENCE_TYPES, MODIFY_ADD, MODIFY_DELETE, MODIFY_REPLACE, MODIFY_INCREMENT +from ..protocol.rfc4511 import ModifyRequest, LDAPDN, Changes, Change, Operation, PartialAttribute, AttributeDescription, Vals, ResultCode +from ..operation.bind import referrals_to_list +from ..protocol.convert import changes_to_list, validate_attribute_value, prepare_for_sending + +# ModifyRequest ::= [APPLICATION 6] SEQUENCE { +# object LDAPDN, +# changes SEQUENCE OF change SEQUENCE { +# operation ENUMERATED { +# add (0), +# delete (1), +# replace (2), +# ... }, +# modification PartialAttribute } } + +change_table = {MODIFY_ADD: 0, # accepts actual values too + MODIFY_DELETE: 1, + MODIFY_REPLACE: 2, + MODIFY_INCREMENT: 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3} + + +def modify_operation(dn, + changes, + auto_encode, + schema=None, + validator=None, + check_names=False): + # changes is a dictionary in the form {'attribute': [(operation, [val1, ...]), ...], ...} + # operation is 0 (add), 1 (delete), 2 (replace), 3 (increment) + # increment as per RFC4525 + + change_list = Changes() + pos = 0 + for attribute in changes: + for change_operation in changes[attribute]: + partial_attribute = PartialAttribute() + partial_attribute['type'] = AttributeDescription(attribute) + partial_attribute['vals'] = Vals() + if isinstance(change_operation[1], SEQUENCE_TYPES): + for index, value in enumerate(change_operation[1]): + partial_attribute['vals'].setComponentByPosition(index, prepare_for_sending(validate_attribute_value(schema, attribute, value, auto_encode, validator, check_names=check_names))) + else: + partial_attribute['vals'].setComponentByPosition(0, prepare_for_sending(validate_attribute_value(schema, attribute, change_operation[1], auto_encode, validator, check_names=check_names))) + change = Change() + change['operation'] = Operation(change_table[change_operation[0]]) + change['modification'] = partial_attribute + + change_list[pos] = change + pos += 1 + + request = ModifyRequest() + request['object'] = LDAPDN(dn) + request['changes'] = change_list + return request + + +def modify_request_to_dict(request): + return {'entry': str(request['object']), + 'changes': changes_to_list(request['changes'])} + + +def modify_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'message': str(response['diagnosticMessage']), + 'dn': str(response['matchedDN']), + 'referrals': referrals_to_list(response['referral'])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/modifyDn.py b/plugins/ldap-user-sync/vendor/ldap3/operation/modifyDn.py new file mode 100644 index 00000000..c2702518 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/modifyDn.py @@ -0,0 +1,62 @@ +""" +""" + +# Created on 2013.05.31 +# +# 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 . + +from ..protocol.rfc4511 import ModifyDNRequest, LDAPDN, RelativeLDAPDN, DeleteOldRDN, NewSuperior, ResultCode +from ..operation.bind import referrals_to_list + +# ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { +# entry LDAPDN, +# newrdn RelativeLDAPDN, +# deleteoldrdn BOOLEAN, +# newSuperior [0] LDAPDN OPTIONAL } + + +def modify_dn_operation(dn, + new_relative_dn, + delete_old_rdn=True, + new_superior=None): + request = ModifyDNRequest() + request['entry'] = LDAPDN(dn) + request['newrdn'] = RelativeLDAPDN(new_relative_dn) + request['deleteoldrdn'] = DeleteOldRDN(delete_old_rdn) + if new_superior: + request['newSuperior'] = NewSuperior(new_superior) + + return request + + +def modify_dn_request_to_dict(request): + return {'entry': str(request['entry']), + 'newRdn': str(request['newrdn']), + 'deleteOldRdn': bool(request['deleteoldrdn']), + 'newSuperior': str(request['newSuperior']) if request['newSuperior'] is not None and request['newSuperior'].hasValue() else None} + + +def modify_dn_response_to_dict(response): + return {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'dn': str(response['matchedDN']), + 'referrals': referrals_to_list(response['referral']), + 'message': str(response['diagnosticMessage'])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/search.py b/plugins/ldap-user-sync/vendor/ldap3/operation/search.py new file mode 100644 index 00000000..92ade9cb --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/search.py @@ -0,0 +1,579 @@ +""" +""" + +# Created on 2013.06.02 +# +# 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 . + +from string import whitespace +from os import linesep + +from .. import DEREF_NEVER, BASE, LEVEL, SUBTREE, DEREF_SEARCH, DEREF_BASE, DEREF_ALWAYS, NO_ATTRIBUTES, SEQUENCE_TYPES, get_config_parameter, STRING_TYPES + +from ..core.exceptions import LDAPInvalidFilterError, LDAPAttributeError, LDAPInvalidScopeError, LDAPInvalidDereferenceAliasesError +from ..utils.ciDict import CaseInsensitiveDict +from ..protocol.rfc4511 import SearchRequest, LDAPDN, Scope, DerefAliases, Integer0ToMax, TypesOnly, \ + AttributeSelection, Selector, EqualityMatch, AttributeDescription, AssertionValue, Filter, \ + Not, And, Or, ApproxMatch, GreaterOrEqual, LessOrEqual, ExtensibleMatch, Present, SubstringFilter, \ + Substrings, Final, Initial, Any, ResultCode, Substring, MatchingRule, Type, MatchValue, DnAttributes +from ..operation.bind import referrals_to_list +from ..protocol.convert import ava_to_dict, attributes_to_list, search_refs_to_list, validate_assertion_value, prepare_filter_for_sending, search_refs_to_list_fast +from ..protocol.formatters.standard import format_attribute_values +from ..utils.conv import to_unicode, to_raw + +ROOT = 0 +AND = 1 +OR = 2 +NOT = 3 +MATCH_APPROX = 4 +MATCH_GREATER_OR_EQUAL = 5 +MATCH_LESS_OR_EQUAL = 6 +MATCH_EXTENSIBLE = 7 +MATCH_PRESENT = 8 +MATCH_SUBSTRING = 9 +MATCH_EQUAL = 10 + +SEARCH_OPEN = 20 +SEARCH_OPEN_OR_CLOSE = 21 +SEARCH_MATCH_OR_CLOSE = 22 +SEARCH_MATCH_OR_CONTROL = 23 + + +class FilterNode(object): + def __init__(self, tag=None, assertion=None): + self.tag = tag + self.parent = None + self.assertion = assertion + self.elements = [] + + def append(self, filter_node): + filter_node.parent = self + self.elements.append(filter_node) + return filter_node + + def __str__(self, pos=0): + self.__repr__(pos) + + def __repr__(self, pos=0): + node_tags = ['ROOT', 'AND', 'OR', 'NOT', 'MATCH_APPROX', 'MATCH_GREATER_OR_EQUAL', 'MATCH_LESS_OR_EQUAL', 'MATCH_EXTENSIBLE', 'MATCH_PRESENT', 'MATCH_SUBSTRING', 'MATCH_EQUAL'] + representation = ' ' * pos + 'tag: ' + node_tags[self.tag] + ' - assertion: ' + str(self.assertion) + if self.elements: + representation += ' - elements: ' + str(len(self.elements)) + for element in self.elements: + representation += linesep + ' ' * pos + element.__repr__(pos + 2) + return representation + + +def evaluate_match(match, schema, auto_escape, auto_encode, validator, check_names): + left_part, equal_sign, right_part = match.strip().partition('=') + if not equal_sign: + raise LDAPInvalidFilterError('invalid matching assertion') + if left_part.endswith('~'): # approximate match '~=' + tag = MATCH_APPROX + left_part = left_part[:-1].strip() + right_part = right_part.strip() + assertion = {'attr': left_part, 'value': validate_assertion_value(schema, left_part, right_part, auto_escape, auto_encode, validator, check_names)} + elif left_part.endswith('>'): # greater or equal match '>=' + tag = MATCH_GREATER_OR_EQUAL + left_part = left_part[:-1].strip() + right_part = right_part.strip() + assertion = {'attr': left_part, 'value': validate_assertion_value(schema, left_part, right_part, auto_escape, auto_encode, validator, check_names)} + elif left_part.endswith('<'): # less or equal match '<=' + tag = MATCH_LESS_OR_EQUAL + left_part = left_part[:-1].strip() + right_part = right_part.strip() + assertion = {'attr': left_part, 'value': validate_assertion_value(schema, left_part, right_part, auto_escape, auto_encode, validator, check_names)} + elif left_part.endswith(':'): # extensible match ':=' + tag = MATCH_EXTENSIBLE + left_part = left_part[:-1].strip() + right_part = right_part.strip() + extended_filter_list = left_part.split(':') + matching_rule = False + dn_attributes = False + attribute_name = False + if extended_filter_list[0] == '': # extensible filter format [:dn]:matchingRule:=assertionValue + if len(extended_filter_list) == 2 and extended_filter_list[1].lower().strip() != 'dn': + matching_rule = extended_filter_list[1] + elif len(extended_filter_list) == 3 and extended_filter_list[1].lower().strip() == 'dn': + dn_attributes = True + matching_rule = extended_filter_list[2] + else: + raise LDAPInvalidFilterError('invalid extensible filter') + elif len(extended_filter_list) <= 3: # extensible filter format attr[:dn][:matchingRule]:=assertionValue + if len(extended_filter_list) == 1: + attribute_name = extended_filter_list[0] + elif len(extended_filter_list) == 2: + attribute_name = extended_filter_list[0] + if extended_filter_list[1].lower().strip() == 'dn': + dn_attributes = True + else: + matching_rule = extended_filter_list[1] + elif len(extended_filter_list) == 3 and extended_filter_list[1].lower().strip() == 'dn': + attribute_name = extended_filter_list[0] + dn_attributes = True + matching_rule = extended_filter_list[2] + else: + raise LDAPInvalidFilterError('invalid extensible filter') + + if not attribute_name and not matching_rule: + raise LDAPInvalidFilterError('invalid extensible filter') + attribute_name = attribute_name.strip() if attribute_name else False + matching_rule = matching_rule.strip() if matching_rule else False + assertion = {'attr': attribute_name, 'value': validate_assertion_value(schema, attribute_name, right_part, auto_escape, auto_encode, validator, check_names), 'matchingRule': matching_rule, 'dnAttributes': dn_attributes} + elif right_part == '*': # attribute present match '=*' + tag = MATCH_PRESENT + left_part = left_part.strip() + assertion = {'attr': left_part} + elif '*' in right_part: # substring match '=initial*substring*substring*final' + tag = MATCH_SUBSTRING + left_part = left_part.strip() + right_part = right_part.strip() + substrings = right_part.split('*') + initial = validate_assertion_value(schema, left_part, substrings[0], auto_escape, auto_encode, validator, check_names) if substrings[0] else None + final = validate_assertion_value(schema, left_part, substrings[-1], auto_escape, auto_encode, validator, check_names) if substrings[-1] else None + any_string = [validate_assertion_value(schema, left_part, substring, auto_escape, auto_encode, validator, check_names) for substring in substrings[1:-1] if substring] + #assertion = {'attr': left_part, 'initial': initial, 'any': any_string, 'final': final} + assertion = {'attr': left_part} + if initial: + assertion['initial'] = initial + if any_string: + assertion['any'] = any_string + if final: + assertion['final'] = final + else: # equality match '=' + tag = MATCH_EQUAL + left_part = left_part.strip() + right_part = right_part.strip() + assertion = {'attr': left_part, 'value': validate_assertion_value(schema, left_part, right_part, auto_escape, auto_encode, validator, check_names)} + + return FilterNode(tag, assertion) + + +def parse_filter(search_filter, schema, auto_escape, auto_encode, validator, check_names): + if str is not bytes and isinstance(search_filter, bytes): # python 3 with byte filter + search_filter = to_unicode(search_filter) + search_filter = search_filter.strip() + if search_filter and search_filter.count('(') == search_filter.count(')') and search_filter.startswith('(') and search_filter.endswith(')'): + state = SEARCH_OPEN_OR_CLOSE + root = FilterNode(ROOT) + current_node = root + start_pos = None + skip_white_space = True + just_closed = False + for pos, c in enumerate(search_filter): + if skip_white_space and c in whitespace: + continue + elif (state == SEARCH_OPEN or state == SEARCH_OPEN_OR_CLOSE) and c == '(': + state = SEARCH_MATCH_OR_CONTROL + just_closed = False + elif state == SEARCH_MATCH_OR_CONTROL and c in '&!|': + if c == '&': + current_node = current_node.append(FilterNode(AND)) + elif c == '|': + current_node = current_node.append(FilterNode(OR)) + elif c == '!': + current_node = current_node.append(FilterNode(NOT)) + state = SEARCH_OPEN + elif (state == SEARCH_MATCH_OR_CLOSE or state == SEARCH_OPEN_OR_CLOSE) and c == ')': + if just_closed: + current_node = current_node.parent + else: + just_closed = True + skip_white_space = True + end_pos = pos + if start_pos: + if current_node.tag == NOT and len(current_node.elements) > 0: + raise LDAPInvalidFilterError('NOT (!) clause in filter cannot be multiple') + current_node.append(evaluate_match(search_filter[start_pos:end_pos], schema, auto_escape, auto_encode, validator, check_names)) + start_pos = None + state = SEARCH_OPEN_OR_CLOSE + elif (state == SEARCH_MATCH_OR_CLOSE or state == SEARCH_MATCH_OR_CONTROL) and c not in '()': + skip_white_space = False + if not start_pos: + start_pos = pos + state = SEARCH_MATCH_OR_CLOSE + else: + raise LDAPInvalidFilterError('malformed filter') + if len(root.elements) != 1: + raise LDAPInvalidFilterError('missing boolean operator in filter') + return root + else: + raise LDAPInvalidFilterError('invalid filter') + + +def compile_filter(filter_node): + """Builds ASN1 structure for filter, converts from filter LDAP escaping to bytes""" + compiled_filter = Filter() + if filter_node.tag == AND: + boolean_filter = And() + pos = 0 + for element in filter_node.elements: + boolean_filter[pos] = compile_filter(element) + pos += 1 + compiled_filter['and'] = boolean_filter + elif filter_node.tag == OR: + boolean_filter = Or() + pos = 0 + for element in filter_node.elements: + boolean_filter[pos] = compile_filter(element) + pos += 1 + compiled_filter['or'] = boolean_filter + elif filter_node.tag == NOT: + boolean_filter = Not() + boolean_filter['innerNotFilter'] = compile_filter(filter_node.elements[0]) + compiled_filter.setComponentByName('notFilter', boolean_filter, verifyConstraints=False) # do not verify constraints because of hack for recursive filters in rfc4511 + + elif filter_node.tag == MATCH_APPROX: + matching_filter = ApproxMatch() + matching_filter['attributeDesc'] = AttributeDescription(filter_node.assertion['attr']) + matching_filter['assertionValue'] = AssertionValue(prepare_filter_for_sending(filter_node.assertion['value'])) + compiled_filter['approxMatch'] = matching_filter + elif filter_node.tag == MATCH_GREATER_OR_EQUAL: + matching_filter = GreaterOrEqual() + matching_filter['attributeDesc'] = AttributeDescription(filter_node.assertion['attr']) + matching_filter['assertionValue'] = AssertionValue(prepare_filter_for_sending(filter_node.assertion['value'])) + compiled_filter['greaterOrEqual'] = matching_filter + elif filter_node.tag == MATCH_LESS_OR_EQUAL: + matching_filter = LessOrEqual() + matching_filter['attributeDesc'] = AttributeDescription(filter_node.assertion['attr']) + matching_filter['assertionValue'] = AssertionValue(prepare_filter_for_sending(filter_node.assertion['value'])) + compiled_filter['lessOrEqual'] = matching_filter + elif filter_node.tag == MATCH_EXTENSIBLE: + matching_filter = ExtensibleMatch() + if filter_node.assertion['matchingRule']: + matching_filter['matchingRule'] = MatchingRule(filter_node.assertion['matchingRule']) + if filter_node.assertion['attr']: + matching_filter['type'] = Type(filter_node.assertion['attr']) + matching_filter['matchValue'] = MatchValue(prepare_filter_for_sending(filter_node.assertion['value'])) + matching_filter['dnAttributes'] = DnAttributes(filter_node.assertion['dnAttributes']) + compiled_filter['extensibleMatch'] = matching_filter + elif filter_node.tag == MATCH_PRESENT: + matching_filter = Present(AttributeDescription(filter_node.assertion['attr'])) + compiled_filter['present'] = matching_filter + elif filter_node.tag == MATCH_SUBSTRING: + matching_filter = SubstringFilter() + matching_filter['type'] = AttributeDescription(filter_node.assertion['attr']) + substrings = Substrings() + pos = 0 + if 'initial' in filter_node.assertion and filter_node.assertion['initial']: + substrings[pos] = Substring().setComponentByName('initial', Initial(prepare_filter_for_sending(filter_node.assertion['initial']))) + pos += 1 + if 'any' in filter_node.assertion and filter_node.assertion['any']: + for substring in filter_node.assertion['any']: + substrings[pos] = Substring().setComponentByName('any', Any(prepare_filter_for_sending(substring))) + pos += 1 + if 'final' in filter_node.assertion and filter_node.assertion['final']: + substrings[pos] = Substring().setComponentByName('final', Final(prepare_filter_for_sending(filter_node.assertion['final']))) + matching_filter['substrings'] = substrings + compiled_filter['substringFilter'] = matching_filter + elif filter_node.tag == MATCH_EQUAL: + matching_filter = EqualityMatch() + matching_filter['attributeDesc'] = AttributeDescription(filter_node.assertion['attr']) + matching_filter['assertionValue'] = AssertionValue(prepare_filter_for_sending(filter_node.assertion['value'])) + compiled_filter.setComponentByName('equalityMatch', matching_filter) + else: + raise LDAPInvalidFilterError('unknown filter node tag') + + return compiled_filter + + +def build_attribute_selection(attribute_list, schema): + conf_attributes_excluded_from_check = [v.lower() for v in get_config_parameter('ATTRIBUTES_EXCLUDED_FROM_CHECK')] + + attribute_selection = AttributeSelection() + for index, attribute in enumerate(attribute_list): + if schema and schema.attribute_types: + if ';' in attribute: # exclude tags from validation + if not attribute[0:attribute.index(';')] in schema.attribute_types and attribute.lower() not in conf_attributes_excluded_from_check: + raise LDAPAttributeError('invalid attribute type in attribute list: ' + attribute) + else: + if attribute not in schema.attribute_types and attribute.lower() not in conf_attributes_excluded_from_check: + raise LDAPAttributeError('invalid attribute type in attribute list: ' + attribute) + attribute_selection[index] = Selector(attribute) + + return attribute_selection + + +def search_operation(search_base, + search_filter, + search_scope, + dereference_aliases, + attributes, + size_limit, + time_limit, + types_only, + auto_escape, + auto_encode, + schema=None, + validator=None, + check_names=False): + # SearchRequest ::= [APPLICATION 3] SEQUENCE { + # baseObject LDAPDN, + # scope ENUMERATED { + # baseObject (0), + # singleLevel (1), + # wholeSubtree (2), + # ... }, + # derefAliases ENUMERATED { + # neverDerefAliases (0), + # derefInSearching (1), + # derefFindingBaseObj (2), + # derefAlways (3) }, + # sizeLimit INTEGER (0 .. maxInt), + # timeLimit INTEGER (0 .. maxInt), + # typesOnly BOOLEAN, + # filter Filter, + # attributes AttributeSelection } + request = SearchRequest() + request['baseObject'] = LDAPDN(search_base) + + if search_scope == BASE or search_scope == 0: + request['scope'] = Scope('baseObject') + elif search_scope == LEVEL or search_scope == 1: + request['scope'] = Scope('singleLevel') + elif search_scope == SUBTREE or search_scope == 2: + request['scope'] = Scope('wholeSubtree') + else: + raise LDAPInvalidScopeError('invalid scope type') + + if dereference_aliases == DEREF_NEVER or dereference_aliases == 0: + request['derefAliases'] = DerefAliases('neverDerefAliases') + elif dereference_aliases == DEREF_SEARCH or dereference_aliases == 1: + request['derefAliases'] = DerefAliases('derefInSearching') + elif dereference_aliases == DEREF_BASE or dereference_aliases == 2: + request['derefAliases'] = DerefAliases('derefFindingBaseObj') + elif dereference_aliases == DEREF_ALWAYS or dereference_aliases == 3: + request['derefAliases'] = DerefAliases('derefAlways') + else: + raise LDAPInvalidDereferenceAliasesError('invalid dereference aliases type') + + request['sizeLimit'] = Integer0ToMax(size_limit) + request['timeLimit'] = Integer0ToMax(time_limit) + request['typesOnly'] = TypesOnly(True) if types_only else TypesOnly(False) + request['filter'] = compile_filter(parse_filter(search_filter, schema, auto_escape, auto_encode, validator, check_names).elements[0]) # parse the searchFilter string and compile it starting from the root node + if not isinstance(attributes, SEQUENCE_TYPES): + attributes = [NO_ATTRIBUTES] + + request['attributes'] = build_attribute_selection(attributes, schema) + + return request + + +def decode_vals(vals): + try: + return [str(val) for val in vals if val] if vals else None + except UnicodeDecodeError: + return decode_raw_vals(vals) + +def decode_vals_fast(vals): + try: + return [to_unicode(val[3], from_server=True) for val in vals if val] if vals else None + except UnicodeDecodeError: + return [val[3] for val in vals if val] if vals else None + + +def attributes_to_dict(attribute_list): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + attributes[str(attribute['type'])] = decode_vals(attribute['vals']) + return attributes + + +def attributes_to_dict_fast(attribute_list): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + attributes[to_unicode(attribute[3][0][3], from_server=True)] = decode_vals_fast(attribute[3][1][3]) + + return attributes + + +def decode_raw_vals(vals): + return [bytes(val) for val in vals] if vals else None + + +def decode_raw_vals_fast(vals): + return [bytes(val[3]) for val in vals] if vals else None + + +def raw_attributes_to_dict(attribute_list): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + + attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + attributes[str(attribute['type'])] = decode_raw_vals(attribute['vals']) + + return attributes + + +def raw_attributes_to_dict_fast(attribute_list): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + attributes[to_unicode(attribute[3][0][3], from_server=True)] = decode_raw_vals_fast(attribute[3][1][3]) + + return attributes + + +def checked_attributes_to_dict(attribute_list, schema=None, custom_formatter=None): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + + checked_attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + name = str(attribute['type']) + checked_attributes[name] = format_attribute_values(schema, name, decode_raw_vals(attribute['vals']) or [], custom_formatter) + return checked_attributes + + +def checked_attributes_to_dict_fast(attribute_list, schema=None, custom_formatter=None): + conf_case_insensitive_attributes = get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES') + + checked_attributes = CaseInsensitiveDict() if conf_case_insensitive_attributes else dict() + for attribute in attribute_list: + name = to_unicode(attribute[3][0][3], from_server=True) + checked_attributes[name] = format_attribute_values(schema, name, decode_raw_vals_fast(attribute[3][1][3]) or [], custom_formatter) + return checked_attributes + + +def matching_rule_assertion_to_string(matching_rule_assertion): + return str(matching_rule_assertion) + + +def filter_to_string(filter_object): + filter_type = filter_object.getName() + filter_string = '(' + if filter_type == 'and': + filter_string += '&' + for f in filter_object['and']: + filter_string += filter_to_string(f) + elif filter_type == 'or': + filter_string += '|' + for f in filter_object['or']: + filter_string += filter_to_string(f) + elif filter_type == 'notFilter': + filter_string += '!' + filter_to_string(filter_object['notFilter']['innerNotFilter']) + elif filter_type == 'equalityMatch': + ava = ava_to_dict(filter_object['equalityMatch']) + filter_string += ava['attribute'] + '=' + ava['value'] + elif filter_type == 'substringFilter': + attribute = filter_object['substringFilter']['type'] + filter_string += str(attribute) + '=' + for substring in filter_object['substringFilter']['substrings']: + component = substring.getName() + if substring[component] is not None and substring[component].hasValue(): + if component == 'initial': + filter_string += str(substring['initial']) + '*' + elif component == 'any': + filter_string += str(substring['any']) if filter_string.endswith('*') else '*' + str(substring['any']) + filter_string += '*' + elif component == 'final': + filter_string += '*' + str(substring['final']) + elif filter_type == 'greaterOrEqual': + ava = ava_to_dict(filter_object['greaterOrEqual']) + filter_string += ava['attribute'] + '>=' + ava['value'] + elif filter_type == 'lessOrEqual': + ava = ava_to_dict(filter_object['lessOrEqual']) + filter_string += ava['attribute'] + '<=' + ava['value'] + elif filter_type == 'present': + filter_string += str(filter_object['present']) + '=*' + elif filter_type == 'approxMatch': + ava = ava_to_dict(filter_object['approxMatch']) + filter_string += ava['attribute'] + '~=' + ava['value'] + elif filter_type == 'extensibleMatch': + filter_string += matching_rule_assertion_to_string(filter_object['extensibleMatch']) + else: + raise LDAPInvalidFilterError('error converting filter to string') + filter_string += ')' + + if str is bytes: # Python2, forces conversion to Unicode + filter_string = to_unicode(filter_string) + + return filter_string + + +def search_request_to_dict(request): + return {'base': str(request['baseObject']), + 'scope': int(request['scope']), + 'dereferenceAlias': int(request['derefAliases']), + 'sizeLimit': int(request['sizeLimit']), + 'timeLimit': int(request['timeLimit']), + 'typesOnly': bool(request['typesOnly']), + 'filter': filter_to_string(request['filter']), + 'attributes': attributes_to_list(request['attributes'])} + + +def search_result_entry_response_to_dict(response, schema, custom_formatter, check_names): + entry = dict() + # entry['dn'] = str(response['object']) + if response['object']: + if isinstance(response['object'], STRING_TYPES): # mock strategies return string not a PyAsn1 object + entry['raw_dn'] = to_raw(response['object']) + entry['dn'] = to_unicode(response['object']) + else: + entry['raw_dn'] = str(response['object']) + entry['dn'] = to_unicode(bytes(response['object']), from_server=True) + else: + entry['raw_dn'] = b'' + entry['dn'] = '' + entry['raw_attributes'] = raw_attributes_to_dict(response['attributes']) + if check_names: + entry['attributes'] = checked_attributes_to_dict(response['attributes'], schema, custom_formatter) + else: + entry['attributes'] = attributes_to_dict(response['attributes']) + + return entry + + +def search_result_done_response_to_dict(response): + result = {'result': int(response['resultCode']), + 'description': ResultCode().getNamedValues().getName(response['resultCode']), + 'message': str(response['diagnosticMessage']), + 'dn': str(response['matchedDN']), + 'referrals': referrals_to_list(response['referral'])} + + if 'controls' in response: # used for returning controls in Mock strategies + result['controls'] = dict() + for control in response['controls']: + result['controls'][control[0]] = control[1] + + return result + + +def search_result_reference_response_to_dict(response): + return {'uri': search_refs_to_list(response)} + + +def search_result_entry_response_to_dict_fast(response, schema, custom_formatter, check_names): + entry_dict = dict() + entry_dict['raw_dn'] = response[0][3] + entry_dict['dn'] = to_unicode(response[0][3], from_server=True) + entry_dict['raw_attributes'] = raw_attributes_to_dict_fast(response[1][3]) # attributes + if check_names: + entry_dict['attributes'] = checked_attributes_to_dict_fast(response[1][3], schema, custom_formatter) # attributes + else: + entry_dict['attributes'] = attributes_to_dict_fast(response[1][3]) # attributes + + return entry_dict + + +def search_result_reference_response_to_dict_fast(response): + return {'uri': search_refs_to_list_fast([r[3] for r in response])} diff --git a/plugins/ldap-user-sync/vendor/ldap3/operation/unbind.py b/plugins/ldap-user-sync/vendor/ldap3/operation/unbind.py new file mode 100644 index 00000000..5196c526 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/operation/unbind.py @@ -0,0 +1,32 @@ +""" +""" + +# Created on 2013.09.03 +# +# 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 . + +from ..protocol.rfc4511 import UnbindRequest + + +def unbind_operation(): + # UnbindRequest ::= [APPLICATION 2] NULL + request = UnbindRequest() + return request diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/controls.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/controls.py new file mode 100644 index 00000000..fb7fd44f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/controls.py @@ -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 . + +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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/convert.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/convert.py new file mode 100644 index 00000000..4acc3cbf --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/convert.py @@ -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 . +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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/formatters.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/formatters.py new file mode 100644 index 00000000..2638d52b --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/formatters.py @@ -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 . + +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[0-9]{4}) + (?P0[1-9]|1[0-2]) + (?P0[1-9]|[12][0-9]|3[01]) + (?P[01][0-9]|2[0-3]) + (?: + (?P[0-5][0-9]) + (?P[0-5][0-9]|60)? + )? + (?: + [.,] + (?P[0-9]+) + )? + (?: + Z + | + (?: + (?P[+-]) + (?P[01][0-9]|2[0-3]) + (?P[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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/standard.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/standard.py new file mode 100644 index 00000000..42f6c266 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/standard.py @@ -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 . + +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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/validators.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/validators.py new file mode 100644 index 00000000..d30b80f6 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/formatters/validators.py @@ -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 . +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[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('. + +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) \ No newline at end of file diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/novell.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/novell.py new file mode 100644 index 00000000..d9ee501a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/novell.py @@ -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 . + +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()) + ) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/oid.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/oid.py new file mode 100644 index 00000000..9e683115 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/oid.py @@ -0,0 +1,1208 @@ +""" +""" + +# Created on 2013.08.30 +# +# 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 . + +from .. import SEQUENCE_TYPES + +# Holds info about OIDs. +# Each OID info is a named tuple with the following attributes: +# oid - the OID number +# type - type of OID +# name - description of OID +# doc - reference document of OID +# +# Source of information is IANA ldap-parameters.txt, oid-registry and products documentation as of 2013.08.21 + + +# OID database definition +OID_CONTROL = 'CONTROL' +OID_EXTENSION = 'EXTENSION' +OID_FEATURE = 'FEATURE' +OID_UNSOLICITED_NOTICE = 'UNSOLICITED_NOTICE' +OID_ATTRIBUTE_TYPE = 'ATTRIBUTE_TYPE' +OID_DIT_CONTENT_RULE = 'DIT_CONTENT_RULE' +OID_LDAP_URL_EXTENSION = 'LDAP_URL_EXTENSION' +OID_FAMILY = 'FAMILY' +OID_MATCHING_RULE = 'MATCHING_RULE' +OID_NAME_FORM = 'NAME_FORM' +OID_OBJECT_CLASS = 'OBJECT_CLASS' +OID_ADMINISTRATIVE_ROLE = 'ADMINISTRATIVE_ROLE' +OID_LDAP_SYNTAX = 'LDAP_SYNTAX' + +# class kind +CLASS_STRUCTURAL = 'STRUCTURAL' +CLASS_ABSTRACT = 'ABSTRACT' +CLASS_AUXILIARY = 'AUXILIARY' + +# attribute kind +ATTRIBUTE_USER_APPLICATION = 'USER_APPLICATION' +ATTRIBUTE_DIRECTORY_OPERATION = 'DIRECTORY_OPERATION' +ATTRIBUTE_DISTRIBUTED_OPERATION = 'DISTRIBUTED_OPERATION' +ATTRIBUTE_DSA_OPERATION = 'DSA_OPERATION' + + +def constant_to_oid_kind(oid_kind): + if oid_kind == OID_CONTROL: + return 'Control' + elif oid_kind == OID_EXTENSION: + return 'Extension' + elif oid_kind == OID_FEATURE: + return 'Feature' + elif oid_kind == OID_UNSOLICITED_NOTICE: + return 'Unsolicited Notice' + elif oid_kind == OID_ATTRIBUTE_TYPE: + return 'Attribute Type' + elif oid_kind == OID_DIT_CONTENT_RULE: + return 'DIT Content Rule' + elif oid_kind == OID_LDAP_URL_EXTENSION: + return 'LDAP URL Extension' + elif oid_kind == OID_FAMILY: + return 'Family' + elif oid_kind == OID_MATCHING_RULE: + return 'Matching Rule' + elif oid_kind == OID_NAME_FORM: + return 'Name Form' + elif oid_kind == OID_OBJECT_CLASS: + return 'Object Class' + elif oid_kind == OID_ADMINISTRATIVE_ROLE: + return 'Administrative Role' + elif oid_kind == OID_LDAP_SYNTAX: + return 'LDAP Syntax' + else: + return 'Unknown' + + +def decode_oids(sequence): + if sequence: + return sorted([Oids.get(oid, (oid, None, None, None)) for oid in sequence if oid]) + return list() + + +def decode_syntax(syntax): + if not syntax: + return None + return Oids.get(syntax, None) + + +def oid_to_string(oid): + s = oid[0] + if oid[2]: + s += ' - ' + ((', '.join(oid[2])) if isinstance(oid[2], SEQUENCE_TYPES) else oid[2]) + s += (' - ' + constant_to_oid_kind(oid[1])) if oid[1] is not None else '' + s += (' - ' + oid[3]) if oid[3] else '' + + return s + +# tuple structure: (oid, kind, name, docs) + +# noinspection PyPep8 +Oids = { # administrative role + '2.5.23.1': ('2.5.23.1', OID_ADMINISTRATIVE_ROLE, 'autonomousArea', 'RFC3672'), + '2.5.23.2': ('2.5.23.2', OID_ADMINISTRATIVE_ROLE, 'accessControlSpecificArea', 'RFC3672'), + '2.5.23.3': ('2.5.23.3', OID_ADMINISTRATIVE_ROLE, 'accessControlInnerArea', 'RFC3672'), + '2.5.23.4': ('2.5.23.4', OID_ADMINISTRATIVE_ROLE, 'subschemaAdminSpecificArea', 'RFC3672'), + '2.5.23.5': ('2.5.23.5', OID_ADMINISTRATIVE_ROLE, 'collectiveAttributeSpecificArea', 'RFC3672'), + '2.5.23.6': ('2.5.23.6', OID_ADMINISTRATIVE_ROLE, 'collectiveAttributeInnerArea', 'RFC3672'), + + # attributes type + '0.9.2342.19200300.100.1.1': ('0.9.2342.19200300.100.1.1', OID_ATTRIBUTE_TYPE, ['uid', 'userId'], 'RFC4519'), + '0.9.2342.19200300.100.1.2': ('0.9.2342.19200300.100.1.2', OID_ATTRIBUTE_TYPE, 'textEncodedORAddress', 'RFC1274'), + '0.9.2342.19200300.100.1.3': ('0.9.2342.19200300.100.1.3', OID_ATTRIBUTE_TYPE, ['mail', 'RFC822Mailbox'], 'RFC4524'), + '0.9.2342.19200300.100.1.4': ('0.9.2342.19200300.100.1.4', OID_ATTRIBUTE_TYPE, 'info', 'RFC4524'), + '0.9.2342.19200300.100.1.5': ('0.9.2342.19200300.100.1.5', OID_ATTRIBUTE_TYPE, ['drink', 'favouriteDrink'], 'RFC4524'), + '0.9.2342.19200300.100.1.6': ('0.9.2342.19200300.100.1.6', OID_ATTRIBUTE_TYPE, 'roomNumber', 'RFC4524'), + '0.9.2342.19200300.100.1.7': ('0.9.2342.19200300.100.1.7', OID_ATTRIBUTE_TYPE, 'photo', 'RFC1274'), + '0.9.2342.19200300.100.1.8': ('0.9.2342.19200300.100.1.8', OID_ATTRIBUTE_TYPE, 'userClass', 'RFC4524'), + '0.9.2342.19200300.100.1.9': ('0.9.2342.19200300.100.1.9', OID_ATTRIBUTE_TYPE, 'host', 'RFC4524'), + '0.9.2342.19200300.100.1.10': ('0.9.2342.19200300.100.1.10', OID_ATTRIBUTE_TYPE, 'manager', 'RFC4524'), + '0.9.2342.19200300.100.1.11': ('0.9.2342.19200300.100.1.11', OID_ATTRIBUTE_TYPE, 'documentIdentifier', 'RFC4524'), + '0.9.2342.19200300.100.1.12': ('0.9.2342.19200300.100.1.12', OID_ATTRIBUTE_TYPE, 'documentTitle', 'RFC4524'), + '0.9.2342.19200300.100.1.13': ('0.9.2342.19200300.100.1.13', OID_ATTRIBUTE_TYPE, 'documentVersion', 'RFC4524'), + '0.9.2342.19200300.100.1.14': ('0.9.2342.19200300.100.1.14', OID_ATTRIBUTE_TYPE, 'documentAuthor', 'RFC4524'), + '0.9.2342.19200300.100.1.15': ('0.9.2342.19200300.100.1.15', OID_ATTRIBUTE_TYPE, 'documentLocation', 'RFC4524'), + '0.9.2342.19200300.100.1.20': ('0.9.2342.19200300.100.1.20', OID_ATTRIBUTE_TYPE, ['homePhone', 'homeTelephone'], 'RFC4524'), + '0.9.2342.19200300.100.1.21': ('0.9.2342.19200300.100.1.21', OID_ATTRIBUTE_TYPE, 'secretary', 'RFC4524'), + '0.9.2342.19200300.100.1.22': ('0.9.2342.19200300.100.1.22', OID_ATTRIBUTE_TYPE, 'otherMailbox', 'RFC1274'), + '0.9.2342.19200300.100.1.23': ('0.9.2342.19200300.100.1.23', OID_ATTRIBUTE_TYPE, 'lastModifiedTime', 'RFC1274'), + '0.9.2342.19200300.100.1.24': ('0.9.2342.19200300.100.1.24', OID_ATTRIBUTE_TYPE, 'lastModifiedBy', 'RFC1274'), + '0.9.2342.19200300.100.1.25': ('0.9.2342.19200300.100.1.25', OID_ATTRIBUTE_TYPE, ['DC', 'domainComponent'], 'RFC4519'), + '0.9.2342.19200300.100.1.26': ('0.9.2342.19200300.100.1.26', OID_ATTRIBUTE_TYPE, 'aRecord', 'RFC1274'), + '0.9.2342.19200300.100.1.27': ('0.9.2342.19200300.100.1.27', OID_ATTRIBUTE_TYPE, 'mDRecord', 'RFC1274'), + '0.9.2342.19200300.100.1.28': ('0.9.2342.19200300.100.1.28', OID_ATTRIBUTE_TYPE, 'mXRecord', 'RFC1274'), + '0.9.2342.19200300.100.1.29': ('0.9.2342.19200300.100.1.29', OID_ATTRIBUTE_TYPE, 'nSRecord', 'RFC1274'), + '0.9.2342.19200300.100.1.30': ('0.9.2342.19200300.100.1.30', OID_ATTRIBUTE_TYPE, 'sOARecord', 'RFC1274'), + '0.9.2342.19200300.100.1.31': ('0.9.2342.19200300.100.1.31', OID_ATTRIBUTE_TYPE, 'cNAMERecord', 'RFC1274'), + '0.9.2342.19200300.100.1.37': ('0.9.2342.19200300.100.1.37', OID_ATTRIBUTE_TYPE, 'associatedDomain', 'RFC4524'), + '0.9.2342.19200300.100.1.38': ('0.9.2342.19200300.100.1.38', OID_ATTRIBUTE_TYPE, 'associatedName', 'RFC4524'), + '0.9.2342.19200300.100.1.39': ('0.9.2342.19200300.100.1.39', OID_ATTRIBUTE_TYPE, 'homePostalAddress', 'RFC4524'), + '0.9.2342.19200300.100.1.40': ('0.9.2342.19200300.100.1.40', OID_ATTRIBUTE_TYPE, 'personalTitle', 'RFC4524'), + '0.9.2342.19200300.100.1.41': ('0.9.2342.19200300.100.1.41', OID_ATTRIBUTE_TYPE, ['mobile', 'mobileTelephoneNumber'], 'RFC4524'), + '0.9.2342.19200300.100.1.42': ('0.9.2342.19200300.100.1.42', OID_ATTRIBUTE_TYPE, ['pager', 'pagerTelephoneNumber'], 'RFC4524'), + '0.9.2342.19200300.100.1.43': ('0.9.2342.19200300.100.1.43', OID_ATTRIBUTE_TYPE, ['co', 'friendlyCountryName'], 'RFC4524'), + '0.9.2342.19200300.100.1.44': ('0.9.2342.19200300.100.1.44', OID_ATTRIBUTE_TYPE, 'uniqueIdentifier', 'RFC4524'), + '0.9.2342.19200300.100.1.45': ('0.9.2342.19200300.100.1.45', OID_ATTRIBUTE_TYPE, 'organizationalStatus', 'RFC4524'), + '0.9.2342.19200300.100.1.46': ('0.9.2342.19200300.100.1.46', OID_ATTRIBUTE_TYPE, 'janetMailbox', 'RFC1274'), + '0.9.2342.19200300.100.1.47': ('0.9.2342.19200300.100.1.47', OID_ATTRIBUTE_TYPE, 'mailPreferenceOption', 'RFC1274'), + '0.9.2342.19200300.100.1.48': ('0.9.2342.19200300.100.1.48', OID_ATTRIBUTE_TYPE, 'buildingName', 'RFC4524'), + '0.9.2342.19200300.100.1.49': ('0.9.2342.19200300.100.1.49', OID_ATTRIBUTE_TYPE, 'dSAQuality', 'RFC1274'), + '0.9.2342.19200300.100.1.50': ('0.9.2342.19200300.100.1.50', OID_ATTRIBUTE_TYPE, 'singleLevelQuality', 'RFC4524'), + '0.9.2342.19200300.100.1.51': ('0.9.2342.19200300.100.1.51', OID_ATTRIBUTE_TYPE, 'subtreeMinimumQuality', 'RFC1274'), + '0.9.2342.19200300.100.1.52': ('0.9.2342.19200300.100.1.52', OID_ATTRIBUTE_TYPE, 'subtreeMaximumQuality', 'RFC1274'), + '0.9.2342.19200300.100.1.53': ('0.9.2342.19200300.100.1.53', OID_ATTRIBUTE_TYPE, 'personalSignature', 'RFC1274'), + '0.9.2342.19200300.100.1.54': ('0.9.2342.19200300.100.1.54', OID_ATTRIBUTE_TYPE, 'dITRedirect', 'RFC1274'), + '0.9.2342.19200300.100.1.55': ('0.9.2342.19200300.100.1.55', OID_ATTRIBUTE_TYPE, 'audio', 'RFC1274'), + '0.9.2342.19200300.100.1.56': ('0.9.2342.19200300.100.1.56', OID_ATTRIBUTE_TYPE, 'documentPublisher', 'RFC4524'), + '0.9.2342.19200300.100.1.60': ('0.9.2342.19200300.100.1.60', OID_ATTRIBUTE_TYPE, 'jpegPhoto', 'RFC2798'), + '1.2.840.113549.1.9.1': ('1.2.840.113549.1.9.1', OID_ATTRIBUTE_TYPE, ['email', 'emailAddress'], 'RFC3280'), + '1.2.840.113556.1.4.478': ('1.2.840.113556.1.4.478', OID_ATTRIBUTE_TYPE, 'calCalURI', 'RFC2739'), + '1.2.840.113556.1.4.479': ('1.2.840.113556.1.4.479', OID_ATTRIBUTE_TYPE, 'calFBURL', 'RFC2739'), + '1.2.840.113556.1.4.480': ('1.2.840.113556.1.4.480', OID_ATTRIBUTE_TYPE, 'calCAPURI', 'RFC2739'), + '1.2.840.113556.1.4.481': ('1.2.840.113556.1.4.481', OID_ATTRIBUTE_TYPE, 'calCalAdrURI', 'RFC2739'), + '1.2.840.113556.1.4.482': ('1.2.840.113556.1.4.482', OID_ATTRIBUTE_TYPE, 'calOtherCalURIs', 'RFC2739'), + '1.2.840.113556.1.4.483': ('1.2.840.113556.1.4.483', OID_ATTRIBUTE_TYPE, 'calOtherFBURLs', 'RFC2739'), + '1.2.840.113556.1.4.484': ('1.2.840.113556.1.4.484', OID_ATTRIBUTE_TYPE, 'calOtherCAPURIs', 'RFC2739'), + '1.2.840.113556.1.4.485': ('1.2.840.113556.1.4.485', OID_ATTRIBUTE_TYPE, 'calOtherCalAdrURIs', 'RFC2739'), + '1.3.18.0.2.4.1107': ('1.3.18.0.2.4.1107', OID_ATTRIBUTE_TYPE, 'printer-xri-supported', 'RFC3712'), + '1.3.18.0.2.4.1108': ('1.3.18.0.2.4.1108', OID_ATTRIBUTE_TYPE, 'printer-aliases', 'RFC3712'), + '1.3.18.0.2.4.1109': ('1.3.18.0.2.4.1109', OID_ATTRIBUTE_TYPE, 'printer-charset-configured', 'RFC3712'), + '1.3.18.0.2.4.1110': ('1.3.18.0.2.4.1110', OID_ATTRIBUTE_TYPE, 'printer-job-priority-supported', 'RFC3712'), + '1.3.18.0.2.4.1111': ('1.3.18.0.2.4.1111', OID_ATTRIBUTE_TYPE, 'printer-job-k-octets-supported', 'RFC3712'), + '1.3.18.0.2.4.1112': ('1.3.18.0.2.4.1112', OID_ATTRIBUTE_TYPE, 'printer-current-operator', 'RFC3712'), + '1.3.18.0.2.4.1113': ('1.3.18.0.2.4.1113', OID_ATTRIBUTE_TYPE, 'printer-service-person', 'RFC3712'), + '1.3.18.0.2.4.1114': ('1.3.18.0.2.4.1114', OID_ATTRIBUTE_TYPE, 'printer-delivery-orientation-supported', 'RFC3712'), + '1.3.18.0.2.4.1115': ('1.3.18.0.2.4.1115', OID_ATTRIBUTE_TYPE, 'printer-stacking-order-supported', 'RFC3712'), + '1.3.18.0.2.4.1116': ('1.3.18.0.2.4.1116', OID_ATTRIBUTE_TYPE, 'printer-output-features-supported', 'RFC3712'), + '1.3.18.0.2.4.1117': ('1.3.18.0.2.4.1117', OID_ATTRIBUTE_TYPE, 'printer-media-local-supported', 'RFC3712'), + '1.3.18.0.2.4.1118': ('1.3.18.0.2.4.1118', OID_ATTRIBUTE_TYPE, 'printer-copies-supported', 'RFC3712'), + '1.3.18.0.2.4.1119': ('1.3.18.0.2.4.1119', OID_ATTRIBUTE_TYPE, 'printer-natural-language-configured', 'RFC3712'), + '1.3.18.0.2.4.1120': ('1.3.18.0.2.4.1120', OID_ATTRIBUTE_TYPE, 'printer-print-quality-supported', 'RFC3712'), + '1.3.18.0.2.4.1121': ('1.3.18.0.2.4.1121', OID_ATTRIBUTE_TYPE, 'printer-resolution-supported', 'RFC3712'), + '1.3.18.0.2.4.1122': ('1.3.18.0.2.4.1122', OID_ATTRIBUTE_TYPE, 'printer-media-supported', 'RFC3712'), + '1.3.18.0.2.4.1123': ('1.3.18.0.2.4.1123', OID_ATTRIBUTE_TYPE, 'printer-sides-supported', 'RFC3712'), + '1.3.18.0.2.4.1124': ('1.3.18.0.2.4.1124', OID_ATTRIBUTE_TYPE, 'printer-number-up-supported', 'RFC3712'), + '1.3.18.0.2.4.1125': ('1.3.18.0.2.4.1125', OID_ATTRIBUTE_TYPE, 'printer-finishings-supported', 'RFC3712'), + '1.3.18.0.2.4.1126': ('1.3.18.0.2.4.1126', OID_ATTRIBUTE_TYPE, 'printer-pages-per-minute-color', 'RFC3712'), + '1.3.18.0.2.4.1127': ('1.3.18.0.2.4.1127', OID_ATTRIBUTE_TYPE, 'printer-pages-per-minute', 'RFC3712'), + '1.3.18.0.2.4.1128': ('1.3.18.0.2.4.1128', OID_ATTRIBUTE_TYPE, 'printer-compression-supported', 'RFC3712'), + '1.3.18.0.2.4.1129': ('1.3.18.0.2.4.1129', OID_ATTRIBUTE_TYPE, 'printer-color-supported', 'RFC3712'), + '1.3.18.0.2.4.1130': ('1.3.18.0.2.4.1130', OID_ATTRIBUTE_TYPE, 'printer-document-format-supported', 'RFC3712'), + '1.3.18.0.2.4.1131': ('1.3.18.0.2.4.1131', OID_ATTRIBUTE_TYPE, 'printer-charset-supported', 'RFC3712'), + '1.3.18.0.2.4.1132': ('1.3.18.0.2.4.1132', OID_ATTRIBUTE_TYPE, 'printer-multiple-document-jobs-supported', 'RFC3712'), + '1.3.18.0.2.4.1133': ('1.3.18.0.2.4.1133', OID_ATTRIBUTE_TYPE, 'printer-ipp-versions-supported', 'RFC3712'), + '1.3.18.0.2.4.1134': ('1.3.18.0.2.4.1134', OID_ATTRIBUTE_TYPE, 'printer-more-info', 'RFC3712'), + '1.3.18.0.2.4.1135': ('1.3.18.0.2.4.1135', OID_ATTRIBUTE_TYPE, 'printer-name', 'RFC3712'), + '1.3.18.0.2.4.1136': ('1.3.18.0.2.4.1136', OID_ATTRIBUTE_TYPE, 'printer-location', 'RFC3712'), + '1.3.18.0.2.4.1137': ('1.3.18.0.2.4.1137', OID_ATTRIBUTE_TYPE, 'printer-generated-natural-language-supported', 'RFC3712'), + '1.3.18.0.2.4.1138': ('1.3.18.0.2.4.1138', OID_ATTRIBUTE_TYPE, 'printer-make-and-model', 'RFC3712'), + '1.3.18.0.2.4.1139': ('1.3.18.0.2.4.1139', OID_ATTRIBUTE_TYPE, 'printer-info', 'RFC3712'), + '1.3.18.0.2.4.1140': ('1.3.18.0.2.4.1140', OID_ATTRIBUTE_TYPE, 'printer-uri', 'RFC3712'), + '1.3.6.1.1.10.4.1': ('1.3.6.1.1.10.4.1', OID_ATTRIBUTE_TYPE, 'uddiBusinessKey', 'RFC4403'), + '1.3.6.1.1.10.4.2': ('1.3.6.1.1.10.4.2', OID_ATTRIBUTE_TYPE, 'uddiAuthorizedName', 'RFC4403'), + '1.3.6.1.1.10.4.3': ('1.3.6.1.1.10.4.3', OID_ATTRIBUTE_TYPE, 'uddiOperator', 'RFC4403'), + '1.3.6.1.1.10.4.4': ('1.3.6.1.1.10.4.4', OID_ATTRIBUTE_TYPE, 'uddiName', 'RFC4403'), + '1.3.6.1.1.10.4.5': ('1.3.6.1.1.10.4.5', OID_ATTRIBUTE_TYPE, 'uddiDescription', 'RFC4403'), + '1.3.6.1.1.10.4.6': ('1.3.6.1.1.10.4.6', OID_ATTRIBUTE_TYPE, 'uddiDiscoveryURLs', 'RFC4403'), + '1.3.6.1.1.10.4.7': ('1.3.6.1.1.10.4.7', OID_ATTRIBUTE_TYPE, 'uddiUseType', 'RFC4403'), + '1.3.6.1.1.10.4.8': ('1.3.6.1.1.10.4.8', OID_ATTRIBUTE_TYPE, 'uddiPersonName', 'RFC4403'), + '1.3.6.1.1.10.4.9': ('1.3.6.1.1.10.4.9', OID_ATTRIBUTE_TYPE, 'uddiPhone', 'RFC4403'), + '1.3.6.1.1.10.4.10': ('1.3.6.1.1.10.4.10', OID_ATTRIBUTE_TYPE, 'uddiEMail', 'RFC4403'), + '1.3.6.1.1.10.4.11': ('1.3.6.1.1.10.4.11', OID_ATTRIBUTE_TYPE, 'uddiSortCode', 'RFC4403'), + '1.3.6.1.1.10.4.12': ('1.3.6.1.1.10.4.12', OID_ATTRIBUTE_TYPE, 'uddiTModelKey', 'RFC4403'), + '1.3.6.1.1.10.4.13': ('1.3.6.1.1.10.4.13', OID_ATTRIBUTE_TYPE, 'uddiAddressLine', 'RFC4403'), + '1.3.6.1.1.10.4.14': ('1.3.6.1.1.10.4.14', OID_ATTRIBUTE_TYPE, 'uddiIdentifierBag', 'RFC4403'), + '1.3.6.1.1.10.4.15': ('1.3.6.1.1.10.4.15', OID_ATTRIBUTE_TYPE, 'uddiCategoryBag', 'RFC4403'), + '1.3.6.1.1.10.4.16': ('1.3.6.1.1.10.4.16', OID_ATTRIBUTE_TYPE, 'uddiKeyedReference', 'RFC4403'), + '1.3.6.1.1.10.4.17': ('1.3.6.1.1.10.4.17', OID_ATTRIBUTE_TYPE, 'uddiServiceKey', 'RFC4403'), + '1.3.6.1.1.10.4.18': ('1.3.6.1.1.10.4.18', OID_ATTRIBUTE_TYPE, 'uddiBindingKey', 'RFC4403'), + '1.3.6.1.1.10.4.19': ('1.3.6.1.1.10.4.19', OID_ATTRIBUTE_TYPE, 'uddiAccessPoint', 'RFC4403'), + '1.3.6.1.1.10.4.20': ('1.3.6.1.1.10.4.20', OID_ATTRIBUTE_TYPE, 'uddiHostingRedirector', 'RFC4403'), + '1.3.6.1.1.10.4.21': ('1.3.6.1.1.10.4.21', OID_ATTRIBUTE_TYPE, 'uddiInstanceDescription', 'RFC4403'), + '1.3.6.1.1.10.4.22': ('1.3.6.1.1.10.4.22', OID_ATTRIBUTE_TYPE, 'uddiInstanceParms', 'RFC4403'), + '1.3.6.1.1.10.4.23': ('1.3.6.1.1.10.4.23', OID_ATTRIBUTE_TYPE, 'uddiOverviewDescription', 'RFC4403'), + '1.3.6.1.1.10.4.24': ('1.3.6.1.1.10.4.24', OID_ATTRIBUTE_TYPE, 'uddiOverviewURL', 'RFC4403'), + '1.3.6.1.1.10.4.25': ('1.3.6.1.1.10.4.25', OID_ATTRIBUTE_TYPE, 'uddiFromKey', 'RFC4403'), + '1.3.6.1.1.10.4.26': ('1.3.6.1.1.10.4.26', OID_ATTRIBUTE_TYPE, 'uddiToKey', 'RFC4403'), + '1.3.6.1.1.10.4.27': ('1.3.6.1.1.10.4.27', OID_ATTRIBUTE_TYPE, 'uddiUUID', 'RFC4403'), + '1.3.6.1.1.10.4.28': ('1.3.6.1.1.10.4.28', OID_ATTRIBUTE_TYPE, 'uddiIsHidden', 'RFC4403'), + '1.3.6.1.1.10.4.29': ('1.3.6.1.1.10.4.29', OID_ATTRIBUTE_TYPE, 'uddiIsProjection', 'RFC4403'), + '1.3.6.1.1.10.4.30': ('1.3.6.1.1.10.4.30', OID_ATTRIBUTE_TYPE, 'uddiLang', 'RFC4403'), + '1.3.6.1.1.10.4.31': ('1.3.6.1.1.10.4.31', OID_ATTRIBUTE_TYPE, 'uddiv3BusinessKey', 'RFC4403'), + '1.3.6.1.1.10.4.32': ('1.3.6.1.1.10.4.32', OID_ATTRIBUTE_TYPE, 'uddiv3ServiceKey', 'RFC4403'), + '1.3.6.1.1.10.4.33': ('1.3.6.1.1.10.4.33', OID_ATTRIBUTE_TYPE, 'uddiv3BindingKey', 'RFC4403'), + '1.3.6.1.1.10.4.34': ('1.3.6.1.1.10.4.34', OID_ATTRIBUTE_TYPE, 'uddiv3TmodelKey', 'RFC4403'), + '1.3.6.1.1.10.4.35': ('1.3.6.1.1.10.4.35', OID_ATTRIBUTE_TYPE, 'uddiv3DigitalSignature', 'RFC4403'), + '1.3.6.1.1.10.4.36': ('1.3.6.1.1.10.4.36', OID_ATTRIBUTE_TYPE, 'uddiv3NodeId', 'RFC4403'), + '1.3.6.1.1.10.4.37': ('1.3.6.1.1.10.4.37', OID_ATTRIBUTE_TYPE, 'uddiv3EntityModificationTime', 'RFC4403'), + '1.3.6.1.1.10.4.38': ('1.3.6.1.1.10.4.38', OID_ATTRIBUTE_TYPE, 'uddiv3SubscriptionKey', 'RFC4403'), + '1.3.6.1.1.10.4.39': ('1.3.6.1.1.10.4.39', OID_ATTRIBUTE_TYPE, 'uddiv3SubscriptionFilter', 'RFC4403'), + '1.3.6.1.1.10.4.40': ('1.3.6.1.1.10.4.40', OID_ATTRIBUTE_TYPE, 'uddiv3NotificationInterval', 'RFC4403'), + '1.3.6.1.1.10.4.41': ('1.3.6.1.1.10.4.41', OID_ATTRIBUTE_TYPE, 'uddiv3MaxEntities', 'RFC4403'), + '1.3.6.1.1.10.4.42': ('1.3.6.1.1.10.4.42', OID_ATTRIBUTE_TYPE, 'uddiv3ExpiresAfter', 'RFC4403'), + '1.3.6.1.1.10.4.43': ('1.3.6.1.1.10.4.43', OID_ATTRIBUTE_TYPE, 'uddiv3BriefResponse', 'RFC4403'), + '1.3.6.1.1.10.4.44': ('1.3.6.1.1.10.4.44', OID_ATTRIBUTE_TYPE, 'uddiv3EntityKey', 'RFC4403'), + '1.3.6.1.1.10.4.45': ('1.3.6.1.1.10.4.45', OID_ATTRIBUTE_TYPE, 'uddiv3EntityCreationTime', 'RFC4403'), + '1.3.6.1.1.10.4.46': ('1.3.6.1.1.10.4.46', OID_ATTRIBUTE_TYPE, 'uddiv3EntityDeletionTime', 'RFC4403'), + '1.3.6.1.1.11.2.1': ('1.3.6.1.1.11.2.1', OID_ATTRIBUTE_TYPE, 'vPIMTelephoneNumber', 'RFC4237'), + '1.3.6.1.1.11.2.2': ('1.3.6.1.1.11.2.2', OID_ATTRIBUTE_TYPE, 'vPIMRfc822Mailbox', 'RFC4237'), + '1.3.6.1.1.11.2.3': ('1.3.6.1.1.11.2.3', OID_ATTRIBUTE_TYPE, 'vPIMSpokenName', 'RFC4237'), + '1.3.6.1.1.11.2.4': ('1.3.6.1.1.11.2.4', OID_ATTRIBUTE_TYPE, 'vPIMSupportedUABehaviors', 'RFC4237'), + '1.3.6.1.1.11.2.5': ('1.3.6.1.1.11.2.5', OID_ATTRIBUTE_TYPE, 'vPIMSupportedAudioMediaTypes', 'RFC4237'), + '1.3.6.1.1.11.2.6': ('1.3.6.1.1.11.2.6', OID_ATTRIBUTE_TYPE, 'vPIMSupportedMessageContext', 'RFC4237'), + '1.3.6.1.1.11.2.7': ('1.3.6.1.1.11.2.7', OID_ATTRIBUTE_TYPE, 'vPIMTextName', 'RFC4237'), + '1.3.6.1.1.11.2.8': ('1.3.6.1.1.11.2.8', OID_ATTRIBUTE_TYPE, 'vPIMExtendedAbsenceStatus', 'RFC4237'), + '1.3.6.1.1.11.2.9': ('1.3.6.1.1.11.2.9', OID_ATTRIBUTE_TYPE, 'vPIMMaxMessageSize', 'RFC4237'), + '1.3.6.1.1.11.2.10': ('1.3.6.1.1.11.2.10', OID_ATTRIBUTE_TYPE, 'vPIMSubMailboxes', 'RFC4237'), + '1.3.6.1.1.16.4': ('1.3.6.1.1.16.4', OID_ATTRIBUTE_TYPE, 'entryUUID', 'RFC4530'), + '1.3.6.1.1.20': ('1.3.6.1.1.20', OID_ATTRIBUTE_TYPE, 'entryDN', 'RFC5020'), + '1.3.6.1.1.6.2.3': ('1.3.6.1.1.6.2.3', OID_ATTRIBUTE_TYPE, 'pcimKeywords', 'RFC3703'), + '1.3.6.1.1.6.2.4': ('1.3.6.1.1.6.2.4', OID_ATTRIBUTE_TYPE, 'pcimGroupName', 'RFC3703'), + '1.3.6.1.1.6.2.5': ('1.3.6.1.1.6.2.5', OID_ATTRIBUTE_TYPE, 'pcimRuleName', 'RFC3703'), + '1.3.6.1.1.6.2.6': ('1.3.6.1.1.6.2.6', OID_ATTRIBUTE_TYPE, 'pcimRuleEnabled', 'RFC3703'), + '1.3.6.1.1.6.2.7': ('1.3.6.1.1.6.2.7', OID_ATTRIBUTE_TYPE, 'pcimRuleConditionListType', 'RFC3703'), + '1.3.6.1.1.6.2.8': ('1.3.6.1.1.6.2.8', OID_ATTRIBUTE_TYPE, 'pcimRuleConditionList', 'RFC3703'), + '1.3.6.1.1.6.2.9': ('1.3.6.1.1.6.2.9', OID_ATTRIBUTE_TYPE, 'pcimRuleActionList', 'RFC3703'), + '1.3.6.1.1.6.2.10': ('1.3.6.1.1.6.2.10', OID_ATTRIBUTE_TYPE, 'pcimRuleValidityPeriodList', 'RFC3703'), + '1.3.6.1.1.6.2.11': ('1.3.6.1.1.6.2.11', OID_ATTRIBUTE_TYPE, 'pcimRuleUsage', 'RFC3703'), + '1.3.6.1.1.6.2.12': ('1.3.6.1.1.6.2.12', OID_ATTRIBUTE_TYPE, 'pcimRulePriority', 'RFC3703'), + '1.3.6.1.1.6.2.13': ('1.3.6.1.1.6.2.13', OID_ATTRIBUTE_TYPE, 'pcimRuleMandatory', 'RFC3703'), + '1.3.6.1.1.6.2.14': ('1.3.6.1.1.6.2.14', OID_ATTRIBUTE_TYPE, 'pcimRuleSequencedActions', 'RFC3703'), + '1.3.6.1.1.6.2.15': ('1.3.6.1.1.6.2.15', OID_ATTRIBUTE_TYPE, 'pcimRoles', 'RFC3703'), + '1.3.6.1.1.6.2.16': ('1.3.6.1.1.6.2.16', OID_ATTRIBUTE_TYPE, 'pcimConditionGroupNumber', 'RFC3703'), + '1.3.6.1.1.6.2.17': ('1.3.6.1.1.6.2.17', OID_ATTRIBUTE_TYPE, 'pcimConditionNegated', 'RFC3703'), + '1.3.6.1.1.6.2.18': ('1.3.6.1.1.6.2.18', OID_ATTRIBUTE_TYPE, 'pcimConditionName', 'RFC3703'), + '1.3.6.1.1.6.2.19': ('1.3.6.1.1.6.2.19', OID_ATTRIBUTE_TYPE, 'pcimConditionDN', 'RFC3703'), + '1.3.6.1.1.6.2.20': ('1.3.6.1.1.6.2.20', OID_ATTRIBUTE_TYPE, 'pcimValidityConditionName', 'RFC3703'), + '1.3.6.1.1.6.2.21': ('1.3.6.1.1.6.2.21', OID_ATTRIBUTE_TYPE, 'pcimTimePeriodConditionDN', 'RFC3703'), + '1.3.6.1.1.6.2.22': ('1.3.6.1.1.6.2.22', OID_ATTRIBUTE_TYPE, 'pcimActionName', 'RFC3703'), + '1.3.6.1.1.6.2.23': ('1.3.6.1.1.6.2.23', OID_ATTRIBUTE_TYPE, 'pcimActionOrder', 'RFC3703'), + '1.3.6.1.1.6.2.24': ('1.3.6.1.1.6.2.24', OID_ATTRIBUTE_TYPE, 'pcimActionDN', 'RFC3703'), + '1.3.6.1.1.6.2.25': ('1.3.6.1.1.6.2.25', OID_ATTRIBUTE_TYPE, 'pcimTPCTime', 'RFC3703'), + '1.3.6.1.1.6.2.26': ('1.3.6.1.1.6.2.26', OID_ATTRIBUTE_TYPE, 'pcimTPCMonthOfYearMask', 'RFC3703'), + '1.3.6.1.1.6.2.27': ('1.3.6.1.1.6.2.27', OID_ATTRIBUTE_TYPE, 'pcimTPCDayOfMonthMask', 'RFC3703'), + '1.3.6.1.1.6.2.28': ('1.3.6.1.1.6.2.28', OID_ATTRIBUTE_TYPE, 'pcimTPCDayOfWeekMask', 'RFC3703'), + '1.3.6.1.1.6.2.29': ('1.3.6.1.1.6.2.29', OID_ATTRIBUTE_TYPE, 'pcimTPCTimeOfDayMask', 'RFC3703'), + '1.3.6.1.1.6.2.30': ('1.3.6.1.1.6.2.30', OID_ATTRIBUTE_TYPE, 'pcimTPCLocalOrUtcTime', 'RFC3703'), + '1.3.6.1.1.6.2.31': ('1.3.6.1.1.6.2.31', OID_ATTRIBUTE_TYPE, 'pcimVendorConstraintData', 'RFC3703'), + '1.3.6.1.1.6.2.32': ('1.3.6.1.1.6.2.32', OID_ATTRIBUTE_TYPE, 'pcimVendorConstraintEncoding', 'RFC3703'), + '1.3.6.1.1.6.2.33': ('1.3.6.1.1.6.2.33', OID_ATTRIBUTE_TYPE, 'pcimVendorActionData', 'RFC3703'), + '1.3.6.1.1.6.2.34': ('1.3.6.1.1.6.2.34', OID_ATTRIBUTE_TYPE, 'pcimVendorActionEncoding', 'RFC3703'), + '1.3.6.1.1.6.2.35': ('1.3.6.1.1.6.2.35', OID_ATTRIBUTE_TYPE, 'pcimPolicyInstanceName', 'RFC3703'), + '1.3.6.1.1.6.2.36': ('1.3.6.1.1.6.2.36', OID_ATTRIBUTE_TYPE, 'pcimRepositoryName', 'RFC3703'), + '1.3.6.1.1.6.2.37': ('1.3.6.1.1.6.2.37', OID_ATTRIBUTE_TYPE, 'pcimSubtreesAuxContainedSet', 'RFC3703'), + '1.3.6.1.1.6.2.38': ('1.3.6.1.1.6.2.38', OID_ATTRIBUTE_TYPE, 'pcimGroupsAuxContainedSet', 'RFC3703'), + '1.3.6.1.1.6.2.39': ('1.3.6.1.1.6.2.39', OID_ATTRIBUTE_TYPE, 'pcimRulesAuxContainedSet', 'RFC3703'), + '1.3.6.1.1.9.2.1': ('1.3.6.1.1.9.2.1', OID_ATTRIBUTE_TYPE, 'pcelsPolicySetName', 'RFC4104'), + '1.3.6.1.1.9.2.2': ('1.3.6.1.1.9.2.2', OID_ATTRIBUTE_TYPE, 'pcelsDecisionStrategy', 'RFC4104'), + '1.3.6.1.1.9.2.3': ('1.3.6.1.1.9.2.3', OID_ATTRIBUTE_TYPE, 'pcelsPolicySetList', 'RFC4104'), + '1.3.6.1.1.9.2.4': ('1.3.6.1.1.9.2.4', OID_ATTRIBUTE_TYPE, 'pcelsPriority', 'RFC4104'), + '1.3.6.1.1.9.2.5': ('1.3.6.1.1.9.2.5', OID_ATTRIBUTE_TYPE, 'pcelsPolicySetDN', 'RFC4104'), + '1.3.6.1.1.9.2.6': ('1.3.6.1.1.9.2.6', OID_ATTRIBUTE_TYPE, 'pcelsConditionListType', 'RFC4104'), + '1.3.6.1.1.9.2.7': ('1.3.6.1.1.9.2.7', OID_ATTRIBUTE_TYPE, 'pcelsConditionList', 'RFC4104'), + '1.3.6.1.1.9.2.8': ('1.3.6.1.1.9.2.8', OID_ATTRIBUTE_TYPE, 'pcelsActionList', 'RFC4104'), + '1.3.6.1.1.9.2.9': ('1.3.6.1.1.9.2.9', OID_ATTRIBUTE_TYPE, 'pcelsSequencedActions', 'RFC4104'), + '1.3.6.1.1.9.2.10': ('1.3.6.1.1.9.2.10', OID_ATTRIBUTE_TYPE, 'pcelsExecutionStrategy', 'RFC4104'), + '1.3.6.1.1.9.2.11': ('1.3.6.1.1.9.2.11', OID_ATTRIBUTE_TYPE, 'pcelsVariableDN', 'RFC4104'), + '1.3.6.1.1.9.2.12': ('1.3.6.1.1.9.2.12', OID_ATTRIBUTE_TYPE, 'pcelsValueDN', 'RFC4104'), + '1.3.6.1.1.9.2.13': ('1.3.6.1.1.9.2.13', OID_ATTRIBUTE_TYPE, 'pcelsIsMirrored', 'RFC4104'), + '1.3.6.1.1.9.2.14': ('1.3.6.1.1.9.2.14', OID_ATTRIBUTE_TYPE, 'pcelsVariableName', 'RFC4104'), + '1.3.6.1.1.9.2.15': ('1.3.6.1.1.9.2.15', OID_ATTRIBUTE_TYPE, 'pcelsExpectedValueList', 'RFC4104'), + '1.3.6.1.1.9.2.16': ('1.3.6.1.1.9.2.16', OID_ATTRIBUTE_TYPE, 'pcelsVariableModelClass', 'RFC4104'), + '1.3.6.1.1.9.2.17': ('1.3.6.1.1.9.2.17', OID_ATTRIBUTE_TYPE, 'pcelsVariableModelProperty', 'RFC4104'), + '1.3.6.1.1.9.2.18': ('1.3.6.1.1.9.2.18', OID_ATTRIBUTE_TYPE, 'pcelsExpectedValueTypes', 'RFC4104'), + '1.3.6.1.1.9.2.19': ('1.3.6.1.1.9.2.19', OID_ATTRIBUTE_TYPE, 'pcelsValueName', 'RFC4104'), + '1.3.6.1.1.9.2.20': ('1.3.6.1.1.9.2.20', OID_ATTRIBUTE_TYPE, 'pcelsIPv4AddrList', 'RFC4104'), + '1.3.6.1.1.9.2.21': ('1.3.6.1.1.9.2.21', OID_ATTRIBUTE_TYPE, 'pcelsIPv6AddrList', 'RFC4104'), + '1.3.6.1.1.9.2.22': ('1.3.6.1.1.9.2.22', OID_ATTRIBUTE_TYPE, 'pcelsMACAddrList', 'RFC4104'), + '1.3.6.1.1.9.2.23': ('1.3.6.1.1.9.2.23', OID_ATTRIBUTE_TYPE, 'pcelsStringList', 'RFC4104'), + '1.3.6.1.1.9.2.24': ('1.3.6.1.1.9.2.24', OID_ATTRIBUTE_TYPE, 'pcelsBitStringList', 'RFC4104'), + '1.3.6.1.1.9.2.25': ('1.3.6.1.1.9.2.25', OID_ATTRIBUTE_TYPE, 'pcelsIntegerList', 'RFC4104'), + '1.3.6.1.1.9.2.26': ('1.3.6.1.1.9.2.26', OID_ATTRIBUTE_TYPE, 'pcelsBoolean', 'RFC4104'), + '1.3.6.1.1.9.2.27': ('1.3.6.1.1.9.2.27', OID_ATTRIBUTE_TYPE, 'pcelsReusableContainerName', 'RFC4104'), + '1.3.6.1.1.9.2.28': ('1.3.6.1.1.9.2.28', OID_ATTRIBUTE_TYPE, 'pcelsReusableContainerList', 'RFC4104'), + '1.3.6.1.1.9.2.29': ('1.3.6.1.1.9.2.29', OID_ATTRIBUTE_TYPE, 'pcelsRole', 'RFC4104'), + '1.3.6.1.1.9.2.30': ('1.3.6.1.1.9.2.30', OID_ATTRIBUTE_TYPE, 'pcelsRoleCollectionName', 'RFC4104'), + '1.3.6.1.1.9.2.31': ('1.3.6.1.1.9.2.31', OID_ATTRIBUTE_TYPE, 'pcelsElementList', 'RFC4104'), + '1.3.6.1.1.9.2.32': ('1.3.6.1.1.9.2.32', OID_ATTRIBUTE_TYPE, 'pcelsFilterName', 'RFC4104'), + '1.3.6.1.1.9.2.33': ('1.3.6.1.1.9.2.33', OID_ATTRIBUTE_TYPE, 'pcelsFilterIsNegated', 'RFC4104'), + '1.3.6.1.1.9.2.34': ('1.3.6.1.1.9.2.34', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrVersion', 'RFC4104'), + '1.3.6.1.1.9.2.35': ('1.3.6.1.1.9.2.35', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrSourceAddress', 'RFC4104'), + '1.3.6.1.1.9.2.36': ('1.3.6.1.1.9.2.36', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrSourceAddressEndOfRange', 'RFC4104'), + '1.3.6.1.1.9.2.37': ('1.3.6.1.1.9.2.37', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrSourceMask', 'RFC4104'), + '1.3.6.1.1.9.2.38': ('1.3.6.1.1.9.2.38', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDestAddress', 'RFC4104'), + '1.3.6.1.1.9.2.39': ('1.3.6.1.1.9.2.39', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDestAddressEndOfRange', 'RFC4104'), + '1.3.6.1.1.9.2.40': ('1.3.6.1.1.9.2.40', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDestMask', 'RFC4104'), + '1.3.6.1.1.9.2.41': ('1.3.6.1.1.9.2.41', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrProtocolID', 'RFC4104'), + '1.3.6.1.1.9.2.42': ('1.3.6.1.1.9.2.42', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrSourcePortStart', 'RFC4104'), + '1.3.6.1.1.9.2.43': ('1.3.6.1.1.9.2.43', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrSourcePortEnd', 'RFC4104'), + '1.3.6.1.1.9.2.44': ('1.3.6.1.1.9.2.44', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDestPortStart', 'RFC4104'), + '1.3.6.1.1.9.2.45': ('1.3.6.1.1.9.2.45', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDestPortEnd', 'RFC4104'), + '1.3.6.1.1.9.2.46': ('1.3.6.1.1.9.2.46', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrDSCPList', 'RFC4104'), + '1.3.6.1.1.9.2.47': ('1.3.6.1.1.9.2.47', OID_ATTRIBUTE_TYPE, 'pcelsIPHdrFlowLabel', 'RFC4104'), + '1.3.6.1.1.9.2.48': ('1.3.6.1.1.9.2.48', OID_ATTRIBUTE_TYPE, 'pcels8021HdrSourceMACAddress', 'RFC4104'), + '1.3.6.1.1.9.2.49': ('1.3.6.1.1.9.2.49', OID_ATTRIBUTE_TYPE, 'pcels8021HdrSourceMACMask', 'RFC4104'), + '1.3.6.1.1.9.2.50': ('1.3.6.1.1.9.2.50', OID_ATTRIBUTE_TYPE, 'pcels8021HdrDestMACAddress', 'RFC4104'), + '1.3.6.1.1.9.2.51': ('1.3.6.1.1.9.2.51', OID_ATTRIBUTE_TYPE, 'pcels8021HdrDestMACMask', 'RFC4104'), + '1.3.6.1.1.9.2.52': ('1.3.6.1.1.9.2.52', OID_ATTRIBUTE_TYPE, 'pcels8021HdrProtocolID', 'RFC4104'), + '1.3.6.1.1.9.2.53': ('1.3.6.1.1.9.2.53', OID_ATTRIBUTE_TYPE, 'pcels8021HdrPriority', 'RFC4104'), + '1.3.6.1.1.9.2.54': ('1.3.6.1.1.9.2.54', OID_ATTRIBUTE_TYPE, 'pcels8021HdrVLANID', 'RFC4104'), + '1.3.6.1.1.9.2.55': ('1.3.6.1.1.9.2.55', OID_ATTRIBUTE_TYPE, 'pcelsFilterListName', 'RFC4104'), + '1.3.6.1.1.9.2.56': ('1.3.6.1.1.9.2.56', OID_ATTRIBUTE_TYPE, 'pcelsFilterDirection', 'RFC4104'), + '1.3.6.1.1.9.2.57': ('1.3.6.1.1.9.2.57', OID_ATTRIBUTE_TYPE, 'pcelsFilterEntryList', 'RFC4104'), + '1.3.6.1.1.9.2.58': ('1.3.6.1.1.9.2.58', OID_ATTRIBUTE_TYPE, 'pcelsVendorVariableData', 'RFC4104'), + '1.3.6.1.1.9.2.59': ('1.3.6.1.1.9.2.59', OID_ATTRIBUTE_TYPE, 'pcelsVendorVariableEncoding', 'RFC4104'), + '1.3.6.1.1.9.2.60': ('1.3.6.1.1.9.2.60', OID_ATTRIBUTE_TYPE, 'pcelsVendorValueData', 'RFC4104'), + '1.3.6.1.1.9.2.61': ('1.3.6.1.1.9.2.61', OID_ATTRIBUTE_TYPE, 'pcelsVendorValueEncoding', 'RFC4104'), + '1.3.6.1.1.9.2.62': ('1.3.6.1.1.9.2.62', OID_ATTRIBUTE_TYPE, 'pcelsRuleValidityPeriodList', 'RFC4104'), + '1.3.6.1.4.1.11.1.3.1.1.0': ('1.3.6.1.4.1.11.1.3.1.1.0', OID_ATTRIBUTE_TYPE, 'defaultServerList', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.1': ('1.3.6.1.4.1.11.1.3.1.1.1', OID_ATTRIBUTE_TYPE, 'defaultSearchBase', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.2': ('1.3.6.1.4.1.11.1.3.1.1.2', OID_ATTRIBUTE_TYPE, 'preferredServerList', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.3': ('1.3.6.1.4.1.11.1.3.1.1.3', OID_ATTRIBUTE_TYPE, 'search_time_limit', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.4': ('1.3.6.1.4.1.11.1.3.1.1.4', OID_ATTRIBUTE_TYPE, 'bindTimeLimit', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.5': ('1.3.6.1.4.1.11.1.3.1.1.5', OID_ATTRIBUTE_TYPE, 'followReferrals', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.6': ('1.3.6.1.4.1.11.1.3.1.1.6', OID_ATTRIBUTE_TYPE, 'authenticationMethod', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.7': ('1.3.6.1.4.1.11.1.3.1.1.7', OID_ATTRIBUTE_TYPE, 'profileTTL', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.9': ('1.3.6.1.4.1.11.1.3.1.1.9', OID_ATTRIBUTE_TYPE, 'attributeMap', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.10': ('1.3.6.1.4.1.11.1.3.1.1.10', OID_ATTRIBUTE_TYPE, 'credentialLevel', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.11': ('1.3.6.1.4.1.11.1.3.1.1.11', OID_ATTRIBUTE_TYPE, 'objectclassMap', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.12': ('1.3.6.1.4.1.11.1.3.1.1.12', OID_ATTRIBUTE_TYPE, 'defaultSearchScope', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.13': ('1.3.6.1.4.1.11.1.3.1.1.13', OID_ATTRIBUTE_TYPE, 'serviceCredentialLevel', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.14': ('1.3.6.1.4.1.11.1.3.1.1.14', OID_ATTRIBUTE_TYPE, 'serviceSearchDescriptor', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.15': ('1.3.6.1.4.1.11.1.3.1.1.15', OID_ATTRIBUTE_TYPE, 'serviceAuthenticationMethod', 'RFC4876'), + '1.3.6.1.4.1.11.1.3.1.1.16': ('1.3.6.1.4.1.11.1.3.1.1.16', OID_ATTRIBUTE_TYPE, 'dereferenceAliases', 'RFC4876'), + '1.3.6.1.4.1.1466.101.119.3': ('1.3.6.1.4.1.1466.101.119.3', OID_ATTRIBUTE_TYPE, 'entryTtl', 'RFC2589'), + '1.3.6.1.4.1.1466.101.119.4': ('1.3.6.1.4.1.1466.101.119.4', OID_ATTRIBUTE_TYPE, 'dynamicSubtrees', 'RFC2589'), + '1.3.6.1.4.1.1466.101.120.1': ('1.3.6.1.4.1.1466.101.120.1', OID_ATTRIBUTE_TYPE, 'administratorsAddress', 'Mark_Wahl'), + '1.3.6.1.4.1.1466.101.120.5': ('1.3.6.1.4.1.1466.101.120.5', OID_ATTRIBUTE_TYPE, 'namingContexts', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.6': ('1.3.6.1.4.1.1466.101.120.6', OID_ATTRIBUTE_TYPE, 'altServer', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.7': ('1.3.6.1.4.1.1466.101.120.7', OID_ATTRIBUTE_TYPE, 'supportedExtension', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.13': ('1.3.6.1.4.1.1466.101.120.13', OID_ATTRIBUTE_TYPE, 'supportedControl', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.14': ('1.3.6.1.4.1.1466.101.120.14', OID_ATTRIBUTE_TYPE, 'supportedSASLMechanisms', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.15': ('1.3.6.1.4.1.1466.101.120.15', OID_ATTRIBUTE_TYPE, 'supportedLDAPVersion', 'RFC4512'), + '1.3.6.1.4.1.1466.101.120.16': ('1.3.6.1.4.1.1466.101.120.16', OID_ATTRIBUTE_TYPE, 'ldapSyntaxes', 'RFC4512'), + '1.3.6.1.4.1.16572.2.2.1': ('1.3.6.1.4.1.16572.2.2.1', OID_ATTRIBUTE_TYPE, 'providerCertificateHash', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.2': ('1.3.6.1.4.1.16572.2.2.2', OID_ATTRIBUTE_TYPE, 'providerCertificate', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.3': ('1.3.6.1.4.1.16572.2.2.3', OID_ATTRIBUTE_TYPE, 'providerName', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.4': ('1.3.6.1.4.1.16572.2.2.4', OID_ATTRIBUTE_TYPE, 'mailReceipt', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.5': ('1.3.6.1.4.1.16572.2.2.5', OID_ATTRIBUTE_TYPE, 'managedDomains', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.6': ('1.3.6.1.4.1.16572.2.2.6', OID_ATTRIBUTE_TYPE, 'LDIFLocationURL', 'RFC6109'), + '1.3.6.1.4.1.16572.2.2.7': ('1.3.6.1.4.1.16572.2.2.7', OID_ATTRIBUTE_TYPE, 'providerUnit', 'RFC6109'), + '1.3.6.1.4.1.250.1.57': ('1.3.6.1.4.1.250.1.57', OID_ATTRIBUTE_TYPE, 'labeledURI', 'RFC2079'), + '1.3.6.1.4.1.31103.1.1': ('1.3.6.1.4.1.31103.1.1', OID_ATTRIBUTE_TYPE, 'fedfsUuid', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.2': ('1.3.6.1.4.1.31103.1.2', OID_ATTRIBUTE_TYPE, 'fedfsNetAddr', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.3': ('1.3.6.1.4.1.31103.1.3', OID_ATTRIBUTE_TYPE, 'fedfsNetPort', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.4': ('1.3.6.1.4.1.31103.1.4', OID_ATTRIBUTE_TYPE, 'fedfsFsnUuid', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.5': ('1.3.6.1.4.1.31103.1.5', OID_ATTRIBUTE_TYPE, 'fedfsNsdbName', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.6': ('1.3.6.1.4.1.31103.1.6', OID_ATTRIBUTE_TYPE, 'fedfsNsdbPort', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.7': ('1.3.6.1.4.1.31103.1.7', OID_ATTRIBUTE_TYPE, 'fedfsNcePrefix', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.8': ('1.3.6.1.4.1.31103.1.8', OID_ATTRIBUTE_TYPE, 'fedfsFslUuid', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.9': ('1.3.6.1.4.1.31103.1.9', OID_ATTRIBUTE_TYPE, 'fedfsFslHost', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.10': ('1.3.6.1.4.1.31103.1.10', OID_ATTRIBUTE_TYPE, 'fedfsFslPort', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.11': ('1.3.6.1.4.1.31103.1.11', OID_ATTRIBUTE_TYPE, 'fedfsFslTTL', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.12': ('1.3.6.1.4.1.31103.1.12', OID_ATTRIBUTE_TYPE, 'fedfsAnnotation', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.13': ('1.3.6.1.4.1.31103.1.13', OID_ATTRIBUTE_TYPE, 'fedfsDescr', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.14': ('1.3.6.1.4.1.31103.1.14', OID_ATTRIBUTE_TYPE, 'fedfsNceDN', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.15': ('1.3.6.1.4.1.31103.1.15', OID_ATTRIBUTE_TYPE, 'fedfsFsnTTL', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.100': ('1.3.6.1.4.1.31103.1.100', OID_ATTRIBUTE_TYPE, 'fedfsNfsPath', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.101': ('1.3.6.1.4.1.31103.1.101', OID_ATTRIBUTE_TYPE, 'fedfsNfsMajorVer', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.102': ('1.3.6.1.4.1.31103.1.102', OID_ATTRIBUTE_TYPE, 'fedfsNfsMinorVer', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.103': ('1.3.6.1.4.1.31103.1.103', OID_ATTRIBUTE_TYPE, 'fedfsNfsCurrency', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.104': ('1.3.6.1.4.1.31103.1.104', OID_ATTRIBUTE_TYPE, 'fedfsNfsGenFlagWritable', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.105': ('1.3.6.1.4.1.31103.1.105', OID_ATTRIBUTE_TYPE, 'fedfsNfsGenFlagGoing', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.106': ('1.3.6.1.4.1.31103.1.106', OID_ATTRIBUTE_TYPE, 'fedfsNfsGenFlagSplit', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.107': ('1.3.6.1.4.1.31103.1.107', OID_ATTRIBUTE_TYPE, 'fedfsNfsTransFlagRdma', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.108': ('1.3.6.1.4.1.31103.1.108', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassSimul', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.109': ('1.3.6.1.4.1.31103.1.109', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassHandle', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.110': ('1.3.6.1.4.1.31103.1.110', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassFileid', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.111': ('1.3.6.1.4.1.31103.1.111', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassWritever', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.112': ('1.3.6.1.4.1.31103.1.112', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassChange', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.113': ('1.3.6.1.4.1.31103.1.113', OID_ATTRIBUTE_TYPE, 'fedfsNfsClassReaddir', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.114': ('1.3.6.1.4.1.31103.1.114', OID_ATTRIBUTE_TYPE, 'fedfsNfsReadRank', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.115': ('1.3.6.1.4.1.31103.1.115', OID_ATTRIBUTE_TYPE, 'fedfsNfsReadOrder', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.116': ('1.3.6.1.4.1.31103.1.116', OID_ATTRIBUTE_TYPE, 'fedfsNfsWriteRank', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.117': ('1.3.6.1.4.1.31103.1.117', OID_ATTRIBUTE_TYPE, 'fedfsNfsWriteOrder', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.118': ('1.3.6.1.4.1.31103.1.118', OID_ATTRIBUTE_TYPE, 'fedfsNfsVarSub', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.119': ('1.3.6.1.4.1.31103.1.119', OID_ATTRIBUTE_TYPE, 'fedfsNfsValidFor', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.120': ('1.3.6.1.4.1.31103.1.120', OID_ATTRIBUTE_TYPE, 'fedfsNfsURI', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.4203.1.3.5': ('1.3.6.1.4.1.4203.1.3.5', OID_ATTRIBUTE_TYPE, 'supportedFeatures', 'RFC4512'), + '1.3.6.1.4.1.453.7.2.1': ('1.3.6.1.4.1.453.7.2.1', OID_ATTRIBUTE_TYPE, 'textTableKey', 'RFC2293'), + '1.3.6.1.4.1.453.7.2.2': ('1.3.6.1.4.1.453.7.2.2', OID_ATTRIBUTE_TYPE, 'textTableValue', 'RFC2293'), + '1.3.6.1.4.1.453.7.2.3': ('1.3.6.1.4.1.453.7.2.3', OID_ATTRIBUTE_TYPE, ['associatedX400Gateway', 'distinguishedNameTableKey'], 'RFC2164-RFC2293'), + '1.3.6.1.4.1.453.7.2.6': ('1.3.6.1.4.1.453.7.2.6', OID_ATTRIBUTE_TYPE, 'associatedORAddress', 'RFC2164'), + '1.3.6.1.4.1.453.7.2.7': ('1.3.6.1.4.1.453.7.2.7', OID_ATTRIBUTE_TYPE, 'oRAddressComponentType', 'RFC2164'), + '1.3.6.1.4.1.453.7.2.8': ('1.3.6.1.4.1.453.7.2.8', OID_ATTRIBUTE_TYPE, 'associatedInternetGateway', 'RFC2164'), + '1.3.6.1.4.1.453.7.2.9': ('1.3.6.1.4.1.453.7.2.9', OID_ATTRIBUTE_TYPE, 'mcgamTables', 'RFC2164'), + '2.16.840.1.113730.3.1.34': ('2.16.840.1.113730.3.1.34', OID_ATTRIBUTE_TYPE, 'ref', 'RFC3296'), + '2.5.18.1': ('2.5.18.1', OID_ATTRIBUTE_TYPE, 'createTimestamp', 'RFC4512'), + '2.5.18.2': ('2.5.18.2', OID_ATTRIBUTE_TYPE, 'modifyTimestamp', 'RFC4512'), + '2.5.18.3': ('2.5.18.3', OID_ATTRIBUTE_TYPE, 'creatorsName', 'RFC4512'), + '2.5.18.4': ('2.5.18.4', OID_ATTRIBUTE_TYPE, 'modifiersName', 'RFC4512'), + '2.5.18.5': ('2.5.18.5', OID_ATTRIBUTE_TYPE, 'administrativeRole', 'RFC3672'), + '2.5.18.6': ('2.5.18.6', OID_ATTRIBUTE_TYPE, 'subtreeSpecification', 'RFC3672'), + '2.5.18.7': ('2.5.18.7', OID_ATTRIBUTE_TYPE, 'collectiveExclusions', 'RFC3671'), + '2.5.18.10': ('2.5.18.10', OID_ATTRIBUTE_TYPE, 'subschemaSubentry', 'RFC4512'), + '2.5.18.12': ('2.5.18.12', OID_ATTRIBUTE_TYPE, 'collectiveAttributeSubentries', 'RFC3671'), + '2.5.21.1': ('2.5.21.1', OID_ATTRIBUTE_TYPE, 'dITStructureRules', 'RFC4512'), + '2.5.21.2': ('2.5.21.2', OID_ATTRIBUTE_TYPE, 'dITContentRules', 'RFC4512'), + '2.5.21.4': ('2.5.21.4', OID_ATTRIBUTE_TYPE, 'matchingRules', 'RFC4512'), + '2.5.21.5': ('2.5.21.5', OID_ATTRIBUTE_TYPE, 'attributeTypes', 'RFC4512'), + '2.5.21.6': ('2.5.21.6', OID_ATTRIBUTE_TYPE, 'objectClasses', 'RFC4512'), + '2.5.21.7': ('2.5.21.7', OID_ATTRIBUTE_TYPE, 'nameForms', 'RFC4512'), + '2.5.21.8': ('2.5.21.8', OID_ATTRIBUTE_TYPE, 'matchingRuleUse', 'RFC4512'), + '2.5.21.9': ('2.5.21.9', OID_ATTRIBUTE_TYPE, 'structuralObjectClass', 'RFC4512'), + '2.5.21.10': ('2.5.21.10', OID_ATTRIBUTE_TYPE, 'governingStructureRule', 'RFC4512'), + '2.5.4.0': ('2.5.4.0', OID_ATTRIBUTE_TYPE, 'objectClass', 'RFC4512'), + '2.5.4.1': ('2.5.4.1', OID_ATTRIBUTE_TYPE, ['aliasedEntryName', 'aliasedObjectName'], 'X.501-RFC4512'), + '2.5.4.2': ('2.5.4.2', OID_ATTRIBUTE_TYPE, 'knowledgeInformation', 'RFC2256'), + '2.5.4.3': ('2.5.4.3', OID_ATTRIBUTE_TYPE, ['cn', 'commonName'], 'RFC4519'), + '2.5.4.4': ('2.5.4.4', OID_ATTRIBUTE_TYPE, ['sn', 'surname'], 'RFC4519'), + '2.5.4.5': ('2.5.4.5', OID_ATTRIBUTE_TYPE, 'serialNumber', 'RFC4519'), + '2.5.4.6': ('2.5.4.6', OID_ATTRIBUTE_TYPE, ['c', 'countryName'], 'RFC4519'), + '2.5.4.7': ('2.5.4.7', OID_ATTRIBUTE_TYPE, ['L', 'localityName'], 'RFC4519'), + '2.5.4.7.1': ('2.5.4.7.1', OID_ATTRIBUTE_TYPE, 'c-l', 'RFC3671'), + '2.5.4.8': ('2.5.4.8', OID_ATTRIBUTE_TYPE, ['st', 'stateOrProvinceName'], 'RFC4519-RFC2256'), + '2.5.4.8.1': ('2.5.4.8.1', OID_ATTRIBUTE_TYPE, 'c-st', 'RFC3671'), + '2.5.4.9': ('2.5.4.9', OID_ATTRIBUTE_TYPE, ['street', 'streetAddress'], 'RFC4519-RFC2256'), + '2.5.4.9.1': ('2.5.4.9.1', OID_ATTRIBUTE_TYPE, 'c-street', 'RFC3671'), + '2.5.4.10': ('2.5.4.10', OID_ATTRIBUTE_TYPE, ['o', 'organizationName'], 'RFC4519'), + '2.5.4.10.1': ('2.5.4.10.1', OID_ATTRIBUTE_TYPE, 'c-o', 'RFC3671'), + '2.5.4.11': ('2.5.4.11', OID_ATTRIBUTE_TYPE, ['ou', 'organizationalUnitName'], 'RFC4519'), + '2.5.4.11.1': ('2.5.4.11.1', OID_ATTRIBUTE_TYPE, 'c-ou', 'RFC3671'), + '2.5.4.12': ('2.5.4.12', OID_ATTRIBUTE_TYPE, 'title', 'RFC4519'), + '2.5.4.13': ('2.5.4.13', OID_ATTRIBUTE_TYPE, 'description', 'RFC4519'), + '2.5.4.14': ('2.5.4.14', OID_ATTRIBUTE_TYPE, 'searchGuide', 'RFC4519'), + '2.5.4.15': ('2.5.4.15', OID_ATTRIBUTE_TYPE, 'businessCategory', 'RFC4519'), + '2.5.4.16': ('2.5.4.16', OID_ATTRIBUTE_TYPE, 'postalAddress', 'RFC4519'), + '2.5.4.16.1': ('2.5.4.16.1', OID_ATTRIBUTE_TYPE, 'c-PostalAddress', 'RFC3671'), + '2.5.4.17': ('2.5.4.17', OID_ATTRIBUTE_TYPE, 'postalCode', 'RFC4519'), + '2.5.4.17.1': ('2.5.4.17.1', OID_ATTRIBUTE_TYPE, 'c-PostalCode', 'RFC3671'), + '2.5.4.18': ('2.5.4.18', OID_ATTRIBUTE_TYPE, 'postOfficeBox', 'RFC4519'), + '2.5.4.18.1': ('2.5.4.18.1', OID_ATTRIBUTE_TYPE, 'c-PostOfficeBox', 'RFC3671'), + '2.5.4.19': ('2.5.4.19', OID_ATTRIBUTE_TYPE, 'physicalDeliveryOfficeName', 'RFC4519'), + '2.5.4.19.1': ('2.5.4.19.1', OID_ATTRIBUTE_TYPE, 'c-PhysicalDeliveryOffice', 'RFC3671'), + '2.5.4.20': ('2.5.4.20', OID_ATTRIBUTE_TYPE, 'telephoneNumber', 'RFC4519'), + '2.5.4.20.1': ('2.5.4.20.1', OID_ATTRIBUTE_TYPE, 'c-TelephoneNumber', 'RFC3671'), + '2.5.4.21': ('2.5.4.21', OID_ATTRIBUTE_TYPE, 'telexNumber', 'RFC4519'), + '2.5.4.21.1': ('2.5.4.21.1', OID_ATTRIBUTE_TYPE, 'c-TelexNumber', 'RFC3671'), + '2.5.4.22': ('2.5.4.22', OID_ATTRIBUTE_TYPE, 'teletexTerminalIdentifier', 'RFC4519'), + '2.5.4.23': ('2.5.4.23', OID_ATTRIBUTE_TYPE, 'facsimileTelephoneNumber', 'RFC4519'), + '2.5.4.23.1': ('2.5.4.23.1', OID_ATTRIBUTE_TYPE, 'c-FacsimileTelephoneNumber', 'RFC3671'), + '2.5.4.24': ('2.5.4.24', OID_ATTRIBUTE_TYPE, 'x121Address', 'RFC4519'), + '2.5.4.25': ('2.5.4.25', OID_ATTRIBUTE_TYPE, 'internationaliSDNNumber', 'RFC4519'), + '2.5.4.25.1': ('2.5.4.25.1', OID_ATTRIBUTE_TYPE, 'c-InternationalISDNNumber', 'RFC3671'), + '2.5.4.26': ('2.5.4.26', OID_ATTRIBUTE_TYPE, 'registeredAddress', 'RFC4519'), + '2.5.4.27': ('2.5.4.27', OID_ATTRIBUTE_TYPE, 'destinationIndicator', 'RFC4519'), + '2.5.4.28': ('2.5.4.28', OID_ATTRIBUTE_TYPE, 'preferredDeliveryMethod', 'RFC4519'), + '2.5.4.29': ('2.5.4.29', OID_ATTRIBUTE_TYPE, 'presentationAddress', 'RFC2256'), + '2.5.4.30': ('2.5.4.30', OID_ATTRIBUTE_TYPE, 'supportedApplicationContext', 'RFC2256'), + '2.5.4.31': ('2.5.4.31', OID_ATTRIBUTE_TYPE, 'member', 'RFC4519'), + '2.5.4.32': ('2.5.4.32', OID_ATTRIBUTE_TYPE, 'owner', 'RFC4519'), + '2.5.4.33': ('2.5.4.33', OID_ATTRIBUTE_TYPE, 'roleOccupant', 'RFC4519'), + '2.5.4.34': ('2.5.4.34', OID_ATTRIBUTE_TYPE, 'seeAlso', 'RFC4519'), + '2.5.4.35': ('2.5.4.35', OID_ATTRIBUTE_TYPE, 'userPassword', 'RFC4519'), + '2.5.4.36': ('2.5.4.36', OID_ATTRIBUTE_TYPE, 'userCertificate', 'RFC4523'), + '2.5.4.37': ('2.5.4.37', OID_ATTRIBUTE_TYPE, 'cACertificate', 'RFC4523'), + '2.5.4.38': ('2.5.4.38', OID_ATTRIBUTE_TYPE, 'authorityRevocationList', 'RFC4523'), + '2.5.4.39': ('2.5.4.39', OID_ATTRIBUTE_TYPE, 'certificateRevocationList', 'RFC4523'), + '2.5.4.40': ('2.5.4.40', OID_ATTRIBUTE_TYPE, 'crossCertificatePair', 'RFC4523'), + '2.5.4.41': ('2.5.4.41', OID_ATTRIBUTE_TYPE, 'name', 'RFC4519'), + '2.5.4.42': ('2.5.4.42', OID_ATTRIBUTE_TYPE, 'givenName', 'RFC4519'), + '2.5.4.43': ('2.5.4.43', OID_ATTRIBUTE_TYPE, 'initials', 'RFC4519'), + '2.5.4.44': ('2.5.4.44', OID_ATTRIBUTE_TYPE, 'generationQualifier', 'RFC4519'), + '2.5.4.45': ('2.5.4.45', OID_ATTRIBUTE_TYPE, 'x500UniqueIdentifier', 'RFC4519'), + '2.5.4.46': ('2.5.4.46', OID_ATTRIBUTE_TYPE, 'dnQualifier', 'RFC4519'), + '2.5.4.47': ('2.5.4.47', OID_ATTRIBUTE_TYPE, 'enhancedSearchGuide', 'RFC4519'), + '2.5.4.48': ('2.5.4.48', OID_ATTRIBUTE_TYPE, 'protocolInformation', 'RFC2256'), + '2.5.4.49': ('2.5.4.49', OID_ATTRIBUTE_TYPE, 'distinguishedName', 'RFC4519'), + '2.5.4.50': ('2.5.4.50', OID_ATTRIBUTE_TYPE, 'uniqueMember', 'RFC4519'), + '2.5.4.51': ('2.5.4.51', OID_ATTRIBUTE_TYPE, 'houseIdentifier', 'RFC4519'), + '2.5.4.52': ('2.5.4.52', OID_ATTRIBUTE_TYPE, 'supportedAlgorithms', 'RFC4523'), + '2.5.4.53': ('2.5.4.53', OID_ATTRIBUTE_TYPE, 'deltaRevocationList', 'RFC4523'), + '2.5.4.54': ('2.5.4.54', OID_ATTRIBUTE_TYPE, 'dmdName', 'RFC2256'), + '2.5.4.65': ('2.5.4.65', OID_ATTRIBUTE_TYPE, 'pseudonym', 'RFC3280'), + '2.16.840.1.113719.1.1.4.1.501': ('2.16.840.1.113719.1.1.4.1.501', OID_ATTRIBUTE_TYPE, 'GUID', 'NOVELL'), + '2.16.840.1.113719.1.27.4.50': ('2.16.840.1.113719.1.27.4.50', OID_ATTRIBUTE_TYPE, 'localEntryID', 'NOVELL'), + '2.16.840.1.113730.3.8.3.1': ('2.16.840.1.113730.3.8.3.1', OID_ATTRIBUTE_TYPE, 'ipaUniqueID', 'freeIPA'), + '2.16.840.1.113730.3.8.3.2': ('2.16.840.1.113730.3.8.3.2', OID_ATTRIBUTE_TYPE, 'ipaClientVersion', 'freeIPA'), + '2.16.840.1.113730.3.8.3.3': ('2.16.840.1.113730.3.8.3.3', OID_ATTRIBUTE_TYPE, 'enrolledBy', 'freeIPA'), + '2.16.840.1.113730.3.8.3.4': ('2.16.840.1.113730.3.8.3.4', OID_ATTRIBUTE_TYPE, 'fqdn', 'freeIPA'), + '2.16.840.1.113730.3.8.3.18': ('2.16.840.1.113730.3.8.3.18', OID_ATTRIBUTE_TYPE, 'managedBy', 'freeIPA'), + '2.16.840.1.113730.3.8.3.24': ('2.16.840.1.113730.3.8.3.24', OID_ATTRIBUTE_TYPE, 'ipaEntitlementId', 'freeIPA'), + + # controls + '1.2.826.0.1.3344810.2.3': ('1.2.826.0.1.3344810.2.3', OID_CONTROL, 'Matched Values', 'RFC3876'), + '1.2.840.113556.1.4.319': ('1.2.840.113556.1.4.319', OID_CONTROL, 'LDAP Simple Paged Results', 'RFC2696'), + '1.2.840.113556.1.4.417': ('1.2.840.113556.1.4.417', OID_CONTROL, 'LDAP server show deleted objects', 'MICROSOFT'), + '1.2.840.113556.1.4.473': ('1.2.840.113556.1.4.473', OID_CONTROL, 'Sort Request', 'RFC2891'), + '1.2.840.113556.1.4.474': ('1.2.840.113556.1.4.474', OID_CONTROL, 'Sort Response', 'RFC2891'), + '1.2.840.113556.1.4.521': ('1.2.840.113556.1.4.521', OID_CONTROL, 'Cross-domain move', 'MICROSOFT'), + '1.2.840.113556.1.4.528': ('1.2.840.113556.1.4.528', OID_CONTROL, 'Server search notification', 'MICROSOFT'), + '1.2.840.113556.1.4.529': ('1.2.840.113556.1.4.529', OID_CONTROL, 'Extended DN', 'MICROSOFT'), + '1.2.840.113556.1.4.619': ('1.2.840.113556.1.4.619', OID_CONTROL, 'Lazy commit', 'MICROSOFT'), + '1.2.840.113556.1.4.801': ('1.2.840.113556.1.4.801', OID_CONTROL, 'Security descriptor flags', 'MICROSOFT'), + '1.2.840.113556.1.4.802': ('1.2.840.113556.1.4.802', OID_CONTROL, 'Range option', 'MICROSOFT'), + '1.2.840.113556.1.4.805': ('1.2.840.113556.1.4.805', OID_CONTROL, 'Tree delete', 'MICROSOFT'), + '1.2.840.113556.1.4.841': ('1.2.840.113556.1.4.841', OID_CONTROL, 'Directory synchronization', 'MICROSOFT'), + '1.2.840.113556.1.4.970': ('1.2.840.113556.1.4.970', OID_CONTROL, 'Get stats', 'MICROSOFT'), + '1.2.840.113556.1.4.1338': ('1.2.840.113556.1.4.1338', OID_CONTROL, 'Verify name', 'MICROSOFT'), + '1.2.840.113556.1.4.1339': ('1.2.840.113556.1.4.1339', OID_CONTROL, 'Domain scope', 'MICROSOFT'), + '1.2.840.113556.1.4.1340': ('1.2.840.113556.1.4.1340', OID_CONTROL, 'Search options', 'MICROSOFT'), + '1.2.840.113556.1.4.1341': ('1.2.840.113556.1.4.1341', OID_CONTROL, 'RODC DCPROMO', 'MICROSOFT'), + '1.2.840.113556.1.4.1413': ('1.2.840.113556.1.4.1413', OID_CONTROL, 'Permissive modify', 'MICROSOFT'), + '1.2.840.113556.1.4.1504': ('1.2.840.113556.1.4.1504', OID_CONTROL, 'Attribute scoped query', 'MICROSOFT'), + '1.2.840.113556.1.4.1852': ('1.2.840.113556.1.4.1852', OID_CONTROL, 'User quota', 'MICROSOFT'), + '1.2.840.113556.1.4.1907': ('1.2.840.113556.1.4.1907', OID_CONTROL, 'Server shutdown notify', 'MICROSOFT'), + '1.2.840.113556.1.4.1948': ('1.2.840.113556.1.4.1948', OID_CONTROL, 'Range retrieval no error', 'MICROSOFT'), + '1.2.840.113556.1.4.1974': ('1.2.840.113556.1.4.1974', OID_CONTROL, 'Server force update', 'MICROSOFT'), + '1.2.840.113556.1.4.2026': ('1.2.840.113556.1.4.2026', OID_CONTROL, 'Input DN', 'MICROSOFT'), + '1.2.840.113556.1.4.2064': ('1.2.840.113556.1.4.2064', OID_CONTROL, 'Show recycled', 'MICROSOFT'), + '1.2.840.113556.1.4.2065': ('1.2.840.113556.1.4.2065', OID_CONTROL, 'Show deactivated link', 'MICROSOFT'), + '1.2.840.113556.1.4.2066': ('1.2.840.113556.1.4.2066', OID_CONTROL, 'Policy hints [DEPRECATED]', 'MICROSOFT'), + '1.2.840.113556.1.4.2090': ('1.2.840.113556.1.4.2090', OID_CONTROL, 'DirSync EX', 'MICROSOFT'), + '1.2.840.113556.1.4.2204': ('1.2.840.113556.1.4.2204', OID_CONTROL, 'Tree deleted EX', 'MICROSOFT'), + '1.2.840.113556.1.4.2205': ('1.2.840.113556.1.4.2205', OID_CONTROL, 'Updates stats', 'MICROSOFT'), + '1.2.840.113556.1.4.2206': ('1.2.840.113556.1.4.2206', OID_CONTROL, 'Search hints', 'MICROSOFT'), + '1.2.840.113556.1.4.2211': ('1.2.840.113556.1.4.2211', OID_CONTROL, 'Expected entry count', 'MICROSOFT'), + '1.2.840.113556.1.4.2239': ('1.2.840.113556.1.4.2239', OID_CONTROL, 'Policy hints', 'MICROSOFT'), + '1.2.840.113556.1.4.2255': ('1.2.840.113556.1.4.2255', OID_CONTROL, 'Set owner', 'MICROSOFT'), + '1.2.840.113556.1.4.2256': ('1.2.840.113556.1.4.2256', OID_CONTROL, 'Bypass quota', 'MICROSOFT'), + '1.3.6.1.1.7.1': ('1.3.6.1.1.7.1', OID_CONTROL, 'LCUP Sync Request', 'RFC3928'), + '1.3.6.1.1.7.2': ('1.3.6.1.1.7.2', OID_CONTROL, 'LCUP Sync Update', 'RFC3928'), + '1.3.6.1.1.7.3': ('1.3.6.1.1.7.3', OID_CONTROL, 'LCUP Sync Done', 'RFC3928'), + '1.3.6.1.1.12': ('1.3.6.1.1.12', OID_CONTROL, 'Assertion', 'RFC4528'), + '1.3.6.1.1.13.1': ('1.3.6.1.1.13.1', OID_CONTROL, 'LDAP Pre-read', 'RFC4527'), + '1.3.6.1.1.13.2': ('1.3.6.1.1.13.2', OID_CONTROL, 'LDAP Post-read', 'RFC4527'), + '1.3.6.1.1.21.2': ('1.3.6.1.1.21.2', OID_CONTROL, 'Transaction Specification', 'RFC5805'), + '1.3.6.1.1.22': ('1.3.6.1.1.22', OID_CONTROL, "LDAP Don't Use Copy", 'RFC6171'), + '1.3.6.1.4.1.42.2.27.8.5.1': ('1.3.6.1.4.1.42.2.27.8.5.1', OID_CONTROL, 'Password policy', 'IETF DRAFT behera-ldap-password-policy'), + '1.3.6.1.4.1.42.2.27.9.5.2': ('1.3.6.1.4.1.42.2.27.9.5.2', OID_CONTROL, 'Get effective rights', 'IETF DRAFT draft-ietf-ldapext-acl-model'), + '1.3.6.1.4.1.42.2.27.9.5.8': ('1.3.6.1.4.1.42.2.27.9.5.8', OID_CONTROL, 'Account usability', 'SUN microsystems'), + '1.3.6.1.4.1.1466.29539.12': ('1.3.6.1.4.1.1466.29539.12', OID_CONTROL, 'Chaining loop detect', 'SUN microsystems'), + '1.3.6.1.4.1.4203.1.9.1.1': ('1.3.6.1.4.1.4203.1.9.1.1', OID_CONTROL, 'LDAP content synchronization', 'RFC4533'), + '1.3.6.1.4.1.4203.1.10.1': ('1.3.6.1.4.1.4203.1.10.1', OID_CONTROL, 'Subentries', 'RFC3672'), + '1.3.6.1.4.1.4203.1.10.2': ('1.3.6.1.4.1.4203.1.10.2', OID_CONTROL, 'No-Operation', 'IETF DRAFT draft-zeilenga-ldap-noop'), + '1.3.6.1.4.1.4203.666.5.16': ('1.3.6.1.4.1.4203.666.5.16', OID_CONTROL, 'LDAP Dereference', 'IETF DRAFT draft-masarati-ldap-deref'), + '1.3.6.1.4.1.7628.5.101.1': ('1.3.6.1.4.1.7628.5.101.1', OID_CONTROL, 'LDAP subentries', 'IETF DRAFT draft-ietf-ldup-subentry'), + '1.3.6.1.4.1.26027.1.5.2': ('1.3.6.1.4.1.26027.1.5.2', OID_CONTROL, 'Replication repair', 'OpenDS'), + '2.16.840.1.113719.1.27.101.5': ('2.16.840.1.113719.1.27.101.5', OID_CONTROL, 'Simple password', 'NOVELL'), + '1.3.6.1.4.1.26027.1.6.1': ('1.3.6.1.4.1.26027.1.6.1', OID_CONTROL, 'Password policy state', 'OpenDS'), + '1.3.6.1.4.1.26027.1.6.2': ('1.3.6.1.4.1.26027.1.6.2', OID_CONTROL, 'Get connection ID', 'OpenDS'), + '1.3.6.1.4.1.26027.1.6.3': ('1.3.6.1.4.1.26027.1.6.3', OID_CONTROL, 'Get symmetric key', 'OpenDS'), + '2.16.840.1.113719.1.27.101.6': ('2.16.840.1.113719.1.27.101.6', OID_CONTROL, 'Forward reference', 'NOVELL'), + '2.16.840.1.113719.1.27.103.7': ('2.16.840.1.113719.1.27.103.7', OID_CONTROL, 'Grouping', 'NOVELL'), + '2.16.840.1.113730.3.4.2': ('2.16.840.1.113730.3.4.2', OID_CONTROL, 'ManageDsaIT', 'RFC3296'), + '2.16.840.1.113730.3.4.3': ('2.16.840.1.113730.3.4.3', OID_CONTROL, 'Persistent Search', 'IETF'), + '2.16.840.1.113730.3.4.4': ('2.16.840.1.113730.3.4.4', OID_CONTROL, 'Netscape Password Expired', 'Netscape'), + '2.16.840.1.113730.3.4.5': ('2.16.840.1.113730.3.4.5', OID_CONTROL, 'Netscape Password Expiring', 'Netscape'), + '2.16.840.1.113730.3.4.6': ('2.16.840.1.113730.3.4.6', OID_CONTROL, 'Netscape NT Synchronization Client', 'Netscape'), + '2.16.840.1.113730.3.4.7': ('2.16.840.1.113730.3.4.7', OID_CONTROL, 'Entry Change Notification', 'Netscape'), + '2.16.840.1.113730.3.4.9': ('2.16.840.1.113730.3.4.9', OID_CONTROL, 'Virtual List View Request', 'IETF'), + '2.16.840.1.113730.3.4.10': ('2.16.840.1.113730.3.4.10', OID_CONTROL, 'Virtual List View Response', 'IETF'), + '2.16.840.1.113730.3.4.12': ('2.16.840.1.113730.3.4.12', OID_CONTROL, 'Proxied Authorization (old)', 'Netscape'), + '2.16.840.1.113730.3.4.13': ('2.16.840.1.113730.3.4.13', OID_CONTROL, 'iPlanet Directory Server Replication Update Information', 'Netscape'), + '2.16.840.1.113730.3.4.14': ('2.16.840.1.113730.3.4.14', OID_CONTROL, 'Search on specific database', 'Netscape'), + '2.16.840.1.113730.3.4.15': ('2.16.840.1.113730.3.4.15', OID_CONTROL, 'Authorization Identity Response Control', 'RFC3829'), + '2.16.840.1.113730.3.4.16': ('2.16.840.1.113730.3.4.16', OID_CONTROL, 'Authorization Identity Request Control', 'RFC3829'), + '2.16.840.1.113730.3.4.17': ('2.16.840.1.113730.3.4.17', OID_CONTROL, 'Real attribute only request', 'Netscape'), + '2.16.840.1.113730.3.4.18': ('2.16.840.1.113730.3.4.18', OID_CONTROL, 'Proxy Authorization Control', 'RFC6171'), + '2.16.840.1.113730.3.4.19': ('2.16.840.1.113730.3.4.19', OID_CONTROL, 'Chaining loop detection', 'Netscape'), + '2.16.840.1.113730.3.4.20': ('2.16.840.1.113730.3.4.20', OID_CONTROL, 'Mapping Tree Node - Use one backend [extended]', 'openLDAP'), + '2.16.840.1.113730.3.8.10.6': ('2.16.840.1.113730.3.8.10.6', OID_CONTROL, 'OTP Sync Request', 'freeIPA'), + + # dit content rules + + # extensions + '1.2.840.113556.1.4.1781': ('1.2.840.113556.1.4.1781', OID_EXTENSION, 'Fast concurrent bind', 'MICROSOFT'), + '1.2.840.113556.1.4.2212': ('1.2.840.113556.1.4.2212', OID_EXTENSION, 'Batch request', 'MICROSOFT'), + '1.3.6.1.1.8': ('1.3.6.1.1.8', OID_EXTENSION, 'Cancel Operation', 'RFC3909'), + '1.3.6.1.1.21.1': ('1.3.6.1.1.21.1', OID_EXTENSION, 'Start Transaction Extended Request', 'RFC5805'), + '1.3.6.1.1.21.3': ('1.3.6.1.1.21.3', OID_EXTENSION, 'End Transaction Extended Request', 'RFC5805'), + '1.3.6.1.4.1.1466.101.119.1': ('1.3.6.1.4.1.1466.101.119.1', OID_EXTENSION, 'Dynamic Refresh', 'RFC2589'), + '1.3.6.1.4.1.1466.20037': ('1.3.6.1.4.1.1466.20037', OID_EXTENSION, 'StartTLS', 'RFC4511-RFC4513'), + '1.3.6.1.4.1.4203.1.11.1': ('1.3.6.1.4.1.4203.1.11.1', OID_EXTENSION, 'Modify Password', 'RFC3062'), + '1.3.6.1.4.1.4203.1.11.3': ('1.3.6.1.4.1.4203.1.11.3', OID_EXTENSION, 'Who am I', 'RFC4532'), + '1.3.6.1.1.17.1': ('1.3.6.1.1.17.1', OID_EXTENSION, 'StartLBURPRequest LDAP ExtendedRequest message', 'RFC4373'), + '1.3.6.1.1.17.2': ('1.3.6.1.1.17.2', OID_EXTENSION, 'StartLBURPResponse LDAP ExtendedResponse message', 'RFC4373'), + '1.3.6.1.1.17.3': ('1.3.6.1.1.17.3', OID_EXTENSION, 'EndLBURPRequest LDAP ExtendedRequest message', 'RFC4373'), + '1.3.6.1.1.17.4': ('1.3.6.1.1.17.4', OID_EXTENSION, 'EndLBURPResponse LDAP ExtendedResponse message', 'RFC4373'), + '1.3.6.1.1.17.5': ('1.3.6.1.1.17.5', OID_EXTENSION, 'LBURPUpdateRequest LDAP ExtendedRequest message', 'RFC4373'), + '1.3.6.1.1.17.6': ('1.3.6.1.1.17.6', OID_EXTENSION, 'LBURPUpdateResponse LDAP ExtendedResponse message', 'RFC4373'), + '1.3.6.1.1.19': ('1.3.6.1.1.19', OID_EXTENSION, 'LDAP Turn Operation', 'RFC4531'), + '2.16.840.1.113719.1.14.100.1': ('2.16.840.1.113719.1.14.100.1', OID_EXTENSION, 'getDriverSetRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.2': ('2.16.840.1.113719.1.14.100.2', OID_EXTENSION, 'getDriverSetResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.3': ('2.16.840.1.113719.1.14.100.3', OID_EXTENSION, 'setDriverSetRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.4': ('2.16.840.1.113719.1.14.100.4', OID_EXTENSION, 'setDriverSetResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.5': ('2.16.840.1.113719.1.14.100.5', OID_EXTENSION, 'clearDriverSetRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.6': ('2.16.840.1.113719.1.14.100.6', OID_EXTENSION, 'clearDriverSetResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.7': ('2.16.840.1.113719.1.14.100.7', OID_EXTENSION, 'getDriverStartOptionRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.8': ('2.16.840.1.113719.1.14.100.8', OID_EXTENSION, 'getDriverStartOptionResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.9': ('2.16.840.1.113719.1.14.100.9', OID_EXTENSION, 'setDriverStartOptionRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.10': ('2.16.840.1.113719.1.14.100.10', OID_EXTENSION, 'setDriverStartOptionResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.11': ('2.16.840.1.113719.1.14.100.11', OID_EXTENSION, 'getVersionRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.12': ('2.16.840.1.113719.1.14.100.12', OID_EXTENSION, 'getVersionResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.13': ('2.16.840.1.113719.1.14.100.13', OID_EXTENSION, 'getDriverStateRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.14': ('2.16.840.1.113719.1.14.100.14', OID_EXTENSION, 'getDriverStateResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.15': ('2.16.840.1.113719.1.14.100.15', OID_EXTENSION, 'startDriverRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.16': ('2.16.840.1.113719.1.14.100.16', OID_EXTENSION, 'startDriverResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.17': ('2.16.840.1.113719.1.14.100.17', OID_EXTENSION, 'stopDriverRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.18': ('2.16.840.1.113719.1.14.100.18', OID_EXTENSION, 'stopDriverResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.19': ('2.16.840.1.113719.1.14.100.19', OID_EXTENSION, 'getDriverStatsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.20': ('2.16.840.1.113719.1.14.100.20', OID_EXTENSION, 'getDriverStatsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.21': ('2.16.840.1.113719.1.14.100.21', OID_EXTENSION, 'driverGetSchemaRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.22': ('2.16.840.1.113719.1.14.100.22', OID_EXTENSION, 'driverGetSchemaResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.23': ('2.16.840.1.113719.1.14.100.23', OID_EXTENSION, 'driverResyncRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.24': ('2.16.840.1.113719.1.14.100.24', OID_EXTENSION, 'driverResyncResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.25': ('2.16.840.1.113719.1.14.100.25', OID_EXTENSION, 'migrateAppRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.26': ('2.16.840.1.113719.1.14.100.26', OID_EXTENSION, 'migrateAppResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.27': ('2.16.840.1.113719.1.14.100.27', OID_EXTENSION, 'queueEventRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.28': ('2.16.840.1.113719.1.14.100.28', OID_EXTENSION, 'queueEventResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.29': ('2.16.840.1.113719.1.14.100.29', OID_EXTENSION, 'submitCommandRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.30': ('2.16.840.1.113719.1.14.100.30', OID_EXTENSION, 'submitCommandResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.31': ('2.16.840.1.113719.1.14.100.31', OID_EXTENSION, 'submitEventRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.32': ('2.16.840.1.113719.1.14.100.32', OID_EXTENSION, 'submitEventResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.33': ('2.16.840.1.113719.1.14.100.33', OID_EXTENSION, 'getChunkedResultRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.34': ('2.16.840.1.113719.1.14.100.34', OID_EXTENSION, 'getChunkedResultResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.35': ('2.16.840.1.113719.1.14.100.35', OID_EXTENSION, 'closeChunkedResultRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.36': ('2.16.840.1.113719.1.14.100.36', OID_EXTENSION, 'closeChunkedResultResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.37': ('2.16.840.1.113719.1.14.100.37', OID_EXTENSION, 'checkObjectPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.38': ('2.16.840.1.113719.1.14.100.38', OID_EXTENSION, 'checkObjectPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.39': ('2.16.840.1.113719.1.14.100.39', OID_EXTENSION, 'initDriverObjectRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.40': ('2.16.840.1.113719.1.14.100.40', OID_EXTENSION, 'initDriverObjectResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.41': ('2.16.840.1.113719.1.14.100.41', OID_EXTENSION, 'viewCacheEntriesRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.42': ('2.16.840.1.113719.1.14.100.42', OID_EXTENSION, 'viewCacheEntriesResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.43': ('2.16.840.1.113719.1.14.100.43', OID_EXTENSION, 'deleteCacheEntriesRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.44': ('2.16.840.1.113719.1.14.100.44', OID_EXTENSION, 'deleteCacheEntriesResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.45': ('2.16.840.1.113719.1.14.100.45', OID_EXTENSION, 'getPasswordsStateRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.46': ('2.16.840.1.113719.1.14.100.46', OID_EXTENSION, 'getPasswordsStateResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.47': ('2.16.840.1.113719.1.14.100.47', OID_EXTENSION, 'regenerateKeyRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.48': ('2.16.840.1.113719.1.14.100.48', OID_EXTENSION, 'regenerateKeyResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.49': ('2.16.840.1.113719.1.14.100.49', OID_EXTENSION, 'getServerCertRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.50': ('2.16.840.1.113719.1.14.100.50', OID_EXTENSION, 'getServerCertResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.51': ('2.16.840.1.113719.1.14.100.51', OID_EXTENSION, 'discoverJobsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.52': ('2.16.840.1.113719.1.14.100.52', OID_EXTENSION, 'discoverJobsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.53': ('2.16.840.1.113719.1.14.100.53', OID_EXTENSION, 'notifyJobUpdateRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.54': ('2.16.840.1.113719.1.14.100.54', OID_EXTENSION, 'notifyJobUpdateResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.55': ('2.16.840.1.113719.1.14.100.55', OID_EXTENSION, 'startJobRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.56': ('2.16.840.1.113719.1.14.100.56', OID_EXTENSION, 'startJobResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.57': ('2.16.840.1.113719.1.14.100.57', OID_EXTENSION, 'abortJobRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.58': ('2.16.840.1.113719.1.14.100.58', OID_EXTENSION, 'abortJobresponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.59': ('2.16.840.1.113719.1.14.100.59', OID_EXTENSION, 'getJobStateRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.60': ('2.16.840.1.113719.1.14.100.60', OID_EXTENSION, 'getJobStateResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.61': ('2.16.840.1.113719.1.14.100.61', OID_EXTENSION, 'checkJobConfigRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.62': ('2.16.840.1.113719.1.14.100.62', OID_EXTENSION, 'checkJobConfigResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.63': ('2.16.840.1.113719.1.14.100.63', OID_EXTENSION, 'setLogEventsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.64': ('2.16.840.1.113719.1.14.100.64', OID_EXTENSION, 'setLogEventsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.65': ('2.16.840.1.113719.1.14.100.65', OID_EXTENSION, 'clearLogEventsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.66': ('2.16.840.1.113719.1.14.100.66', OID_EXTENSION, 'clearLogEventsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.67': ('2.16.840.1.113719.1.14.100.67', OID_EXTENSION, 'setAppPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.68': ('2.16.840.1.113719.1.14.100.68', OID_EXTENSION, 'setAppPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.69': ('2.16.840.1.113719.1.14.100.69', OID_EXTENSION, 'clearAppPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.70': ('2.16.840.1.113719.1.14.100.70', OID_EXTENSION, 'clearAppPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.71': ('2.16.840.1.113719.1.14.100.71', OID_EXTENSION, 'setRemoteLoaderPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.72': ('2.16.840.1.113719.1.14.100.72', OID_EXTENSION, 'setRemoteLoaderPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.73': ('2.16.840.1.113719.1.14.100.73', OID_EXTENSION, 'clearRemoteLoaderPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.74': ('2.16.840.1.113719.1.14.100.74', OID_EXTENSION, 'clearRemoteLoaderPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.75': ('2.16.840.1.113719.1.14.100.75', OID_EXTENSION, 'setNamedPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.76': ('2.16.840.1.113719.1.14.100.76', OID_EXTENSION, 'setNamedPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.77': ('2.16.840.1.113719.1.14.100.77', OID_EXTENSION, 'removeNamedPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.78': ('2.16.840.1.113719.1.14.100.78', OID_EXTENSION, 'removeNamedPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.79': ('2.16.840.1.113719.1.14.100.79', OID_EXTENSION, 'removeAllNamedPasswordsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.80': ('2.16.840.1.113719.1.14.100.80', OID_EXTENSION, 'removeAllNamedPasswordsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.81': ('2.16.840.1.113719.1.14.100.81', OID_EXTENSION, 'listNamedPasswordsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.82': ('2.16.840.1.113719.1.14.100.82', OID_EXTENSION, 'listNamedPasswordsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.83': ('2.16.840.1.113719.1.14.100.83', OID_EXTENSION, 'getDefaultReciprocalAttrsMapRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.84': ('2.16.840.1.113719.1.14.100.84', OID_EXTENSION, 'getDefaultReciprocalAttrsMapResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.85': ('2.16.840.1.113719.1.14.100.85', OID_EXTENSION, 'resetDriverStatsRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.86': ('2.16.840.1.113719.1.14.100.86', OID_EXTENSION, 'resetDriverStatsResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.87': ('2.16.840.1.113719.1.14.100.87', OID_EXTENSION, 'regenerateAllKeysRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.88': ('2.16.840.1.113719.1.14.100.88', OID_EXTENSION, 'regenerateAllKeysResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.89': ('2.16.840.1.113719.1.14.100.89', OID_EXTENSION, 'getDriverGCVRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.90': ('2.16.840.1.113719.1.14.100.90', OID_EXTENSION, 'getDriverGCVResponse', 'NOVELL'), + '2.16.840.1.113719.1.14.100.91': ('2.16.840.1.113719.1.14.100.91', OID_EXTENSION, 'getNamedPasswordRequest', 'NOVELL'), + '2.16.840.1.113719.1.14.100.92': ('2.16.840.1.113719.1.14.100.92', OID_EXTENSION, 'getNamedPasswordResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.1': ('2.16.840.1.113719.1.27.100.1', OID_EXTENSION, 'ndsToLdapResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.2': ('2.16.840.1.113719.1.27.100.2', OID_EXTENSION, 'ndsToLdapRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.3': ('2.16.840.1.113719.1.27.100.3', OID_EXTENSION, 'splitPartitionRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.4': ('2.16.840.1.113719.1.27.100.4', OID_EXTENSION, 'splitPartitionResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.5': ('2.16.840.1.113719.1.27.100.5', OID_EXTENSION, 'mergePartitionRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.6': ('2.16.840.1.113719.1.27.100.6', OID_EXTENSION, 'mergePartitionResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.7': ('2.16.840.1.113719.1.27.100.7', OID_EXTENSION, 'addReplicaRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.8': ('2.16.840.1.113719.1.27.100.8', OID_EXTENSION, 'addReplicaResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.9': ('2.16.840.1.113719.1.27.100.9', OID_EXTENSION, 'refreshLDAPServerRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.10': ('2.16.840.1.113719.1.27.100.10', OID_EXTENSION, 'refreshLDAPServerResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.11': ('2.16.840.1.113719.1.27.100.11', OID_EXTENSION, 'removeReplicaRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.12': ('2.16.840.1.113719.1.27.100.12', OID_EXTENSION, 'removeReplicaResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.13': ('2.16.840.1.113719.1.27.100.13', OID_EXTENSION, 'partitionEntryCountRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.14': ('2.16.840.1.113719.1.27.100.14', OID_EXTENSION, 'partitionEntryCountResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.15': ('2.16.840.1.113719.1.27.100.15', OID_EXTENSION, 'changeReplicaTypeRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.16': ('2.16.840.1.113719.1.27.100.16', OID_EXTENSION, 'changeReplicaTypeResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.17': ('2.16.840.1.113719.1.27.100.17', OID_EXTENSION, 'getReplicaInfoRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.18': ('2.16.840.1.113719.1.27.100.18', OID_EXTENSION, 'getReplicaInfoResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.19': ('2.16.840.1.113719.1.27.100.19', OID_EXTENSION, 'listReplicaRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.20': ('2.16.840.1.113719.1.27.100.20', OID_EXTENSION, 'listReplicaResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.21': ('2.16.840.1.113719.1.27.100.21', OID_EXTENSION, 'receiveAllUpdatesRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.22': ('2.16.840.1.113719.1.27.100.22', OID_EXTENSION, 'receiveAllUpdatesResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.23': ('2.16.840.1.113719.1.27.100.23', OID_EXTENSION, 'sendAllUpdatesRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.24': ('2.16.840.1.113719.1.27.100.24', OID_EXTENSION, 'sendAllUpdatesResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.25': ('2.16.840.1.113719.1.27.100.25', OID_EXTENSION, 'requestPartitionSyncRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.26': ('2.16.840.1.113719.1.27.100.26', OID_EXTENSION, 'requestPartitionSyncResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.27': ('2.16.840.1.113719.1.27.100.27', OID_EXTENSION, 'requestSchemaSyncRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.28': ('2.16.840.1.113719.1.27.100.28', OID_EXTENSION, 'requestSchemaSyncResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.29': ('2.16.840.1.113719.1.27.100.29', OID_EXTENSION, 'abortPartitionOperationRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.30': ('2.16.840.1.113719.1.27.100.30', OID_EXTENSION, 'abortPartitionOperationResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.31': ('2.16.840.1.113719.1.27.100.31', OID_EXTENSION, 'getBindDNRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.32': ('2.16.840.1.113719.1.27.100.32', OID_EXTENSION, 'getBindDNResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.33': ('2.16.840.1.113719.1.27.100.33', OID_EXTENSION, 'getEffectivePrivilegesRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.34': ('2.16.840.1.113719.1.27.100.34', OID_EXTENSION, 'getEffectivePrivilegesResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.35': ('2.16.840.1.113719.1.27.100.35', OID_EXTENSION, 'setReplicationFilterRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.36': ('2.16.840.1.113719.1.27.100.36', OID_EXTENSION, 'setReplicationFilterResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.37': ('2.16.840.1.113719.1.27.100.37', OID_EXTENSION, 'getReplicationFilterRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.38': ('2.16.840.1.113719.1.27.100.38', OID_EXTENSION, 'getReplicationFilterResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.39': ('2.16.840.1.113719.1.27.100.39', OID_EXTENSION, 'splitOrphanPartitionRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.40': ('2.16.840.1.113719.1.27.100.40', OID_EXTENSION, 'splitOrphanPartitionResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.41': ('2.16.840.1.113719.1.27.100.41', OID_EXTENSION, 'removeOrphanPartitionRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.42': ('2.16.840.1.113719.1.27.100.42', OID_EXTENSION, 'removeOrphanPartitionResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.43': ('2.16.840.1.113719.1.27.100.43', OID_EXTENSION, 'triggerBKLinkerRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.44': ('2.16.840.1.113719.1.27.100.44', OID_EXTENSION, 'triggerBKLinkerResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.45': ('2.16.840.1.113719.1.27.100.45', OID_EXTENSION, 'triggerDRLProcessRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.46': ('2.16.840.1.113719.1.27.100.46', OID_EXTENSION, 'triggerDRLProcessResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.47': ('2.16.840.1.113719.1.27.100.47', OID_EXTENSION, 'triggerJanitorRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.48': ('2.16.840.1.113719.1.27.100.48', OID_EXTENSION, 'triggerJanitorResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.49': ('2.16.840.1.113719.1.27.100.49', OID_EXTENSION, 'triggerLimberRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.50': ('2.16.840.1.113719.1.27.100.50', OID_EXTENSION, 'triggerLimberResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.51': ('2.16.840.1.113719.1.27.100.51', OID_EXTENSION, 'triggerSkulkerRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.52': ('2.16.840.1.113719.1.27.100.52', OID_EXTENSION, 'triggerSkulkerResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.53': ('2.16.840.1.113719.1.27.100.53', OID_EXTENSION, 'triggerSchemaSyncRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.54': ('2.16.840.1.113719.1.27.100.54', OID_EXTENSION, 'triggerSchemaSyncResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.55': ('2.16.840.1.113719.1.27.100.55', OID_EXTENSION, 'triggerPartitionPurgeRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.56': ('2.16.840.1.113719.1.27.100.56', OID_EXTENSION, 'triggerPartitionPurgeResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.79': ('2.16.840.1.113719.1.27.100.79', OID_EXTENSION, 'eventMonitorRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.80': ('2.16.840.1.113719.1.27.100.80', OID_EXTENSION, 'eventMonitorResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.81': ('2.16.840.1.113719.1.27.100.81', OID_EXTENSION, 'nldapEventNotification', 'NOVELL'), + '2.16.840.1.113719.1.27.100.84': ('2.16.840.1.113719.1.27.100.84', OID_EXTENSION, 'filteredEventMonitorRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.85': ('2.16.840.1.113719.1.27.100.85', OID_EXTENSION, 'filteredEventMonitorResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.96': ('2.16.840.1.113719.1.27.100.96', OID_EXTENSION, 'ldapBackupRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.97': ('2.16.840.1.113719.1.27.100.97', OID_EXTENSION, 'ldapBackupResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.98': ('2.16.840.1.113719.1.27.100.98', OID_EXTENSION, 'ldapRestoreRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.99': ('2.16.840.1.113719.1.27.100.99', OID_EXTENSION, 'ldapRestoreResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.101': ('2.16.840.1.113719.1.27.100.101', OID_EXTENSION, 'LDAPDNStoX500DNRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.102': ('2.16.840.1.113719.1.27.100.102', OID_EXTENSION, 'LDAPDNStoX500DNResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.100.103': ('2.16.840.1.113719.1.27.100.103', OID_EXTENSION, 'getPrivilegesListRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.100.104': ('2.16.840.1.113719.1.27.100.104', OID_EXTENSION, 'getPrivilegesListResponse', 'NOVELL'), + '2.16.840.1.113719.1.27.103.1': ('2.16.840.1.113719.1.27.103.1', OID_EXTENSION, 'createGroupingRequest', 'NOVELL'), + '2.16.840.1.113719.1.27.103.2': ('2.16.840.1.113719.1.27.103.2', OID_EXTENSION, 'endGroupingRequest', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.1': ('2.16.840.1.113719.1.39.42.100.1', OID_EXTENSION, 'NMAS Put Login Configuration', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.3': ('2.16.840.1.113719.1.39.42.100.3', OID_EXTENSION, 'NMAS Get Login Configuration', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.5': ('2.16.840.1.113719.1.39.42.100.5', OID_EXTENSION, 'NMAS Delete Login Configuration', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.7': ('2.16.840.1.113719.1.49.42.100.7', OID_EXTENSION, 'NMAS Put Login Secret', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.9': ('2.16.840.1.113719.1.39.42.100.9', OID_EXTENSION, 'NMAS Delete Login Secret', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.11': ('2.16.840.1.113719.1.39.42.100.11', OID_EXTENSION, 'NMAS Set Universal Password Request', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.12': ('2.16.840.1.113719.1.39.42.100.12', OID_EXTENSION, 'NMAS Set Universal Password Response', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.13': ('2.16.840.1.113719.1.39.42.100.13', OID_EXTENSION, 'NMAS Get Universal Password Request', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.14': ('2.16.840.1.113719.1.39.42.100.14', OID_EXTENSION, 'NMAS Get Universal Password Response', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.15': ('2.16.840.1.113719.1.39.42.100.15', OID_EXTENSION, 'NMAS Delete Universal Password', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.17': ('2.16.840.1.113719.1.39.42.100.17', OID_EXTENSION, 'NMAS Check password against password policy', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.19': ('2.16.840.1.113719.1.39.42.100.19', OID_EXTENSION, 'NMAS Get password policy information', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.21': ('2.16.840.1.113719.1.39.42.100.21', OID_EXTENSION, 'NMAS Change Universal Password', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.23': ('2.16.840.1.113719.1.39.42.100.23', OID_EXTENSION, 'NMAS Graded Authentication management', 'NOVELL'), + '2.16.840.1.113719.1.39.42.100.25': ('2.16.840.1.113719.1.39.42.100.25', OID_EXTENSION, 'NMAS management (new with NMAS 3.1.0)', 'NOVELL'), + '2.16.840.1.113719.1.142.1.4.1': ('2.16.840.1.113719.1.142.1.4.1', OID_EXTENSION, 'LBURPIncUpdate', 'NOVELL'), + '2.16.840.1.113719.1.142.1.4.2': ('2.16.840.1.113719.1.142.1.4.2', OID_EXTENSION, 'LBURPFullUpdate', 'NOVELL'), + '2.16.840.1.113719.1.142.100.1': ('2.16.840.1.113719.1.142.100.1', OID_EXTENSION, 'LBURPStartReplRequest', 'NOVELL'), + '2.16.840.1.113719.1.142.100.2': ('2.16.840.1.113719.1.142.100.2', OID_EXTENSION, 'LBURPStartReplResponse', 'NOVELL'), + '2.16.840.1.113719.1.142.100.4': ('2.16.840.1.113719.1.142.100.4', OID_EXTENSION, 'LBURPEndReplRequest', 'NOVELL'), + '2.16.840.1.113719.1.142.100.5': ('2.16.840.1.113719.1.142.100.5', OID_EXTENSION, 'LBURPEndReplResponse', 'NOVELL'), + '2.16.840.1.113719.1.142.100.6': ('2.16.840.1.113719.1.142.100.6', OID_EXTENSION, 'LBURPOperationRequest', 'NOVELL'), + '2.16.840.1.113719.1.142.100.7': ('2.16.840.1.113719.1.142.100.7', OID_EXTENSION, 'LBURPOperationResponse', 'NOVELL'), + '2.16.840.1.113719.1.148.100.1': ('2.16.840.1.113719.1.148.100.1', OID_EXTENSION, 'SSLDAP_GET_SERVICE_INFO_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.2': ('2.16.840.1.113719.1.148.100.2', OID_EXTENSION, 'SSLDAP_GET_SERVICE_INFO_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.3': ('2.16.840.1.113719.1.148.100.3', OID_EXTENSION, 'SSLDAP_READ_SECRET_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.4': ('2.16.840.1.113719.1.148.100.4', OID_EXTENSION, 'SSLDAP_READ_SECRET_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.5': ('2.16.840.1.113719.1.148.100.5', OID_EXTENSION, 'SSLDAP_WRITE_SECRET_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.6': ('2.16.840.1.113719.1.148.100.6', OID_EXTENSION, 'SSLDAP_WRITE_SECRET_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.7': ('2.16.840.1.113719.1.148.100.7', OID_EXTENSION, 'SSLDAP_ADD_SECRET_ID_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.8': ('2.16.840.1.113719.1.148.100.8', OID_EXTENSION, 'SSLDAP_ADD_SECRET_ID_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.9': ('2.16.840.1.113719.1.148.100.9', OID_EXTENSION, 'SSLDAP_REMOVE_SECRET_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.10': ('2.16.840.1.113719.1.148.100.10', OID_EXTENSION, 'SSLDAP_REMOVE_SECRET_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.11': ('2.16.840.1.113719.1.148.100.11', OID_EXTENSION, 'SSLDAP_REMOVE_SECRET_STORE_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.12': ('2.16.840.1.113719.1.148.100.12', OID_EXTENSION, 'SSLDAP_REMOVE_SECRET_STORE_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.13': ('2.16.840.1.113719.1.148.100.13', OID_EXTENSION, 'SSLDAP_ENUMERATE_SECRET_IDS_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.14': ('2.16.840.1.113719.1.148.100.14', OID_EXTENSION, 'SSLDAP_ENUMERATE_SECRET_IDS_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.15': ('2.16.840.1.113719.1.148.100.15', OID_EXTENSION, 'SSLDAP_UNLOCK_SECRETS_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.16': ('2.16.840.1.113719.1.148.100.16', OID_EXTENSION, 'SSLDAP_UNLOCK_SECRETS_REPLY', 'NOVELL'), + '2.16.840.1.113719.1.148.100.17': ('2.16.840.1.113719.1.148.100.17', OID_EXTENSION, 'SSLDAP_SET_EP_MASTER_PASSWORD_REQUEST', 'NOVELL'), + '2.16.840.1.113719.1.148.100.18': ('2.16.840.1.113719.1.148.100.18', OID_EXTENSION, 'SSLDAP_SET_EP_MASTER_PASSWORD_REPLY', 'NOVELL'), + '2.16.840.1.113730.3.5.1': ('2.16.840.1.113730.3.5.1', OID_EXTENSION, 'Transaction Request Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.2': ('2.16.840.1.113730.3.5.2', OID_EXTENSION, 'Transaction Response Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.3': ('2.16.840.1.113730.3.5.3', OID_EXTENSION, 'Transaction Response Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.4': ('2.16.840.1.113730.3.5.4', OID_EXTENSION, 'iPlanet Replication Response Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.5': ('2.16.840.1.113730.3.5.5', OID_EXTENSION, 'iPlanet End Replication Request Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.6': ('2.16.840.1.113730.3.5.6', OID_EXTENSION, 'iPlanet Replication Entry Request Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.7': ('2.16.840.1.113730.3.5.7', OID_EXTENSION, 'iPlanet Bulk Import Start Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.8': ('2.16.840.1.113730.3.5.8', OID_EXTENSION, 'iPlanet Bulk Import Finished Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.9': ('2.16.840.1.113730.3.5.9', OID_EXTENSION, 'iPlanet Digest Authentication Calculation Extended Operation', 'Netscape'), + '2.16.840.1.113730.3.5.10': ('2.16.840.1.113730.3.5.10', OID_EXTENSION, 'Distributed Numeric Assignment Extended Request', 'Netscape'), + '2.16.840.1.113730.3.5.11': ('2.16.840.1.113730.3.5.11', OID_EXTENSION, 'Distributed Numeric Assignment Extended Response', 'Netscape'), + '2.16.840.1.113730.3.5.12': ('2.16.840.1.113730.3.5.12', OID_EXTENSION, 'Start replication request', 'Netscape'), + '2.16.840.1.113730.3.5.13': ('2.16.840.1.113730.3.5.13', OID_EXTENSION, 'Start replication response', 'Netscape'), + '2.16.840.1.113730.3.6.5': ('2.16.840.1.113730.3.6.5', OID_EXTENSION, 'Replication CleanAllRUV', 'Netscape'), + '2.16.840.1.113730.3.6.6': ('2.16.840.1.113730.3.6.6', OID_EXTENSION, 'Replication Abort CleanAllRUV', 'Netscape'), + '2.16.840.1.113730.3.6.7': ('2.16.840.1.113730.3.6.7', OID_EXTENSION, 'Replication CleanAllRUV Retrieve MaxCSN', 'Netscape'), + '2.16.840.1.113730.3.6.8': ('2.16.840.1.113730.3.6.8', OID_EXTENSION, 'Replication CleanAllRUV Check Status', 'Netscape'), + '2.16.840.1.113730.3.8.10.1': ('2.16.840.1.113730.3.8.10.1', OID_EXTENSION, 'KeyTab set', 'FreeIPA'), + '2.16.840.1.113730.3.8.10.2': ('2.16.840.1.113730.3.8.10.2', OID_EXTENSION, 'KeyTab ret', 'FreeIPA'), + '2.16.840.1.113730.3.8.10.3': ('2.16.840.1.113730.3.8.10.3', OID_EXTENSION, 'Enrollment join', 'FreeIPA'), + '2.16.840.1.113730.3.8.10.5': ('2.16.840.1.113730.3.8.10.5', OID_EXTENSION, 'KeyTab get', 'FreeIPA'), + + # features (capabilities) + '1.2.840.113556.1.4.800': ('1.2.840.113556.1.4.800', OID_FEATURE, 'Active directory', 'MICROSOFT'), + '1.2.840.113556.1.4.1670': ('1.2.840.113556.1.4.1670', OID_FEATURE, 'Active directory V51', 'MICROSOFT'), + '1.2.840.113556.1.4.1791': ('1.2.840.113556.1.4.1791', OID_FEATURE, 'Active directory LDAP Integration', 'MICROSOFT'), + '1.2.840.113556.1.4.1880': ('1.2.840.113556.1.4.1880', OID_FEATURE, 'Active directory ADAM digest', 'MICROSOFT'), + '1.2.840.113556.1.4.1851': ('1.2.840.113556.1.4.1851', OID_FEATURE, 'Active directory ADAM', 'MICROSOFT'), + '1.2.840.113556.1.4.1920': ('1.2.840.113556.1.4.1920', OID_FEATURE, 'Active directory partial secrets', 'MICROSOFT'), + '1.2.840.113556.1.4.1935': ('1.2.840.113556.1.4.1935', OID_FEATURE, 'Active directory V60', 'MICROSOFT'), + '1.2.840.113556.1.4.2080': ('1.2.840.113556.1.4.2080', OID_FEATURE, 'Active directory V61 R2', 'MICROSOFT'), + '1.2.840.113556.1.4.2237': ('1.2.840.113556.1.4.2237', OID_FEATURE, 'Active directory W8', 'MICROSOFT'), + '1.3.6.1.1.14': ('1.3.6.1.1.14', OID_FEATURE, 'Modify-Increment', 'RFC4525'), + '1.3.6.1.1.17.7': ('1.3.6.1.1.17.7', OID_FEATURE, 'LBURP Incremental Update style OID', 'RFC4373'), + '1.3.6.1.4.1.4203.1.5.1': ('1.3.6.1.4.1.4203.1.5.1', OID_FEATURE, 'All Op Attrs', 'RFC3673'), + '1.3.6.1.4.1.4203.1.5.2': ('1.3.6.1.4.1.4203.1.5.2', OID_FEATURE, 'OC AD Lists', 'RFC4529'), + '1.3.6.1.4.1.4203.1.5.3': ('1.3.6.1.4.1.4203.1.5.3', OID_FEATURE, 'True/False filters', 'RFC4526'), + '1.3.6.1.4.1.4203.1.5.4': ('1.3.6.1.4.1.4203.1.5.4', OID_FEATURE, 'Language Tag Options', 'RFC3866'), + '1.3.6.1.4.1.4203.1.5.5': ('1.3.6.1.4.1.4203.1.5.5', OID_FEATURE, 'language Range Options', 'RFC3866'), + '2.16.840.1.113719.1.27.99.1': ('2.16.840.1.113719.1.27.99.1', OID_FEATURE, 'Superior References', 'NOVELL'), + + # ldap syntaxes + '1.2.840.113556.1.4.903': ('1.2.840.113556.1.4.903', OID_LDAP_SYNTAX, 'Object (DN-binary)', 'MICROSOFT'), + '1.2.840.113556.1.4.904': ('1.2.840.113556.1.4.904', OID_LDAP_SYNTAX, 'Object(DN-string)', 'MICROSOFT'), + '1.2.840.113556.1.4.905': ('1.2.840.113556.1.4.905', OID_LDAP_SYNTAX, 'String (Teletex)', 'MICROSOFT'), + '1.2.840.113556.1.4.906': ('1.2.840.113556.1.4.906', OID_LDAP_SYNTAX, 'Large Integer', 'MICROSOFT'), + '1.2.840.113556.1.4.907': ('1.2.840.113556.1.4.907', OID_LDAP_SYNTAX, 'String (NT-Sec-Desc)', 'MICROSOFT'), + '1.2.840.113556.1.4.1221': ('1.2.840.113556.1.4.1221', OID_LDAP_SYNTAX, 'Object (OR-Name)', 'MICROSOFT'), + '1.2.840.113556.1.4.1362': ('1.2.840.113556.1.4.1362', OID_LDAP_SYNTAX, 'String (Case)', 'MICROSOFT'), + '1.3.6.1.1.16.1': ('1.3.6.1.1.16.1', OID_LDAP_SYNTAX, 'Universally Unique Identifier (UUID)', 'RFC4530'), + '1.3.6.1.4.1.1466.115.121.1.1': ('1.3.6.1.4.1.1466.115.121.1.1', OID_LDAP_SYNTAX, 'ACI item [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.2': ('1.3.6.1.4.1.1466.115.121.1.2', OID_LDAP_SYNTAX, 'Access point [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.3': ('1.3.6.1.4.1.1466.115.121.1.3', OID_LDAP_SYNTAX, 'Attribute Type Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.4': ('1.3.6.1.4.1.1466.115.121.1.4', OID_LDAP_SYNTAX, 'Audio [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.5': ('1.3.6.1.4.1.1466.115.121.1.5', OID_LDAP_SYNTAX, 'Binary [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.6': ('1.3.6.1.4.1.1466.115.121.1.6', OID_LDAP_SYNTAX, 'Bit String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.7': ('1.3.6.1.4.1.1466.115.121.1.7', OID_LDAP_SYNTAX, 'Boolean', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.8': ('1.3.6.1.4.1.1466.115.121.1.8', OID_LDAP_SYNTAX, 'Certificate [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.9': ('1.3.6.1.4.1.1466.115.121.1.9', OID_LDAP_SYNTAX, 'Certificate List [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.10': ('1.3.6.1.4.1.1466.115.121.1.10', OID_LDAP_SYNTAX, 'Certificate Pair [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.11': ('1.3.6.1.4.1.1466.115.121.1.11', OID_LDAP_SYNTAX, 'Country String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.12': ('1.3.6.1.4.1.1466.115.121.1.12', OID_LDAP_SYNTAX, 'DN', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.13': ('1.3.6.1.4.1.1466.115.121.1.13', OID_LDAP_SYNTAX, 'Data Quality Syntax [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.14': ('1.3.6.1.4.1.1466.115.121.1.14', OID_LDAP_SYNTAX, 'Delivery Method', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.15': ('1.3.6.1.4.1.1466.115.121.1.15', OID_LDAP_SYNTAX, 'Directory String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.16': ('1.3.6.1.4.1.1466.115.121.1.16', OID_LDAP_SYNTAX, 'DIT Content Rule Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.17': ('1.3.6.1.4.1.1466.115.121.1.17', OID_LDAP_SYNTAX, 'DIT Structure Rule Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.18': ('1.3.6.1.4.1.1466.115.121.1.18', OID_LDAP_SYNTAX, 'DL Submit Permission [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.19': ('1.3.6.1.4.1.1466.115.121.1.19', OID_LDAP_SYNTAX, 'DSA Quality Syntax [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.20': ('1.3.6.1.4.1.1466.115.121.1.20', OID_LDAP_SYNTAX, 'DSE Type [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.21': ('1.3.6.1.4.1.1466.115.121.1.21', OID_LDAP_SYNTAX, 'Enhanced Guide', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.22': ('1.3.6.1.4.1.1466.115.121.1.22', OID_LDAP_SYNTAX, 'Facsimile Telephone Number', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.23': ('1.3.6.1.4.1.1466.115.121.1.23', OID_LDAP_SYNTAX, 'Fax', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.24': ('1.3.6.1.4.1.1466.115.121.1.24', OID_LDAP_SYNTAX, 'Generalized Time', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.25': ('1.3.6.1.4.1.1466.115.121.1.25', OID_LDAP_SYNTAX, 'Guide [OBSOLETE]', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.26': ('1.3.6.1.4.1.1466.115.121.1.26', OID_LDAP_SYNTAX, 'IA5 String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.27': ('1.3.6.1.4.1.1466.115.121.1.27', OID_LDAP_SYNTAX, 'Integer', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.28': ('1.3.6.1.4.1.1466.115.121.1.28', OID_LDAP_SYNTAX, 'JPEG', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.29': ('1.3.6.1.4.1.1466.115.121.1.29', OID_LDAP_SYNTAX, 'Master and Shadow Access Points [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.30': ('1.3.6.1.4.1.1466.115.121.1.30', OID_LDAP_SYNTAX, 'Matching Rule Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.31': ('1.3.6.1.4.1.1466.115.121.1.31', OID_LDAP_SYNTAX, 'Matching Rule Use Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.32': ('1.3.6.1.4.1.1466.115.121.1.32', OID_LDAP_SYNTAX, 'Mail Preference [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.33': ('1.3.6.1.4.1.1466.115.121.1.33', OID_LDAP_SYNTAX, 'MHS OR Address [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.34': ('1.3.6.1.4.1.1466.115.121.1.34', OID_LDAP_SYNTAX, 'Name And Optional UID', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.35': ('1.3.6.1.4.1.1466.115.121.1.35', OID_LDAP_SYNTAX, 'Name Form Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.36': ('1.3.6.1.4.1.1466.115.121.1.36', OID_LDAP_SYNTAX, 'Numeric String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.37': ('1.3.6.1.4.1.1466.115.121.1.37', OID_LDAP_SYNTAX, 'Object Class Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.38': ('1.3.6.1.4.1.1466.115.121.1.38', OID_LDAP_SYNTAX, 'OID', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.39': ('1.3.6.1.4.1.1466.115.121.1.39', OID_LDAP_SYNTAX, 'Other Mailbox', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.40': ('1.3.6.1.4.1.1466.115.121.1.40', OID_LDAP_SYNTAX, 'Octet String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.41': ('1.3.6.1.4.1.1466.115.121.1.41', OID_LDAP_SYNTAX, 'Postal Address', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.42': ('1.3.6.1.4.1.1466.115.121.1.42', OID_LDAP_SYNTAX, 'Protocol Information [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.43': ('1.3.6.1.4.1.1466.115.121.1.43', OID_LDAP_SYNTAX, 'Presentation Address [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.44': ('1.3.6.1.4.1.1466.115.121.1.44', OID_LDAP_SYNTAX, 'Printable String', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.45': ('1.3.6.1.4.1.1466.115.121.1.45', OID_LDAP_SYNTAX, 'Subtree specification [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.46': ('1.3.6.1.4.1.1466.115.121.1.46', OID_LDAP_SYNTAX, 'Supplier Information [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.47': ('1.3.6.1.4.1.1466.115.121.1.47', OID_LDAP_SYNTAX, 'Supplier Or Consumer [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.48': ('1.3.6.1.4.1.1466.115.121.1.48', OID_LDAP_SYNTAX, 'Supplier And Consumer [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.49': ('1.3.6.1.4.1.1466.115.121.1.49', OID_LDAP_SYNTAX, 'Supported Algorithm [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.50': ('1.3.6.1.4.1.1466.115.121.1.50', OID_LDAP_SYNTAX, 'Telephone Number', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.51': ('1.3.6.1.4.1.1466.115.121.1.51', OID_LDAP_SYNTAX, 'Teletex Terminal Identifier', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.52': ('1.3.6.1.4.1.1466.115.121.1.52', OID_LDAP_SYNTAX, 'Telex Number', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.53': ('1.3.6.1.4.1.1466.115.121.1.53', OID_LDAP_SYNTAX, 'UTC Time [DEPRECATED]', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.54': ('1.3.6.1.4.1.1466.115.121.1.54', OID_LDAP_SYNTAX, 'LDAP Syntax Description', 'RFC4517'), + '1.3.6.1.4.1.1466.115.121.1.55': ('1.3.6.1.4.1.1466.115.121.1.55', OID_LDAP_SYNTAX, 'Modify rights [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.56': ('1.3.6.1.4.1.1466.115.121.1.56', OID_LDAP_SYNTAX, 'LDAP Schema Definition [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.57': ('1.3.6.1.4.1.1466.115.121.1.57', OID_LDAP_SYNTAX, 'LDAP Schema Description [OBSOLETE]', 'RFC2252'), + '1.3.6.1.4.1.1466.115.121.1.58': ('1.3.6.1.4.1.1466.115.121.1.58', OID_LDAP_SYNTAX, 'Substring Assertion', 'RFC4517'), + '2.16.840.1.113719.1.1.5.1.0': ('2.16.840.1.113719.1.1.5.1.0', OID_LDAP_SYNTAX, 'Unknown', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.6': ('2.16.840.1.113719.1.1.5.1.6', OID_LDAP_SYNTAX, 'Case Ignore List', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.12': ('2.16.840.1.113719.1.1.5.1.12', OID_LDAP_SYNTAX, 'Tagged Data', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.13': ('2.16.840.1.113719.1.1.5.1.13', OID_LDAP_SYNTAX, 'Octet List', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.14': ('2.16.840.1.113719.1.1.5.1.14', OID_LDAP_SYNTAX, 'Tagged String', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.15': ('2.16.840.1.113719.1.1.5.1.15', OID_LDAP_SYNTAX, 'Tagged Name And String', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.16': ('2.16.840.1.113719.1.1.5.1.16', OID_LDAP_SYNTAX, 'NDS Replica Pointer', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.17': ('2.16.840.1.113719.1.1.5.1.17', OID_LDAP_SYNTAX, 'NDS ACL', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.19': ('2.16.840.1.113719.1.1.5.1.19', OID_LDAP_SYNTAX, 'NDS Timestamp', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.22': ('2.16.840.1.113719.1.1.5.1.22', OID_LDAP_SYNTAX, 'Counter', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.23': ('2.16.840.1.113719.1.1.5.1.23', OID_LDAP_SYNTAX, 'Tagged Name', 'NOVELL'), + '2.16.840.1.113719.1.1.5.1.25': ('2.16.840.1.113719.1.1.5.1.25', OID_LDAP_SYNTAX, 'Typed Name', 'NOVELL'), + + # ldap url extensions + + # matching rules + '1.2.36.79672281.1.13.2': ('1.2.36.79672281.1.13.2', OID_MATCHING_RULE, 'componentFilterMatch', 'RFC3687'), + '1.2.36.79672281.1.13.3': ('1.2.36.79672281.1.13.3', OID_MATCHING_RULE, 'rdnMatch', 'RFC3687'), + '1.2.36.79672281.1.13.5': ('1.2.36.79672281.1.13.5', OID_MATCHING_RULE, 'presentMatch', 'RFC3687'), + '1.2.36.79672281.1.13.6': ('1.2.36.79672281.1.13.6', OID_MATCHING_RULE, 'allComponentsMatch', 'RFC3687'), + '1.2.36.79672281.1.13.7': ('1.2.36.79672281.1.13.7', OID_MATCHING_RULE, 'directoryComponentsMatch', 'RFC3687'), + '1.2.840.113556.1.4.803': ('1.2.840.113556.1.4.803', OID_MATCHING_RULE, 'Bit AND', 'MICROSOFT'), + '1.2.840.113556.1.4.804': ('1.2.840.113556.1.4.804', OID_MATCHING_RULE, 'Bit OR', 'MICROSOFT'), + '1.2.840.113556.1.4.1941': ('1.2.840.113556.1.4.1941', OID_MATCHING_RULE, 'Transitive Evaluation', 'MICROSOFT'), + '1.2.840.113556.1.4.2253': ('1.2.840.113556.1.4.2253', OID_MATCHING_RULE, 'DN with data', 'MICROSOFT'), + '1.3.6.1.1.16.2': ('1.3.6.1.1.16.2', OID_MATCHING_RULE, 'uuidMatch', 'RFC4530'), + '1.3.6.1.1.16.3': ('1.3.6.1.1.16.3', OID_MATCHING_RULE, 'uuidOrderingMatch', 'RFC4530'), + '1.3.6.1.4.1.1466.109.114.1': ('1.3.6.1.4.1.1466.109.114.1', OID_MATCHING_RULE, 'caseExactIA5Match', 'RFC4517'), + '1.3.6.1.4.1.1466.109.114.2': ('1.3.6.1.4.1.1466.109.114.2', OID_MATCHING_RULE, 'caseIgnoreIA5Match', 'RFC4517'), + '1.3.6.1.4.1.1466.109.114.3': ('1.3.6.1.4.1.1466.109.114.3', OID_MATCHING_RULE, 'caseIgnoreIA5SubstringsMatch', 'RFC4517'), + '2.5.13.0': ('2.5.13.0', OID_MATCHING_RULE, 'objectIdentifierMatch', 'RFC4517'), + '2.5.13.1': ('2.5.13.1', OID_MATCHING_RULE, 'distinguishedNameMatch', 'RFC4517'), + '2.5.13.2': ('2.5.13.2', OID_MATCHING_RULE, 'caseIgnoreMatch', 'RFC4517'), + '2.5.13.3': ('2.5.13.3', OID_MATCHING_RULE, 'caseIgnoreOrderingMatch', 'RFC4517'), + '2.5.13.4': ('2.5.13.4', OID_MATCHING_RULE, 'caseIgnoreSubstringsMatch', 'RFC4517'), + '2.5.13.5': ('2.5.13.5', OID_MATCHING_RULE, 'caseExactMatch', 'RFC4517'), + '2.5.13.6': ('2.5.13.6', OID_MATCHING_RULE, 'caseExactOrderingMatch', 'RFC4517'), + '2.5.13.7': ('2.5.13.7', OID_MATCHING_RULE, 'caseExactSubstringsMatch', 'RFC4517'), + '2.5.13.8': ('2.5.13.8', OID_MATCHING_RULE, 'numericStringMatch', 'RFC4517'), + '2.5.13.9': ('2.5.13.9', OID_MATCHING_RULE, 'numericStringOrderingMatch', 'RFC4517'), + '2.5.13.10': ('2.5.13.10', OID_MATCHING_RULE, 'numericStringSubstringsMatch', 'RFC4517'), + '2.5.13.11': ('2.5.13.11', OID_MATCHING_RULE, 'caseIgnoreListMatch', 'RFC4517'), + '2.5.13.12': ('2.5.13.12', OID_MATCHING_RULE, 'caseIgnoreListSubstringsMatch', 'RFC4517'), + '2.5.13.13': ('2.5.13.13', OID_MATCHING_RULE, 'booleanMatch', 'RFC4517'), + '2.5.13.14': ('2.5.13.14', OID_MATCHING_RULE, 'integerMatch', 'RFC4517'), + '2.5.13.15': ('2.5.13.15', OID_MATCHING_RULE, 'integerOrderingMatch', 'RFC4517'), + '2.5.13.16': ('2.5.13.16', OID_MATCHING_RULE, 'bitStringMatch', 'RFC4517'), + '2.5.13.17': ('2.5.13.17', OID_MATCHING_RULE, 'octetStringMatch', 'RFC4517'), + '2.5.13.18': ('2.5.13.18', OID_MATCHING_RULE, 'octetStringOrderingMatch', 'RFC4517'), + '2.5.13.20': ('2.5.13.20', OID_MATCHING_RULE, 'telephoneNumberMatch', 'RFC4517'), + '2.5.13.21': ('2.5.13.21', OID_MATCHING_RULE, 'telephoneNumberSubstringsMatch', 'RFC4517'), + '2.5.13.22': ('2.5.13.22', OID_MATCHING_RULE, 'presentationAddressMatch', 'RFC2252'), + '2.5.13.23': ('2.5.13.23', OID_MATCHING_RULE, 'uniqueMemberMatch', 'RFC4517'), + '2.5.13.24': ('2.5.13.24', OID_MATCHING_RULE, 'protocolInformationMatch', 'RFC2252'), + '2.5.13.27': ('2.5.13.27', OID_MATCHING_RULE, 'generalizedTimeMatch', 'RFC4517'), + '2.5.13.28': ('2.5.13.28', OID_MATCHING_RULE, 'generalizedTimeOrderingMatch', 'RFC4517'), + '2.5.13.29': ('2.5.13.29', OID_MATCHING_RULE, 'integerFirstComponentMatch', 'RFC4517'), + '2.5.13.30': ('2.5.13.30', OID_MATCHING_RULE, 'objectIdentifierFirstComponentMatch', 'RFC4517'), + '2.5.13.31': ('2.5.13.31', OID_MATCHING_RULE, 'directoryStringFirstComponentMatch', 'RFC4517'), + '2.5.13.32': ('2.5.13.32', OID_MATCHING_RULE, 'wordMatch', 'RFC4517'), + '2.5.13.33': ('2.5.13.33', OID_MATCHING_RULE, 'keywordMatch', 'RFC4517'), + '2.5.13.34': ('2.5.13.34', OID_MATCHING_RULE, 'certificateExactMatch', 'RFC4523'), + '2.5.13.35': ('2.5.13.35', OID_MATCHING_RULE, 'certificateMatch', 'RFC4523'), + '2.5.13.36': ('2.5.13.36', OID_MATCHING_RULE, 'certificatePairExactMatch', 'RFC4523'), + '2.5.13.37': ('2.5.13.37', OID_MATCHING_RULE, 'certificatePairMatch', 'RFC4523'), + '2.5.13.38': ('2.5.13.38', OID_MATCHING_RULE, 'certificateListExactMatch', 'RFC4523'), + '2.5.13.39': ('2.5.13.39', OID_MATCHING_RULE, 'certificateListMatch', 'RFC4523'), + '2.5.13.40': ('2.5.13.40', OID_MATCHING_RULE, 'algorithmIdentifierMatch', 'RFC4523'), + '2.5.13.41': ('2.5.13.41', OID_MATCHING_RULE, 'storedPrefixMatch', 'RFC3698'), + + # name forms + '1.3.6.1.1.10.15.1': ('1.3.6.1.1.10.15.1', OID_NAME_FORM, 'uddiBusinessEntityNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.2': ('1.3.6.1.1.10.15.2', OID_NAME_FORM, 'uddiContactNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.3': ('1.3.6.1.1.10.15.3', OID_NAME_FORM, 'uddiAddressNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.4': ('1.3.6.1.1.10.15.4', OID_NAME_FORM, 'uddiBusinessServiceNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.5': ('1.3.6.1.1.10.15.5', OID_NAME_FORM, 'uddiBindingTemplateNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.6': ('1.3.6.1.1.10.15.6', OID_NAME_FORM, 'uddiTModelInstanceInfoNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.7': ('1.3.6.1.1.10.15.7', OID_NAME_FORM, 'uddiTModelNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.8': ('1.3.6.1.1.10.15.8', OID_NAME_FORM, 'uddiPublisherAssertionNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.9': ('1.3.6.1.1.10.15.9', OID_NAME_FORM, 'uddiv3SubscriptionNameForm', 'RFC4403'), + '1.3.6.1.1.10.15.10': ('1.3.6.1.1.10.15.10', OID_NAME_FORM, 'uddiv3EntityObituaryNameForm', 'RFC4403'), + '1.3.6.1.4.1.1466.345': ('1.3.6.1.4.1.1466.345', OID_NAME_FORM, 'domainNameForm', 'RFC2247'), + + # object classes + '0.9.2342.19200300.100.4.3': ('0.9.2342.19200300.100.4.3', OID_OBJECT_CLASS, 'pilotObject', 'RFC1274'), + '0.9.2342.19200300.100.4.4': ('0.9.2342.19200300.100.4.4', OID_OBJECT_CLASS, 'pilotPerson', 'RFC1274'), + '0.9.2342.19200300.100.4.5': ('0.9.2342.19200300.100.4.5', OID_OBJECT_CLASS, 'account', 'RFC4524'), + '0.9.2342.19200300.100.4.6': ('0.9.2342.19200300.100.4.6', OID_OBJECT_CLASS, 'document', 'RFC4524'), + '0.9.2342.19200300.100.4.7': ('0.9.2342.19200300.100.4.7', OID_OBJECT_CLASS, 'room', 'RFC4524'), + '0.9.2342.19200300.100.4.8': ('0.9.2342.19200300.100.4.8', OID_OBJECT_CLASS, 'documentSeries', 'RFC4524'), + '0.9.2342.19200300.100.4.13': ('0.9.2342.19200300.100.4.13', OID_OBJECT_CLASS, 'domain', 'RFC4524'), + '0.9.2342.19200300.100.4.14': ('0.9.2342.19200300.100.4.14', OID_OBJECT_CLASS, 'RFC822LocalPart', 'RFC4524'), + '0.9.2342.19200300.100.4.15': ('0.9.2342.19200300.100.4.15', OID_OBJECT_CLASS, 'dNSDomain', 'RFC1274'), + '0.9.2342.19200300.100.4.17': ('0.9.2342.19200300.100.4.17', OID_OBJECT_CLASS, 'domainRelatedObject', 'RFC4524'), + '0.9.2342.19200300.100.4.18': ('0.9.2342.19200300.100.4.18', OID_OBJECT_CLASS, 'friendlyCountry', 'RFC4524'), + '0.9.2342.19200300.100.4.19': ('0.9.2342.19200300.100.4.19', OID_OBJECT_CLASS, 'simpleSecurityObject', 'RFC4524'), + '0.9.2342.19200300.100.4.20': ('0.9.2342.19200300.100.4.20', OID_OBJECT_CLASS, 'pilotOrganization', 'RFC1274'), + '0.9.2342.19200300.100.4.21': ('0.9.2342.19200300.100.4.21', OID_OBJECT_CLASS, 'pilotDSA', 'RFC1274'), + '0.9.2342.19200300.100.4.22': ('0.9.2342.19200300.100.4.22', OID_OBJECT_CLASS, 'qualityLabelledData', 'RFC1274'), + '1.2.840.113556.1.5.87': ('1.2.840.113556.1.5.87', OID_OBJECT_CLASS, 'calEntry', 'RFC2739'), + '1.3.18.0.2.6.253': ('1.3.18.0.2.6.253', OID_OBJECT_CLASS, 'printerLPR', 'RFC3712'), + '1.3.18.0.2.6.254': ('1.3.18.0.2.6.254', OID_OBJECT_CLASS, 'slpServicePrinter', 'RFC3712'), + '1.3.18.0.2.6.255': ('1.3.18.0.2.6.255', OID_OBJECT_CLASS, 'printerService', 'RFC3712'), + '1.3.18.0.2.6.256': ('1.3.18.0.2.6.256', OID_OBJECT_CLASS, 'printerIPP', 'RFC3712'), + '1.3.18.0.2.6.257': ('1.3.18.0.2.6.257', OID_OBJECT_CLASS, 'printerServiceAuxClass', 'RFC3712'), + '1.3.18.0.2.6.258': ('1.3.18.0.2.6.258', OID_OBJECT_CLASS, 'printerAbstract', 'RFC3712'), + '1.3.6.1.1.10.6.1': ('1.3.6.1.1.10.6.1', OID_OBJECT_CLASS, 'uddiBusinessEntity', 'RFC4403'), + '1.3.6.1.1.10.6.2': ('1.3.6.1.1.10.6.2', OID_OBJECT_CLASS, 'uddiContact', 'RFC4403'), + '1.3.6.1.1.10.6.3': ('1.3.6.1.1.10.6.3', OID_OBJECT_CLASS, 'uddiAddress', 'RFC4403'), + '1.3.6.1.1.10.6.4': ('1.3.6.1.1.10.6.4', OID_OBJECT_CLASS, 'uddiBusinessService', 'RFC4403'), + '1.3.6.1.1.10.6.5': ('1.3.6.1.1.10.6.5', OID_OBJECT_CLASS, 'uddiBindingTemplate', 'RFC4403'), + '1.3.6.1.1.10.6.6': ('1.3.6.1.1.10.6.6', OID_OBJECT_CLASS, 'uddiTModelInstanceInfo', 'RFC4403'), + '1.3.6.1.1.10.6.7': ('1.3.6.1.1.10.6.7', OID_OBJECT_CLASS, 'uddiTModel', 'RFC4403'), + '1.3.6.1.1.10.6.8': ('1.3.6.1.1.10.6.8', OID_OBJECT_CLASS, 'uddiPublisherAssertion', 'RFC4403'), + '1.3.6.1.1.10.6.9': ('1.3.6.1.1.10.6.9', OID_OBJECT_CLASS, 'uddiv3Subscription', 'RFC4403'), + '1.3.6.1.1.10.6.10': ('1.3.6.1.1.10.6.10', OID_OBJECT_CLASS, 'uddiv3EntityObituary', 'RFC4403'), + '1.3.6.1.1.11.1.1': ('1.3.6.1.1.11.1.1', OID_OBJECT_CLASS, 'vPIMUser', 'RFC4237'), + '1.3.6.1.1.3.1': ('1.3.6.1.1.3.1', OID_OBJECT_CLASS, 'uidObject', 'RFC4519'), + '1.3.6.1.1.6.1.1': ('1.3.6.1.1.6.1.1', OID_OBJECT_CLASS, 'pcimPolicy', 'RFC3703'), + '1.3.6.1.1.6.1.2': ('1.3.6.1.1.6.1.2', OID_OBJECT_CLASS, 'pcimGroup', 'RFC3703'), + '1.3.6.1.1.6.1.3': ('1.3.6.1.1.6.1.3', OID_OBJECT_CLASS, 'pcimGroupAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.4': ('1.3.6.1.1.6.1.4', OID_OBJECT_CLASS, 'pcimGroupInstance', 'RFC3703'), + '1.3.6.1.1.6.1.5': ('1.3.6.1.1.6.1.5', OID_OBJECT_CLASS, 'pcimRule', 'RFC3703'), + '1.3.6.1.1.6.1.6': ('1.3.6.1.1.6.1.6', OID_OBJECT_CLASS, 'pcimRuleAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.7': ('1.3.6.1.1.6.1.7', OID_OBJECT_CLASS, 'pcimRuleInstance', 'RFC3703'), + '1.3.6.1.1.6.1.8': ('1.3.6.1.1.6.1.8', OID_OBJECT_CLASS, 'pcimRuleConditionAssociation', 'RFC3703'), + '1.3.6.1.1.6.1.9': ('1.3.6.1.1.6.1.9', OID_OBJECT_CLASS, 'pcimRuleValidityAssociation', 'RFC3703'), + '1.3.6.1.1.6.1.10': ('1.3.6.1.1.6.1.10', OID_OBJECT_CLASS, 'pcimRuleActionAssociation', 'RFC3703'), + '1.3.6.1.1.6.1.11': ('1.3.6.1.1.6.1.11', OID_OBJECT_CLASS, 'pcimConditionAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.12': ('1.3.6.1.1.6.1.12', OID_OBJECT_CLASS, 'pcimTPCAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.13': ('1.3.6.1.1.6.1.13', OID_OBJECT_CLASS, 'pcimConditionVendorAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.14': ('1.3.6.1.1.6.1.14', OID_OBJECT_CLASS, 'pcimActionAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.15': ('1.3.6.1.1.6.1.15', OID_OBJECT_CLASS, 'pcimActionVendorAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.16': ('1.3.6.1.1.6.1.16', OID_OBJECT_CLASS, 'pcimPolicyInstance', 'RFC3703'), + '1.3.6.1.1.6.1.17': ('1.3.6.1.1.6.1.17', OID_OBJECT_CLASS, 'pcimElementAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.18': ('1.3.6.1.1.6.1.18', OID_OBJECT_CLASS, 'pcimRepository', 'RFC3703'), + '1.3.6.1.1.6.1.19': ('1.3.6.1.1.6.1.19', OID_OBJECT_CLASS, 'pcimRepositoryAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.20': ('1.3.6.1.1.6.1.20', OID_OBJECT_CLASS, 'pcimRepositoryInstance', 'RFC3703'), + '1.3.6.1.1.6.1.21': ('1.3.6.1.1.6.1.21', OID_OBJECT_CLASS, 'pcimSubtreesPtrAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.22': ('1.3.6.1.1.6.1.22', OID_OBJECT_CLASS, 'pcimGroupContainmentAuxClass', 'RFC3703'), + '1.3.6.1.1.6.1.23': ('1.3.6.1.1.6.1.23', OID_OBJECT_CLASS, 'pcimRuleContainmentAuxClass', 'RFC3703'), + '1.3.6.1.1.9.1.1': ('1.3.6.1.1.9.1.1', OID_OBJECT_CLASS, 'pcelsPolicySet', 'RFC4104'), + '1.3.6.1.1.9.1.2': ('1.3.6.1.1.9.1.2', OID_OBJECT_CLASS, 'pcelsPolicySetAssociation', 'RFC4104'), + '1.3.6.1.1.9.1.3': ('1.3.6.1.1.9.1.3', OID_OBJECT_CLASS, 'pcelsGroup', 'RFC4104'), + '1.3.6.1.1.9.1.4': ('1.3.6.1.1.9.1.4', OID_OBJECT_CLASS, 'pcelsGroupAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.5': ('1.3.6.1.1.9.1.5', OID_OBJECT_CLASS, 'pcelsGroupInstance', 'RFC4104'), + '1.3.6.1.1.9.1.6': ('1.3.6.1.1.9.1.6', OID_OBJECT_CLASS, 'pcelsRule', 'RFC4104'), + '1.3.6.1.1.9.1.7': ('1.3.6.1.1.9.1.7', OID_OBJECT_CLASS, 'pcelsRuleAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.8': ('1.3.6.1.1.9.1.8', OID_OBJECT_CLASS, 'pcelsRuleInstance', 'RFC4104'), + '1.3.6.1.1.9.1.9': ('1.3.6.1.1.9.1.9', OID_OBJECT_CLASS, 'pcelsConditionAssociation', 'RFC4104'), + '1.3.6.1.1.9.1.10': ('1.3.6.1.1.9.1.10', OID_OBJECT_CLASS, 'pcelsActionAssociation', 'RFC4104'), + '1.3.6.1.1.9.1.11': ('1.3.6.1.1.9.1.11', OID_OBJECT_CLASS, 'pcelsSimpleConditionAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.12': ('1.3.6.1.1.9.1.12', OID_OBJECT_CLASS, 'pcelsCompoundConditionAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.13': ('1.3.6.1.1.9.1.13', OID_OBJECT_CLASS, 'pcelsCompoundFilterConditionAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.14': ('1.3.6.1.1.9.1.14', OID_OBJECT_CLASS, 'pcelsSimpleActionAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.15': ('1.3.6.1.1.9.1.15', OID_OBJECT_CLASS, 'pcelsCompoundActionAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.16': ('1.3.6.1.1.9.1.16', OID_OBJECT_CLASS, 'pcelsVariable', 'RFC4104'), + '1.3.6.1.1.9.1.17': ('1.3.6.1.1.9.1.17', OID_OBJECT_CLASS, 'pcelsExplicitVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.18': ('1.3.6.1.1.9.1.18', OID_OBJECT_CLASS, 'pcelsImplicitVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.19': ('1.3.6.1.1.9.1.19', OID_OBJECT_CLASS, 'pcelsSourceIPv4VariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.20': ('1.3.6.1.1.9.1.20', OID_OBJECT_CLASS, 'pcelsSourceIPv6VariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.21': ('1.3.6.1.1.9.1.21', OID_OBJECT_CLASS, 'pcelsDestinationIPv4VariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.22': ('1.3.6.1.1.9.1.22', OID_OBJECT_CLASS, 'pcelsDestinationIPv6VariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.23': ('1.3.6.1.1.9.1.23', OID_OBJECT_CLASS, 'pcelsSourcePortVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.24': ('1.3.6.1.1.9.1.24', OID_OBJECT_CLASS, 'pcelsDestinationPortVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.25': ('1.3.6.1.1.9.1.25', OID_OBJECT_CLASS, 'pcelsIPProtocolVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.26': ('1.3.6.1.1.9.1.26', OID_OBJECT_CLASS, 'pcelsIPVersionVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.27': ('1.3.6.1.1.9.1.27', OID_OBJECT_CLASS, 'pcelsIPToSVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.28': ('1.3.6.1.1.9.1.28', OID_OBJECT_CLASS, 'pcelsDSCPVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.29': ('1.3.6.1.1.9.1.29', OID_OBJECT_CLASS, 'pcelsFlowIdVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.30': ('1.3.6.1.1.9.1.30', OID_OBJECT_CLASS, 'pcelsSourceMACVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.31': ('1.3.6.1.1.9.1.31', OID_OBJECT_CLASS, 'pcelsDestinationMACVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.32': ('1.3.6.1.1.9.1.32', OID_OBJECT_CLASS, 'pcelsVLANVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.33': ('1.3.6.1.1.9.1.33', OID_OBJECT_CLASS, 'pcelsCoSVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.34': ('1.3.6.1.1.9.1.34', OID_OBJECT_CLASS, 'pcelsEthertypeVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.35': ('1.3.6.1.1.9.1.35', OID_OBJECT_CLASS, 'pcelsSourceSAPVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.36': ('1.3.6.1.1.9.1.36', OID_OBJECT_CLASS, 'pcelsDestinationSAPVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.37': ('1.3.6.1.1.9.1.37', OID_OBJECT_CLASS, 'pcelsSNAPOUIVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.38': ('1.3.6.1.1.9.1.38', OID_OBJECT_CLASS, 'pcelsSNAPTypeVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.39': ('1.3.6.1.1.9.1.39', OID_OBJECT_CLASS, 'pcelsFlowDirectionVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.40': ('1.3.6.1.1.9.1.40', OID_OBJECT_CLASS, 'pcelsValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.41': ('1.3.6.1.1.9.1.41', OID_OBJECT_CLASS, 'pcelsIPv4AddrValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.42': ('1.3.6.1.1.9.1.42', OID_OBJECT_CLASS, 'pcelsIPv6AddrValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.43': ('1.3.6.1.1.9.1.43', OID_OBJECT_CLASS, 'pcelsMACAddrValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.44': ('1.3.6.1.1.9.1.44', OID_OBJECT_CLASS, 'pcelsStringValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.45': ('1.3.6.1.1.9.1.45', OID_OBJECT_CLASS, 'pcelsBitStringValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.46': ('1.3.6.1.1.9.1.46', OID_OBJECT_CLASS, 'pcelsIntegerValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.47': ('1.3.6.1.1.9.1.47', OID_OBJECT_CLASS, 'pcelsBooleanValueAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.48': ('1.3.6.1.1.9.1.48', OID_OBJECT_CLASS, 'pcelsReusableContainer', 'RFC4104'), + '1.3.6.1.1.9.1.49': ('1.3.6.1.1.9.1.49', OID_OBJECT_CLASS, 'pcelsReusableContainerAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.50': ('1.3.6.1.1.9.1.50', OID_OBJECT_CLASS, 'pcelsReusableContainerInstance', 'RFC4104'), + '1.3.6.1.1.9.1.51': ('1.3.6.1.1.9.1.51', OID_OBJECT_CLASS, 'pcelsRoleCollection', 'RFC4104'), + '1.3.6.1.1.9.1.52': ('1.3.6.1.1.9.1.52', OID_OBJECT_CLASS, 'pcelsFilterEntryBase', 'RFC4104'), + '1.3.6.1.1.9.1.53': ('1.3.6.1.1.9.1.53', OID_OBJECT_CLASS, 'pcelsIPHeadersFilter', 'RFC4104'), + '1.3.6.1.1.9.1.54': ('1.3.6.1.1.9.1.54', OID_OBJECT_CLASS, 'pcels8021Filter', 'RFC4104'), + '1.3.6.1.1.9.1.55': ('1.3.6.1.1.9.1.55', OID_OBJECT_CLASS, 'pcelsFilterListAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.56': ('1.3.6.1.1.9.1.56', OID_OBJECT_CLASS, 'pcelsVendorVariableAuxClass', 'RFC4104'), + '1.3.6.1.1.9.1.57': ('1.3.6.1.1.9.1.57', OID_OBJECT_CLASS, 'pcelsVendorValueAuxClass', 'RFC4104'), + '1.3.6.1.4.1.11.1.3.1.2.5': ('1.3.6.1.4.1.11.1.3.1.2.5', OID_OBJECT_CLASS, 'DUAConfigProfile', 'RFC4876'), + '1.3.6.1.4.1.1466.101.119.2': ('1.3.6.1.4.1.1466.101.119.2', OID_OBJECT_CLASS, 'dynamicObject', 'RFC2589'), + '1.3.6.1.4.1.1466.101.120.111': ('1.3.6.1.4.1.1466.101.120.111', OID_OBJECT_CLASS, 'extensibleObject', 'RFC4512'), + '1.3.6.1.4.1.1466.344': ('1.3.6.1.4.1.1466.344', OID_OBJECT_CLASS, 'dcObject', 'RFC4519'), + '1.3.6.1.4.1.16572.2.1.1': ('1.3.6.1.4.1.16572.2.1.1', OID_OBJECT_CLASS, 'LDIFLocationURLObject', 'RFC6109'), + '1.3.6.1.4.1.16572.2.1.2': ('1.3.6.1.4.1.16572.2.1.2', OID_OBJECT_CLASS, 'provider', 'RFC6109'), + '1.3.6.1.4.1.250.3.15': ('1.3.6.1.4.1.250.3.15', OID_OBJECT_CLASS, 'labeledURIObject', 'RFC2079'), + '1.3.6.1.4.1.31103.1.1001': ('1.3.6.1.4.1.31103.1.1001', OID_OBJECT_CLASS, 'fedfsNsdbContainerInfo', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.1002': ('1.3.6.1.4.1.31103.1.1002', OID_OBJECT_CLASS, 'fedfsFsn', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.1003': ('1.3.6.1.4.1.31103.1.1003', OID_OBJECT_CLASS, 'fedfsFsl', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.31103.1.1004': ('1.3.6.1.4.1.31103.1.1004', OID_OBJECT_CLASS, 'fedfsNfsFsl', 'RFC-ietf-nfsv4-federated-fs-protocol-15'), + '1.3.6.1.4.1.453.7.1.1': ('1.3.6.1.4.1.453.7.1.1', OID_OBJECT_CLASS, ['rFC822ToX400Mapping', 'subtree'], 'RFC2164-RFC2293'), + '1.3.6.1.4.1.453.7.1.2': ('1.3.6.1.4.1.453.7.1.2', OID_OBJECT_CLASS, ['x400ToRFC822Mapping', 'table'], 'RFC2164-RFC2293'), + '1.3.6.1.4.1.453.7.1.3': ('1.3.6.1.4.1.453.7.1.3', OID_OBJECT_CLASS, ['omittedORAddressComponent', 'tableEntry'], 'RFC2164-RFC2293'), + '1.3.6.1.4.1.453.7.1.4': ('1.3.6.1.4.1.453.7.1.4', OID_OBJECT_CLASS, ['mixerGateway', 'textTableEntry'], 'RFC2164-RFC2293'), + '1.3.6.1.4.1.453.7.1.5': ('1.3.6.1.4.1.453.7.1.5', OID_OBJECT_CLASS, 'distinguishedNameTableEntry', 'RFC2293'), + '2.16.840.1.113730.3.2.6': ('2.16.840.1.113730.3.2.6', OID_OBJECT_CLASS, 'referral', 'RFC3296'), + '2.5.17.0': ('2.5.17.0', OID_OBJECT_CLASS, 'subentry', 'RFC3672'), + '2.5.20.1': ('2.5.20.1', OID_OBJECT_CLASS, 'subschema', 'RFC4512'), + '2.5.20.2': ('2.5.20.2', OID_OBJECT_CLASS, 'collectiveAttributeSubentry', 'RFC3671'), + '2.5.6.0': ('2.5.6.0', OID_OBJECT_CLASS, 'top', 'RFC4512'), + '2.5.6.1': ('2.5.6.1', OID_OBJECT_CLASS, 'alias', 'RFC4512'), + '2.5.6.2': ('2.5.6.2', OID_OBJECT_CLASS, 'country', 'RFC4519'), + '2.5.6.3': ('2.5.6.3', OID_OBJECT_CLASS, 'locality', 'RFC4519'), + '2.5.6.4': ('2.5.6.4', OID_OBJECT_CLASS, 'organization', 'RFC4519'), + '2.5.6.5': ('2.5.6.5', OID_OBJECT_CLASS, 'organizationalUnit', 'RFC4519'), + '2.5.6.6': ('2.5.6.6', OID_OBJECT_CLASS, 'person', 'RFC4519'), + '2.5.6.7': ('2.5.6.7', OID_OBJECT_CLASS, 'organizationalPerson', 'RFC4519'), + '2.5.6.8': ('2.5.6.8', OID_OBJECT_CLASS, 'organizationalRole', 'RFC4519'), + '2.5.6.9': ('2.5.6.9', OID_OBJECT_CLASS, 'groupOfNames', 'RFC4519'), + '2.5.6.10': ('2.5.6.10', OID_OBJECT_CLASS, 'residentialPerson', 'RFC4519'), + '2.5.6.11': ('2.5.6.11', OID_OBJECT_CLASS, 'applicationProcess', 'RFC4519'), + '2.5.6.12': ('2.5.6.12', OID_OBJECT_CLASS, 'applicationEntity', 'RFC2256'), + '2.5.6.13': ('2.5.6.13', OID_OBJECT_CLASS, 'dSA', 'RFC2256'), + '2.5.6.14': ('2.5.6.14', OID_OBJECT_CLASS, 'device', 'RFC4519'), + '2.5.6.15': ('2.5.6.15', OID_OBJECT_CLASS, 'strongAuthenticationUser', 'RFC4523'), + '2.5.6.16': ('2.5.6.16', OID_OBJECT_CLASS, 'certificationAuthority', 'RFC4523'), + '2.5.6.16.2': ('2.5.6.16.2', OID_OBJECT_CLASS, 'certificationAuthority-V2', 'RFC4523'), + '2.5.6.17': ('2.5.6.17', OID_OBJECT_CLASS, 'groupOfUniqueNames', 'RFC4519'), + '2.5.6.18': ('2.5.6.18', OID_OBJECT_CLASS, 'userSecurityInformation', 'RFC4523'), + '2.5.6.19': ('2.5.6.19', OID_OBJECT_CLASS, 'cRLDistributionPoint', 'RFC4523'), + '2.5.6.20': ('2.5.6.20', OID_OBJECT_CLASS, 'dmd', 'RFC2256'), + '2.5.6.21': ('2.5.6.21', OID_OBJECT_CLASS, 'pkiUser', 'RFC4523'), + '2.5.6.22': ('2.5.6.22', OID_OBJECT_CLASS, 'pkiCA', 'RFC4523'), + '2.5.6.23': ('2.5.6.23', OID_OBJECT_CLASS, 'deltaCRL', 'RFC4523'), + + # unsolicited notices + '1.3.6.1.1.21.4': ('1.3.6.1.1.21.4', OID_UNSOLICITED_NOTICE, 'Aborted Transaction Notice', 'RFC5805'), '1.3.6.1.4.1.1466.20036': ('1.3.6.1.4.1.1466.20036', OID_UNSOLICITED_NOTICE, 'Notice of Disconnection', 'RFC4511')} diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/persistentSearch.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/persistentSearch.py new file mode 100644 index 00000000..9abafc5f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/persistentSearch.py @@ -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 . + +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) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2696.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2696.py new file mode 100644 index 00000000..64337461 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2696.py @@ -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 . + +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) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2849.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2849.py new file mode 100644 index 00000000..af30a384 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc2849.py @@ -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 . + +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" diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc3062.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc3062.py new file mode 100644 index 00000000..9de3993e --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc3062.py @@ -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 . + +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())) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4511.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4511.py new file mode 100644 index 00000000..dccd4e60 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4511.py @@ -0,0 +1,1007 @@ +""" +""" + +# Created on 2013.05.15 +# +# 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 . + +####################### +# ldap ASN.1 Definition +# from RFC4511 - Appendix B +# extended with result codes from IANA ldap-parameters as of 2013.08.21 +# extended with modify_increment from RFC4525 + +######################################################### +# Lightweight-Directory-Access-Protocol-V3 {1 3 6 1 1 18} +# -- Copyright (C) The Internet Society (2006). This version of +# -- this ASN.1 module is part of RFC 4511; see the RFC itself +# -- for full legal notices. +# DEFINITIONS +# IMPLICIT TAGS +# EXTENSIBILITY IMPLIED + +from pyasn1.type.univ import OctetString, Integer, Sequence, Choice, SequenceOf, Boolean, Null, Enumerated, SetOf +from pyasn1.type.namedtype import NamedTypes, NamedType, OptionalNamedType, DefaultedNamedType +from pyasn1.type.constraint import ValueRangeConstraint, SingleValueConstraint, ValueSizeConstraint +from pyasn1.type.namedval import NamedValues +from pyasn1.type.tag import tagClassApplication, tagFormatConstructed, Tag, tagClassContext, tagFormatSimple + + +# constants +# maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) -- +LDAP_MAX_INT = 2147483647 +MAXINT = Integer(LDAP_MAX_INT) + +# constraints +rangeInt0ToMaxConstraint = ValueRangeConstraint(0, MAXINT) +rangeInt1To127Constraint = ValueRangeConstraint(1, 127) +size1ToMaxConstraint = ValueSizeConstraint(1, MAXINT) +responseValueConstraint = SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 32, 33, 34, 36, 48, 49, 50, 51, 52, 53, 54, 64, 65, 66, 67, 68, 69, 71, 80, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 4096) + +# custom constraints +numericOIDConstraint = None # TODO +distinguishedNameConstraint = None # TODO +nameComponentConstraint = None # TODO +attributeDescriptionConstraint = None # TODO +uriConstraint = None # TODO +attributeSelectorConstraint = None # TODO + + +class Integer0ToMax(Integer): + subtypeSpec = Integer.subtypeSpec + rangeInt0ToMaxConstraint + + +class LDAPString(OctetString): + # LDAPString ::= OCTET STRING -- UTF-8 encoded, -- [ISO10646] characters + encoding = 'utf-8' + + +class MessageID(Integer0ToMax): + # MessageID ::= INTEGER (0 .. maxInt) + pass + + +class LDAPOID(OctetString): + # LDAPOID ::= OCTET STRING -- Constrained to + # -- [RFC4512] + + # subtypeSpec = numericOIDConstraint + pass + + +class LDAPDN(LDAPString): + # LDAPDN ::= LDAPString -- Constrained to + # -- [RFC4514] + + # subtypeSpec = distinguishedName + pass + + +class RelativeLDAPDN(LDAPString): + # RelativeLDAPDN ::= LDAPString -- Constrained to + # -- [RFC4514] + + # subtypeSpec = LDAPString.subtypeSpec + nameComponentConstraint + pass + + +class AttributeDescription(LDAPString): + # AttributeDescription ::= LDAPString -- Constrained to + # -- [RFC4512] + + # subtypeSpec = LDAPString.subtypeSpec + attributeDescriptionConstraint + pass + + +class AttributeValue(OctetString): + # AttributeValue ::= OCTET STRING + encoding = 'utf-8' + + +class AssertionValue(OctetString): + # AssertionValue ::= OCTET STRING + encoding = 'utf-8' + + +class AttributeValueAssertion(Sequence): + # AttributeValueAssertion ::= SEQUENCE { + # attributeDesc AttributeDescription, + # assertionValue AssertionValue } + componentType = NamedTypes(NamedType('attributeDesc', AttributeDescription()), + NamedType('assertionValue', AssertionValue())) + + +class MatchingRuleId(LDAPString): + # MatchingRuleId ::= LDAPString + pass + + +class Vals(SetOf): + # vals SET OF value AttributeValue } + componentType = AttributeValue() + + +class ValsAtLeast1(SetOf): + # vals SET OF value AttributeValue } + componentType = AttributeValue() + subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint + + +class PartialAttribute(Sequence): + # PartialAttribute ::= SEQUENCE { + # type AttributeDescription, + # vals SET OF value AttributeValue } + componentType = NamedTypes(NamedType('type', AttributeDescription()), + NamedType('vals', Vals())) + + +class Attribute(Sequence): + # Attribute ::= PartialAttribute(WITH COMPONENTS { + # ..., + # vals (SIZE(1..MAX))}) + componentType = NamedTypes(NamedType('type', AttributeDescription()), + # NamedType('vals', ValsAtLeast1())) + NamedType('vals', Vals())) # changed from ValsAtLeast1() to allow empty member values in groups - this should not be as per rfc4511 4.1.7, but openldap accept it + + +class AttributeList(SequenceOf): + # AttributeList ::= SEQUENCE OF attribute Attribute + componentType = Attribute() + + +class Simple(OctetString): + # simple [0] OCTET STRING, + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0)) + encoding = 'utf-8' + + +class Credentials(OctetString): + # credentials OCTET STRING + encoding = 'utf-8' + + +class SaslCredentials(Sequence): + # SaslCredentials ::= SEQUENCE { + # mechanism LDAPString, + # credentials OCTET STRING OPTIONAL } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3)) + componentType = NamedTypes(NamedType('mechanism', LDAPString()), + OptionalNamedType('credentials', Credentials())) + + +# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol) +class SicilyPackageDiscovery(OctetString): + # sicilyPackageDiscovery [9] OCTET STRING, + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 9)) + encoding = 'utf-8' + + +# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol) +class SicilyNegotiate(OctetString): + # sicilyNegotiate [10] OCTET STRING, + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 10)) + encoding = 'utf-8' + + +# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol) +class SicilyResponse(OctetString): + # sicilyResponse [11] OCTET STRING, + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 11)) + encoding = 'utf-8' + + +class AuthenticationChoice(Choice): + # AuthenticationChoice ::= CHOICE { + # simple [0] OCTET STRING, + # -- 1 and 2 reserved + # sasl [3] SaslCredentials, + # ... } + + # from https://msdn.microsoft.com/en-us/library/cc223498.aspx # legacy NTLM authentication for Windows Active Directory + # sicilyPackageDiscovery [9] OCTET STRING + # sicilyNegotiate [10] OCTET STRING + # sicilyResponse [11] OCTET STRING } + + componentType = NamedTypes(NamedType('simple', Simple()), + NamedType('sasl', SaslCredentials()), + NamedType('sicilyPackageDiscovery', SicilyPackageDiscovery()), + NamedType('sicilyNegotiate', SicilyNegotiate()), + NamedType('sicilyResponse', SicilyResponse()), + ) + + +class Version(Integer): + # version INTEGER (1 .. 127), + subtypeSpec = Integer.subtypeSpec + rangeInt1To127Constraint + + +class ResultCode(Enumerated): + # resultCode ENUMERATED { + # success (0), + # operationsError (1), + # protocolError (2), + # timeLimitExceeded (3), + # sizeLimitExceeded (4), + # compareFalse (5), + # compareTrue (6), + # authMethodNotSupported (7), + # strongerAuthRequired (8), + # -- 9 reserved -- + # referral (10), + # adminLimitExceeded (11), + # unavailableCriticalExtension (12), + # confidentialityRequired (13), + # saslBindInProgress (14), + # noSuchAttribute (16), + # undefinedAttributeType (17), + # inappropriateMatching (18), + # constraintViolation (19), + # attributeOrValueExists (20), + # invalidAttributeSyntax (21), + # -- 22-31 unused -- + # noSuchObject (32), + # aliasProblem (33), + # invalidDNSyntax (34), + # -- 35 reserved for undefined isLeaf -- + # aliasDereferencingProblem (36), + # -- 37-47 unused -- + # inappropriateAuthentication (48), + # invalidCredentials (49), + # insufficientAccessRights (50), + # busy (51), + # unavailable (52), + # unwillingToPerform (53), + # loopDetect (54), + # -- 55-63 unused -- + # namingViolation (64), + # objectClassViolation (65), + # notAllowedOnNonLeaf (66), + # notAllowedOnRDN (67), + # entryAlreadyExists (68), + # objectClassModsProhibited (69), + # -- 70 reserved for CLDAP -- + # affectsMultipleDSAs (71), + # -- 72-79 unused -- + # other (80), + # ... } + # + # from IANA ldap-parameters: + # lcupResourcesExhausted 113 IESG [RFC3928] + # lcupSecurityViolation 114 IESG [RFC3928] + # lcupInvalidData 115 IESG [RFC3928] + # lcupUnsupportedScheme 116 IESG [RFC3928] + # lcupReloadRequired 117 IESG [RFC3928] + # canceled 118 IESG [RFC3909] + # noSuchOperation 119 IESG [RFC3909] + # tooLate 120 IESG [RFC3909] + # cannotCancel 121 IESG [RFC3909] + # assertionFailed 122 IESG [RFC4528] + # authorizationDenied 123 WELTMAN [RFC4370] + # e-syncRefreshRequired 4096 [Kurt_Zeilenga] [Jong_Hyuk_Choi] [RFC4533] + namedValues = NamedValues(('success', 0), + ('operationsError', 1), + ('protocolError', 2), + ('timeLimitExceeded', 3), + ('sizeLimitExceeded', 4), + ('compareFalse', 5), + ('compareTrue', 6), + ('authMethodNotSupported', 7), + ('strongerAuthRequired', 8), + ('referral', 10), + ('adminLimitExceeded', 11), + ('unavailableCriticalExtension', 12), + ('confidentialityRequired', 13), + ('saslBindInProgress', 14), + ('noSuchAttribute', 16), + ('undefinedAttributeType', 17), + ('inappropriateMatching', 18), + ('constraintViolation', 19), + ('attributeOrValueExists', 20), + ('invalidAttributeSyntax', 21), + ('noSuchObject', 32), + ('aliasProblem', 33), + ('invalidDNSyntax', 34), + ('aliasDereferencingProblem', 36), + ('inappropriateAuthentication', 48), + ('invalidCredentials', 49), + ('insufficientAccessRights', 50), + ('busy', 51), + ('unavailable', 52), + ('unwillingToPerform', 53), + ('loopDetected', 54), + ('namingViolation', 64), + ('objectClassViolation', 65), + ('notAllowedOnNonLeaf', 66), + ('notAllowedOnRDN', 67), + ('entryAlreadyExists', 68), + ('objectClassModsProhibited', 69), + ('affectMultipleDSAs', 71), + ('other', 80), + ('lcupResourcesExhausted', 113), + ('lcupSecurityViolation', 114), + ('lcupInvalidData', 115), + ('lcupUnsupportedScheme', 116), + ('lcupReloadRequired', 117), + ('canceled', 118), + ('noSuchOperation', 119), + ('tooLate', 120), + ('cannotCancel', 121), + ('assertionFailed', 122), + ('authorizationDenied', 123), + ('e-syncRefreshRequired', 4096)) + + subTypeSpec = Enumerated.subtypeSpec + responseValueConstraint + + +class URI(LDAPString): + # URI ::= LDAPString -- limited to characters permitted in + # -- URIs + + # subtypeSpec = LDAPString.subTypeSpec + uriConstrain + pass + + +class Referral(SequenceOf): + # Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI + tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3)) + componentType = URI() + + +class ServerSaslCreds(OctetString): + # serverSaslCreds [7] OCTET STRING OPTIONAL + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 7)) + encoding = 'utf-8' + + +class LDAPResult(Sequence): + # LDAPResult ::= SEQUENCE { + # resultCode ENUMERATED { + # success (0), + # operationsError (1), + # protocolError (2), + # timeLimitExceeded (3), + # sizeLimitExceeded (4), + # compareFalse (5), + # compareTrue (6), + # authMethodNotSupported (7), + # strongerAuthRequired (8), + # -- 9 reserved -- + # referral (10), + # adminLimitExceeded (11), + # unavailableCriticalExtension (12), + # confidentialityRequired (13), + # saslBindInProgress (14), + # noSuchAttribute (16), + # undefinedAttributeType (17), + # inappropriateMatching (18), + # constraintViolation (19), + # attributeOrValueExists (20), + # invalidAttributeSyntax (21), + # -- 22-31 unused -- + # noSuchObject (32), + # aliasProblem (33), + # invalidDNSyntax (34), + # -- 35 reserved for undefined isLeaf -- + # aliasDereferencingProblem (36), + # -- 37-47 unused -- + # inappropriateAuthentication (48), + # invalidCredentials (49), + # insufficientAccessRights (50), + # busy (51), + # unavailable (52), + # unwillingToPerform (53), + # loopDetect (54), + # -- 55-63 unused -- + # namingViolation (64), + # objectClassViolation (65), + # notAllowedOnNonLeaf (66), + # notAllowedOnRDN (67), + # entryAlreadyExists (68), + # objectClassModsProhibited (69), + # -- 70 reserved for CLDAP -- + # affectsMultipleDSAs (71), + # -- 72-79 unused -- + # other (80), + # ... }, + # matchedDN LDAPDN, + # diagnosticMessage LDAPString, + # referral [3] Referral OPTIONAL } + componentType = NamedTypes(NamedType('resultCode', ResultCode()), + NamedType('matchedDN', LDAPDN()), + NamedType('diagnosticMessage', LDAPString()), + OptionalNamedType('referral', Referral())) + + +class Criticality(Boolean): + # criticality BOOLEAN DEFAULT FALSE + defaultValue = False + + +class ControlValue(OctetString): + # controlValue OCTET STRING + encoding = 'utf-8' + + +class Control(Sequence): + # Control ::= SEQUENCE { + # controlType LDAPOID, + # criticality BOOLEAN DEFAULT FALSE, + # controlValue OCTET STRING OPTIONAL } + componentType = NamedTypes(NamedType('controlType', LDAPOID()), + DefaultedNamedType('criticality', Criticality()), + OptionalNamedType('controlValue', ControlValue())) + + +class Controls(SequenceOf): + # Controls ::= SEQUENCE OF control Control + tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 0)) + componentType = Control() + + +class Scope(Enumerated): + # scope ENUMERATED { + # baseObject (0), + # singleLevel (1), + # wholeSubtree (2), + namedValues = NamedValues(('baseObject', 0), + ('singleLevel', 1), + ('wholeSubtree', 2)) + + +class DerefAliases(Enumerated): + # derefAliases ENUMERATED { + # neverDerefAliases (0), + # derefInSearching (1), + # derefFindingBaseObj (2), + # derefAlways (3) }, + namedValues = NamedValues(('neverDerefAliases', 0), + ('derefInSearching', 1), + ('derefFindingBaseObj', 2), + ('derefAlways', 3)) + + +class TypesOnly(Boolean): + # typesOnly BOOLEAN + pass + + +class Selector(LDAPString): + # -- The LDAPString is constrained to + # -- in Section 4.5.1.8 + + # subtypeSpec = LDAPString.subtypeSpec + attributeSelectorConstraint + pass + + +class AttributeSelection(SequenceOf): + # AttributeSelection ::= SEQUENCE OF selector LDAPString + # -- The LDAPString is constrained to + # -- in Section 4.5.1.8 + componentType = Selector() + + +class MatchingRule(MatchingRuleId): + # matchingRule [1] MatchingRuleId + tagSet = MatchingRuleId.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1)) + + +class Type(AttributeDescription): + # type [2] AttributeDescription + tagSet = AttributeDescription.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 2)) + + +class MatchValue(AssertionValue): + # matchValue [3] AssertionValue, + tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 3)) + + +class DnAttributes(Boolean): + # dnAttributes [4] BOOLEAN DEFAULT FALSE } + tagSet = Boolean.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 4)) + defaultValue = Boolean(False) + + +class MatchingRuleAssertion(Sequence): + # MatchingRuleAssertion ::= SEQUENCE { + # matchingRule [1] MatchingRuleId OPTIONAL, + # type [2] AttributeDescription OPTIONAL, + # matchValue [3] AssertionValue, + # dnAttributes [4] BOOLEAN DEFAULT FALSE } + componentType = NamedTypes(OptionalNamedType('matchingRule', MatchingRule()), + OptionalNamedType('type', Type()), + NamedType('matchValue', MatchValue()), + DefaultedNamedType('dnAttributes', DnAttributes())) + + +class Initial(AssertionValue): + # initial [0] AssertionValue, -- can occur at most once + tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0)) + + +class Any(AssertionValue): + # any [1] AssertionValue, + tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1)) + + +class Final(AssertionValue): + # final [1] AssertionValue, -- can occur at most once + tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 2)) + + +class Substring(Choice): + # substring CHOICE { + # initial [0] AssertionValue, -- can occur at most once + # any [1] AssertionValue, + # final [2] AssertionValue } -- can occur at most once + # } + componentType = NamedTypes(NamedType('initial', Initial()), + NamedType('any', Any()), + NamedType('final', Final())) + + +class Substrings(SequenceOf): + # substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE { + # ... + # } + subtypeSpec = SequenceOf.subtypeSpec + size1ToMaxConstraint + componentType = Substring() + + +class SubstringFilter(Sequence): + # SubstringFilter ::= SEQUENCE { + # type AttributeDescription, + # substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE { + # initial [0] AssertionValue, -- can occur at most once + # any [1] AssertionValue, + # final [2] AssertionValue } -- can occur at most once + # } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 4)) + componentType = NamedTypes(NamedType('type', AttributeDescription()), + NamedType('substrings', Substrings())) + + +class And(SetOf): + # and [0] SET SIZE (1..MAX) OF filter Filter + tagSet = SetOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 0)) + subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint + + +class Or(SetOf): + # or [1] SET SIZE (1..MAX) OF filter Filter + tagSet = SetOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 1)) + subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint + + +class Not(Choice): + # not [2] Filter + pass # defined after Filter definition to allow recursion + + +class EqualityMatch(AttributeValueAssertion): + # equalityMatch [3] AttributeValueAssertion + tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3)) + + +class GreaterOrEqual(AttributeValueAssertion): + # greaterOrEqual [5] AttributeValueAssertion + tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 5)) + + +class LessOrEqual(AttributeValueAssertion): + # lessOrEqual [6] AttributeValueAssertion + tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 6)) + + +class Present(AttributeDescription): + # present [7] AttributeDescription + tagSet = AttributeDescription.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 7)) + + +class ApproxMatch(AttributeValueAssertion): + # approxMatch [8] AttributeValueAssertion + tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 8)) + + +class ExtensibleMatch(MatchingRuleAssertion): + # extensibleMatch [9] MatchingRuleAssertion + tagSet = MatchingRuleAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 9)) + + +class Filter(Choice): + # Filter ::= CHOICE { + # and [0] SET SIZE (1..MAX) OF filter Filter, + # or [1] SET SIZE (1..MAX) OF filter Filter, + # not [2] Filter, + # equalityMatch [3] AttributeValueAssertion, + # substrings [4] SubstringFilter, + # greaterOrEqual [5] AttributeValueAssertion, + # lessOrEqual [6] AttributeValueAssertion, + # present [7] AttributeDescription, + # approxMatch [8] AttributeValueAssertion, + # extensibleMatch [9] MatchingRuleAssertion, + # ... } + componentType = NamedTypes(NamedType('and', And()), + NamedType('or', Or()), + NamedType('notFilter', Not()), + NamedType('equalityMatch', EqualityMatch()), + NamedType('substringFilter', SubstringFilter()), + NamedType('greaterOrEqual', GreaterOrEqual()), + NamedType('lessOrEqual', LessOrEqual()), + NamedType('present', Present()), + NamedType('approxMatch', ApproxMatch()), + NamedType('extensibleMatch', ExtensibleMatch())) + + +And.componentType = Filter() +Or.componentType = Filter() +Not.componentType = NamedTypes(NamedType('innerNotFilter', Filter())) +Not.tagSet = Filter.tagSet.tagExplicitly(Tag(tagClassContext, tagFormatConstructed, 2)) # as per RFC4511 page 23 + + +class PartialAttributeList(SequenceOf): + # PartialAttributeList ::= SEQUENCE OF + # partialAttribute PartialAttribute + componentType = PartialAttribute() + + +class Operation(Enumerated): + # operation ENUMERATED { + # add (0), + # delete (1), + # replace (2), + # ... } + namedValues = NamedValues(('add', 0), + ('delete', 1), + ('replace', 2), + ('increment', 3)) + + +class Change(Sequence): + # change SEQUENCE { + # operation ENUMERATED { + # add (0), + # delete (1), + # replace (2), + # ... }, + # modification PartialAttribute } } + componentType = NamedTypes(NamedType('operation', Operation()), + NamedType('modification', PartialAttribute())) + + +class Changes(SequenceOf): + # changes SEQUENCE OF change SEQUENCE + componentType = Change() + + +class DeleteOldRDN(Boolean): + # deleteoldrdn BOOLEAN + pass + + +class NewSuperior(LDAPDN): + # newSuperior [0] LDAPDN + tagSet = LDAPDN.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0)) + + +class RequestName(LDAPOID): + # requestName [0] LDAPOID + tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0)) + + +class RequestValue(OctetString): + # requestValue [1] OCTET STRING + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1)) + encoding = 'utf-8' + + +class ResponseName(LDAPOID): + # responseName [10] LDAPOID + tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 10)) + + +class ResponseValue(OctetString): + # responseValue [11] OCTET STRING + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 11)) + encoding = 'utf-8' + + +class IntermediateResponseName(LDAPOID): + # responseName [0] LDAPOID + tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0)) + + +class IntermediateResponseValue(OctetString): + # responseValue [1] OCTET STRING + tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1)) + encoding = 'utf-8' + + +# operations +class BindRequest(Sequence): + # BindRequest ::= [APPLICATION 0] SEQUENCE { + # version INTEGER (1 .. 127), + # name LDAPDN, + # authentication AuthenticationChoice } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 0)) + componentType = NamedTypes(NamedType('version', Version()), + NamedType('name', LDAPDN()), + NamedType('authentication', AuthenticationChoice())) + + +class BindResponse(Sequence): + # 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('matchedDN', LDAPDN()), + NamedType('diagnosticMessage', LDAPString()), + OptionalNamedType('referral', Referral()), + OptionalNamedType('serverSaslCreds', ServerSaslCreds())) + + +class UnbindRequest(Null): + # UnbindRequest ::= [APPLICATION 2] NULL + tagSet = Null.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 2)) + + +class SearchRequest(Sequence): + # SearchRequest ::= [APPLICATION 3] SEQUENCE { + # baseObject LDAPDN, + # scope ENUMERATED { + # baseObject (0), + # singleLevel (1), + # wholeSubtree (2), + # ... }, + # derefAliases ENUMERATED { + # neverDerefAliases (0), + # derefInSearching (1), + # derefFindingBaseObj (2), + # derefAlways (3) }, + # sizeLimit INTEGER (0 .. maxInt), + # timeLimit INTEGER (0 .. maxInt), + # typesOnly BOOLEAN, + # filter Filter, + # attributes AttributeSelection } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 3)) + componentType = NamedTypes(NamedType('baseObject', LDAPDN()), + NamedType('scope', Scope()), + NamedType('derefAliases', DerefAliases()), + NamedType('sizeLimit', Integer0ToMax()), + NamedType('timeLimit', Integer0ToMax()), + NamedType('typesOnly', TypesOnly()), + NamedType('filter', Filter()), + NamedType('attributes', AttributeSelection())) + + +class SearchResultReference(SequenceOf): + # SearchResultReference ::= [APPLICATION 19] SEQUENCE + # SIZE (1..MAX) OF uri URI + tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 19)) + subtypeSpec = SequenceOf.subtypeSpec + size1ToMaxConstraint + componentType = URI() + + +class SearchResultEntry(Sequence): + # SearchResultEntry ::= [APPLICATION 4] SEQUENCE { + # objectName LDAPDN, + # attributes PartialAttributeList } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 4)) + componentType = NamedTypes(NamedType('object', LDAPDN()), + NamedType('attributes', PartialAttributeList())) + + +class SearchResultDone(LDAPResult): + # SearchResultDone ::= [APPLICATION 5] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 5)) + + +class ModifyRequest(Sequence): + # ModifyRequest ::= [APPLICATION 6] SEQUENCE { + # object LDAPDN, + # changes SEQUENCE OF change SEQUENCE { + # operation ENUMERATED { + # add (0), + # delete (1), + # replace (2), + # ... }, + # modification PartialAttribute } } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 6)) + componentType = NamedTypes(NamedType('object', LDAPDN()), + NamedType('changes', Changes())) + + +class ModifyResponse(LDAPResult): + # ModifyResponse ::= [APPLICATION 7] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 7)) + + +class AddRequest(Sequence): + # AddRequest ::= [APPLICATION 8] SEQUENCE { + # entry LDAPDN, + # attributes AttributeList } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 8)) + componentType = NamedTypes(NamedType('entry', LDAPDN()), + NamedType('attributes', AttributeList())) + + +class AddResponse(LDAPResult): + # AddResponse ::= [APPLICATION 9] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 9)) + + +class DelRequest(LDAPDN): + # DelRequest ::= [APPLICATION 10] LDAPDN + tagSet = LDAPDN.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 10)) + + +class DelResponse(LDAPResult): + # DelResponse ::= [APPLICATION 11] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 11)) + + +class ModifyDNRequest(Sequence): + # ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { + # entry LDAPDN, + # newrdn RelativeLDAPDN, + # deleteoldrdn BOOLEAN, + # newSuperior [0] LDAPDN OPTIONAL } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 12)) + componentType = NamedTypes(NamedType('entry', LDAPDN()), + NamedType('newrdn', RelativeLDAPDN()), + NamedType('deleteoldrdn', DeleteOldRDN()), + OptionalNamedType('newSuperior', NewSuperior())) + + +class ModifyDNResponse(LDAPResult): + # ModifyDNResponse ::= [APPLICATION 13] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 13)) + + +class CompareRequest(Sequence): + # CompareRequest ::= [APPLICATION 14] SEQUENCE { + # entry LDAPDN, + # ava AttributeValueAssertion } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 14)) + componentType = NamedTypes(NamedType('entry', LDAPDN()), + NamedType('ava', AttributeValueAssertion())) + + +class CompareResponse(LDAPResult): + # CompareResponse ::= [APPLICATION 15] LDAPResult + tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 15)) + + +class AbandonRequest(MessageID): + # AbandonRequest ::= [APPLICATION 16] MessageID + tagSet = MessageID.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 16)) + + +class ExtendedRequest(Sequence): + # ExtendedRequest ::= [APPLICATION 23] SEQUENCE { + # requestName [0] LDAPOID, + # requestValue [1] OCTET STRING OPTIONAL } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 23)) + componentType = NamedTypes(NamedType('requestName', RequestName()), + OptionalNamedType('requestValue', RequestValue())) + + +class ExtendedResponse(Sequence): + # ExtendedResponse ::= [APPLICATION 24] SEQUENCE { + # COMPONENTS OF LDAPResult, + # responseName [10] LDAPOID OPTIONAL, + # responseValue [11] OCTET STRING OPTIONAL } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 24)) + componentType = NamedTypes(NamedType('resultCode', ResultCode()), + NamedType('matchedDN', LDAPDN()), + NamedType('diagnosticMessage', LDAPString()), + OptionalNamedType('referral', Referral()), + OptionalNamedType('responseName', ResponseName()), + OptionalNamedType('responseValue', ResponseValue())) + + +class IntermediateResponse(Sequence): + # IntermediateResponse ::= [APPLICATION 25] SEQUENCE { + # responseName [0] LDAPOID OPTIONAL, + # responseValue [1] OCTET STRING OPTIONAL } + tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 25)) + componentType = NamedTypes(OptionalNamedType('responseName', IntermediateResponseName()), + OptionalNamedType('responseValue', IntermediateResponseValue())) + + +class ProtocolOp(Choice): + # protocolOp CHOICE { + # bindRequest BindRequest, + # bindResponse BindResponse, + # unbindRequest UnbindRequest, + # searchRequest SearchRequest, + # searchResEntry SearchResultEntry, + # searchResDone SearchResultDone, + # searchResRef SearchResultReference, + # modifyRequest ModifyRequest, + # modifyResponse ModifyResponse, + # addRequest AddRequest, + # addResponse AddResponse, + # delRequest DelRequest, + # delResponse DelResponse, + # modDNRequest ModifyDNRequest, + # modDNResponse ModifyDNResponse, + # compareRequest CompareRequest, + # compareResponse CompareResponse, + # abandonRequest AbandonRequest, + # extendedReq ExtendedRequest, + # extendedResp ExtendedResponse, + # ..., + # intermediateResponse IntermediateResponse } + componentType = NamedTypes(NamedType('bindRequest', BindRequest()), + NamedType('bindResponse', BindResponse()), + NamedType('unbindRequest', UnbindRequest()), + NamedType('searchRequest', SearchRequest()), + NamedType('searchResEntry', SearchResultEntry()), + NamedType('searchResDone', SearchResultDone()), + NamedType('searchResRef', SearchResultReference()), + NamedType('modifyRequest', ModifyRequest()), + NamedType('modifyResponse', ModifyResponse()), + NamedType('addRequest', AddRequest()), + NamedType('addResponse', AddResponse()), + NamedType('delRequest', DelRequest()), + NamedType('delResponse', DelResponse()), + NamedType('modDNRequest', ModifyDNRequest()), + NamedType('modDNResponse', ModifyDNResponse()), + NamedType('compareRequest', CompareRequest()), + NamedType('compareResponse', CompareResponse()), + NamedType('abandonRequest', AbandonRequest()), + NamedType('extendedReq', ExtendedRequest()), + NamedType('extendedResp', ExtendedResponse()), + NamedType('intermediateResponse', IntermediateResponse())) + + +class LDAPMessage(Sequence): + # LDAPMessage ::= SEQUENCE { + # messageID MessageID, + # protocolOp CHOICE { + # bindRequest BindRequest, + # bindResponse BindResponse, + # unbindRequest UnbindRequest, + # searchRequest SearchRequest, + # searchResEntry SearchResultEntry, + # searchResDone SearchResultDone, + # searchResRef SearchResultReference, + # modifyRequest ModifyRequest, + # modifyResponse ModifyResponse, + # addRequest AddRequest, + # addResponse AddResponse, + # delRequest DelRequest, + # delResponse DelResponse, + # modDNRequest ModifyDNRequest, + # modDNResponse ModifyDNResponse, + # compareRequest CompareRequest, + # compareResponse CompareResponse, + # abandonRequest AbandonRequest, + # extendedReq ExtendedRequest, + # extendedResp ExtendedResponse, + # ..., + # intermediateResponse IntermediateResponse }, + # controls [0] Controls OPTIONAL } + componentType = NamedTypes(NamedType('messageID', MessageID()), + NamedType('protocolOp', ProtocolOp()), + OptionalNamedType('controls', Controls())) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4512.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4512.py new file mode 100644 index 00000000..c12e7eb9 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4512.py @@ -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 . + +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 '' + + +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) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4527.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4527.py new file mode 100644 index 00000000..8413c870 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/rfc4527.py @@ -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 . + +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) + diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py new file mode 100644 index 00000000..9fa4ae82 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py @@ -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 . + +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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/external.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/external.py new file mode 100644 index 00000000..efb3e4ff --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/external.py @@ -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 . + +from ...protocol.sasl.sasl import send_sasl_negotiation + + +def sasl_external(connection, controls): + result = send_sasl_negotiation(connection, controls, connection.sasl_credentials) + + return result diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/kerberos.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/kerberos.py new file mode 100644 index 00000000..05ce363b --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/kerberos.py @@ -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 . + +# 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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/plain.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/plain.py new file mode 100644 index 00000000..1c370808 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/plain.py @@ -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 . + +# 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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/sasl.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/sasl.py new file mode 100644 index 00000000..2656b52c --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/sasl.py @@ -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 . + +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 diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ad2012R2.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ad2012R2.py new file mode 100644 index 00000000..41282c47 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ad2012R2.py @@ -0,0 +1,2232 @@ +""" +""" + +# 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 . + +ad_2012_r2_schema = """ +{ + "raw": { + "attributeTypes": [ + "( 1.2.840.113556.1.4.149 NAME 'attributeSecurityGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1703 NAME 'msDS-FilterContainers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.655 NAME 'legacyExchangeDN' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.21 NAME 'cOMProgID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2147 NAME 'msDNS-PropagationTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.301 NAME 'msSFU30KeyAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.686 NAME 'domainID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.23 NAME 'msDFSR-ReplicationGroupGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.818 NAME 'productCode' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.375 NAME 'systemFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.814 NAME 'msiScript' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.880 NAME 'fRSTimeLastCommand' SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1850 NAME 'msDS-TopQuotaUsage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2052 NAME 'msDS-OIDToGroupLinkBl' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.965 NAME 'mSMQSiteName' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1373 NAME 'mS-SQL-Clustered' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.624 NAME 'ipsecOwnersReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1353 NAME 'localizationDisplayId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1637 NAME 'msWMI-StringValidValues' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2103 NAME 'msDS-MembersOfResourcePropertyList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.480 NAME 'defaultGroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.55 NAME 'dBCSPwd' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1330 NAME 'pKICriticalExtensions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.93 NAME 'pwdProperties' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1840 NAME 'msDS-ObjectReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.7 NAME 'subRefs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.845 NAME 'msiScriptName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2242 NAME 'msDS-MaximumRegistrationInactivityPeriod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.713 NAME 'optionsLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.942 NAME 'mSMQVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2138 NAME 'msDNS-NSEC3Iterations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.471 NAME 'trustParent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1237 NAME 'mSMQRoutingService' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.649 NAME 'primaryInternationalISDNNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1627 NAME 'msWMI-ID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2006 NAME 'msTSExpireDate4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2003 NAME 'msTSExpireDate3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2000 NAME 'msTSExpireDate2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113549.1.9.8 NAME 'unstructuredAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.340 NAME 'msSFU30Domains' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.2069 NAME 'msDS-EnabledFeatureBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.3.6.1.1.1.1.6 NAME 'shadowMin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1412 NAME 'primaryGroupToken' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.358 NAME 'netbootInitialization' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2136 NAME 'msDNS-NSEC3HashAlgorithm' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.1 NAME 'instanceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.846 NAME 'msiScriptSize' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.20 NAME 'msDFSR-RdcMinFileSizeInKb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.663 NAME 'partialAttributeDeletionList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2078 NAME 'msTSSecondaryDesktopBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1995 NAME 'msTSManagingLS' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.371 NAME 'rIDAllocationPool' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.677 NAME 'replTopologyStayOfExecution' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.3 NAME 'replPropertyMetaData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2036 NAME 'msDFS-Commentv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.329 NAME 'versionNumberLo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.234 NAME 'printEndTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1673 NAME 'msPKI-OID-User-Notice' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.684 NAME 'certificateAuthorityObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.290 NAME 'printNumberUp' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1625 NAME 'msWMI-ClassDefinition' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1784 NAME 'msDS-LogonTimeSyncInterval' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1910 NAME 'unixUserPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.129 NAME 'trustAuthIncoming' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1319 NAME 'aCSNonReservedTokenSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1628 NAME 'msWMI-IntDefault' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1249 NAME 'proxiedObjectName' SYNTAX '1.2.840.113556.1.4.903' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2173 NAME 'msKds-PublicKeyLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 2.5.4.27 NAME 'destinationIndicator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.2187 NAME 'msDS-ValueTypeReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.897 NAME 'aCSMaxAggregatePeakRatePerUser' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1335 NAME 'pKIEnrollmentAccess' SYNTAX '1.2.840.113556.1.4.907' )", + "( 1.2.840.113556.1.4.1708 NAME 'msDS-ReplValueMetaData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1690 NAME 'adminMultiselectPropertyPages' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.35 NAME 'userPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2200 NAME 'msDS-GroupMSAMembership' SYNTAX '1.2.840.113556.1.4.907' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.500 NAME 'fRSServiceCommand' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.16.840.1.113730.3.1.1 NAME 'carLicense' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2038 NAME 'msDFS-TargetListv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.27 NAME 'msDFSR-DeletedSizeInMb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1648 NAME 'msWMI-TargetPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1793 NAME 'msDS-NonMembers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.3.6.1.1.1.1.22 NAME 'macAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.265 NAME 'notes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2274 NAME 'msDS-CloudIssuerPublicCertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1982 NAME 'msTSMaxConnectionTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1959 NAME 'msDS-isGC' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1424 NAME 'msCOM-PartitionSetLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.516 NAME 'serverReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1977 NAME 'msTSHomeDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1369 NAME 'mS-SQL-ServiceAccount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.530 NAME 'nonSecurityMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.506 NAME 'objectCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1386 NAME 'mS-SQL-GPSLongitude' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1437 NAME 'msPKI-Supersede-Templates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1707 NAME 'msDS-ReplAttributeMetaData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.652 NAME 'assistant' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1644 NAME 'msWMI-SourceOrganization' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1443 NAME 'msDS-Site-Affinity' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.286 NAME 'printRateUnit' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1444 NAME 'msDS-Preferred-GC-Site' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.589 NAME 'meetingBandwidth' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.1706 NAME 'msDS-NCReplOutboundNeighbors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1709 NAME 'msDS-HasInstantiatedNCs' SYNTAX '1.2.840.113556.1.4.903' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.79 NAME 'minPwdLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1952 NAME 'ms-net-ieee-80211-GP-PolicyData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.865 NAME 'pekList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 2.5.4.26 NAME 'registeredAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2179 NAME 'msKds-CreateTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2149 NAME 'msDNS-NSEC3CurrentSalt' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1815 NAME 'msDS-TasksForAzRoleBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2148 NAME 'msDNS-NSEC3UserSalt' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2197 NAME 'msDS-ManagedPasswordId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1407 NAME 'mS-SQL-ThirdParty' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.510 NAME 'serviceBindingInformation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1416 NAME 'mSMQSiteNameEx' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1426 NAME 'msCOM-UserPartitionSetLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1303 NAME 'tokenGroupsNoGCAcceptable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.596 NAME 'msExchHouseIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2233 NAME 'msDS-cloudExtensionAttribute20' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.335 NAME 'currentLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.20 NAME 'homePhone' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1441 NAME 'msDS-Cached-Membership' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.14 NAME 'msDFSR-Schedule' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.622 NAME 'ipsecDataType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.645 NAME 'userCert' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.367 NAME 'rpcNsCodeset' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.223 NAME 'serverName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.950 NAME 'mSMQServices' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2250 NAME 'msDS-DeviceOSVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.332 NAME 'birthLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1440 NAME 'msDs-Schema-Extensions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1348 NAME 'gPCMachineExtensionNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1833 NAME 'msDS-ExternalKey' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.858 NAME 'netbootTools' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1717 NAME 'msDS-AdditionalDnsHostName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.770 NAME 'aCSEnableACSService' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.170 NAME 'systemOnly' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.32 NAME 'domainPolicyObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.766 NAME 'aCSAllocableRSVPBandwidth' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.9 NAME 'helpData32' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1805 NAME 'msDS-AzGenerateAudits' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.276 NAME 'driverVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1317 NAME 'aCSMinimumDelayVariation' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.302 NAME 'sAMAccountType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.610 NAME 'employeeNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.30 NAME 'attributeID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTTL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1843 NAME 'msDRM-IdentityCertificate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.6.13.3.103 NAME 'msDFSR-ComputerReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1989 NAME 'msTSWorkDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1674 NAME 'msPKI-Certificate-Application-Policy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.716 NAME 'mscopeId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.514 NAME 'physicalLocationObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.570 NAME 'meetingProtocol' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.2.370 NAME 'objectClassCategory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.15 NAME 'msDFSR-Keywords' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.812 NAME 'createWizardExt' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.61 NAME 'lockOutObservationWindow' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.750 NAME 'groupType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1459 NAME 'msDS-Behavior-Version' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.937 NAME 'mSMQSignKey' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.913 NAME 'allowedAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.120 NAME 'uSNChanged' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.340 NAME 'rightsGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.277 NAME 'otherHomePhone' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1309 NAME 'mSMQInterval2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1439 NAME 'msPKI-Certificate-Policy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1308 NAME 'mSMQInterval1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1383 NAME 'mS-SQL-ConnectionURL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2176 NAME 'msKds-Version' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.859 NAME 'netbootLocallyInstalledOSes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.967 NAME 'mSMQSignCertificatesMig' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2232 NAME 'msDS-cloudExtensionAttribute19' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2231 NAME 'msDS-cloudExtensionAttribute18' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2230 NAME 'msDS-cloudExtensionAttribute17' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2229 NAME 'msDS-cloudExtensionAttribute16' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2228 NAME 'msDS-cloudExtensionAttribute15' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2227 NAME 'msDS-cloudExtensionAttribute14' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2226 NAME 'msDS-cloudExtensionAttribute13' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2225 NAME 'msDS-cloudExtensionAttribute12' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2142 NAME 'msDNS-SecureDelegationPollingPeriod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2224 NAME 'msDS-cloudExtensionAttribute11' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.718 NAME 'dhcpProperties' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2223 NAME 'msDS-cloudExtensionAttribute10' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.157 NAME 'serverRole' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1394 NAME 'mS-SQL-AllowAnonymousSubscription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.563 NAME 'shellPropertyPages' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1315 NAME 'aCSMinimumPolicedSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.273 NAME 'printStatus' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.644 NAME 'showInAddressBook' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.626 NAME 'ipsecISAKMPReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1925 NAME 'msDS-hasFullReplicaNCs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.940 NAME 'mSMQCSPName' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.30 NAME 'msDFSR-MinDurationCacheInMin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.243 NAME 'printColor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2193 NAME 'msDS-TDOIngressBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1993 NAME 'msTSExpireDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 2.5.4.2 NAME 'knowledgeInformation' SYNTAX '1.2.840.113556.1.4.905' )", + "( 1.2.840.113556.1.4.908 NAME 'extendedClassInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.953 NAME 'mSMQSiteID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2040 NAME 'msDFS-LinkSecurityDescriptorv2' SYNTAX '1.2.840.113556.1.4.907' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1343 NAME 'dSUIAdminNotification' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1700 NAME 'msTAPI-ConferenceBlob' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.486 NAME 'fRSWorkingPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.62 NAME 'scriptPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1810 NAME 'msDS-TasksForAzTask' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.6.13.3.31 NAME 'msDFSR-MaxAgeInCacheInMin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.19 NAME 'cOMClassID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.108 NAME 'remoteSourceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.704 NAME 'dhcpServers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.876 NAME 'fRSMemberReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2261 NAME 'msDS-DeviceLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.82 NAME 'moniker' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.289 NAME 'printMediaReady' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1209 NAME 'shortServerName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.910 NAME 'fromEntry' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.636 NAME 'privilegeAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2025 NAME 'msDS-IsUserCachableAtRodc' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1715 NAME 'msDS-SPNSuffixes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.562 NAME 'adminPropertyPages' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 0.9.2342.19200300.100.1.10 NAME 'manager' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 2.5.4.49 NAME 'distinguishedName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1356 NAME 'validAccesses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2053 NAME 'msImaging-PSPIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.459 NAME 'machineWidePolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1403 NAME 'mS-SQL-AllowKnownPullSubscription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.283 NAME 'assetNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.885 NAME 'terminalServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2012 NAME 'msDS-MinimumPasswordAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.7 NAME 'msDFSR-ConflictPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1831 NAME 'msDS-ByteArray' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.135 NAME 'trustAuthOutgoing' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2258 NAME 'msDS-RegisteredOwner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.608 NAME 'queryPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.109 NAME 'replicaSource' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2296 NAME 'msDS-AssignedAuthNPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.402 NAME 'helpData16' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.232 NAME 'defaultPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1388 NAME 'mS-SQL-Version' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.364 NAME 'operatingSystemVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2284 NAME 'msDS-ServiceTGTLifetime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1460 NAME 'msDS-User-Account-Control-Computed' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.75 NAME 'maxRenewAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.285 NAME 'printRate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.911 NAME 'allowedChildClasses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.615 NAME 'personalTitle' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1225 NAME 'mSMQPrevSiteGates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.2131 NAME 'msDNS-SignWithNSEC3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2007 NAME 'msTSLicenseVersion4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2004 NAME 'msTSLicenseVersion3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2001 NAME 'msTSLicenseVersion2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.507 NAME 'volumeCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.137 NAME 'uNCName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2022 NAME 'msDS-ResultantPSO' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.168 NAME 'modifiedCount' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1809 NAME 'msDS-OperationsForAzTaskBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.328 NAME 'versionNumberHi' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2099 NAME 'msDS-ClaimAttributeSource' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.754 NAME 'rpcNsEntryFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.778 NAME 'aCSDSBMDeadTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.917 NAME 'mSMQQueueType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.326 NAME 'packageName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.422 NAME 'domainPolicyReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2241 NAME 'msDS-RegistrationQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.3 NAME 'msDFSR-RootPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1817 NAME 'msDS-AzApplicationVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.436 NAME 'directReports' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.240 NAME 'printOrientationsSupported' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.574 NAME 'meetingLanguage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.43 NAME 'fRSVersionGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 2.5.4.30 NAME 'supportedApplicationContext' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.26 NAME 'rDNAttID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1409 NAME 'masteredBy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.752 NAME 'userSharedFolderOther' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2199 NAME 'msDS-ManagedPasswordInterval' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1932 NAME 'msDS-IsFullReplicaFor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.22 NAME 'msDFSR-RootFence' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.789 NAME 'transportDLLName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.499 NAME 'contextMenu' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.202 NAME 'auditingPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.11 NAME 'msDFSR-TombstoneExpiryInMin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1364 NAME 'mS-SQL-RegisteredOwner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.8 NAME 'userClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.775 NAME 'aCSMaxSizeOfRSVPLogFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.144 NAME 'operatorCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1238 NAME 'mSMQDsService' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1984 NAME 'msTSReconnectionAction' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2286 NAME 'msDS-AssignedAuthNPolicySiloBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2180 NAME 'msImaging-ThumbprintHash' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.68 NAME 'machineArchitecture' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.1311 NAME 'printDuplexSupported' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1795 NAME 'msDS-AzDomainTimeout' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1992 NAME 'msTSProperty02' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.583 NAME 'meetingURL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1991 NAME 'msTSProperty01' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.635 NAME 'privilegeValue' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2100 NAME 'msDS-ClaimTypeAppliesToClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.115 NAME 'invocationId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2288 NAME 'msDS-AuthNPolicySiloMembersBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1681 NAME 'msWMI-intFlags4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1680 NAME 'msWMI-intFlags3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1679 NAME 'msWMI-intFlags2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1678 NAME 'msWMI-intFlags1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.100 NAME 'msDFSR-MemberReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.100 NAME 'priorValue' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1379 NAME 'mS-SQL-Vines' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1377 NAME 'mS-SQL-TCPIP' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2172 NAME 'msKds-SecretAgreementParam' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2222 NAME 'msDS-cloudExtensionAttribute9' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2221 NAME 'msDS-cloudExtensionAttribute8' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2220 NAME 'msDS-cloudExtensionAttribute7' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2219 NAME 'msDS-cloudExtensionAttribute6' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2218 NAME 'msDS-cloudExtensionAttribute5' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.661 NAME 'isDefunct' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2217 NAME 'msDS-cloudExtensionAttribute4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.653 NAME 'managedBy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2216 NAME 'msDS-cloudExtensionAttribute3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2215 NAME 'msDS-cloudExtensionAttribute2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2214 NAME 'msDS-cloudExtensionAttribute1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.588 NAME 'meetingEndTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' )", + "( 1.2.840.113556.1.4.498 NAME 'creationWizard' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1915 NAME 'msRADIUS-FramedIpv6Prefix' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.12 NAME 'msDFSR-FileFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.24 NAME 'x121Address' SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' )", + "( 1.2.840.113556.1.4.637 NAME 'privilegeHolder' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.214 NAME 'originalDisplayTableMSDOS' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.211 NAME 'schedule' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1228 NAME 'mSMQDsServices' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.64 NAME 'logonHours' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.883 NAME 'msRRASVendorAttributeEntry' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.58 NAME 'localeID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.97 NAME 'preferredOU' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2033 NAME 'msDFS-NamespaceIdentityGUIDv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1334 NAME 'pKIDefaultCSPs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1411 NAME 'ms-DS-MachineAccountQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.891 NAME 'gPLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.617 NAME 'homePostalAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.320 NAME 'implementedCategories' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.19 NAME 'uSNCreated' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.651 NAME 'otherMailbox' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.345 NAME 'msSFU30NSMAPFieldPosition' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.618 NAME 'wellKnownObjects' SYNTAX '1.2.840.113556.1.4.903' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2160 NAME 'msDS-ClaimIsSingleValued' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.1 NAME 'msDFSR-Version' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.874 NAME 'fRSFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1713 NAME 'MSMQ-SecuredSource' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.825 NAME 'enrollmentProviders' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.666 NAME 'syncAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.665 NAME 'syncMembership' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.48 NAME 'keywords' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2169 NAME 'msKds-KDFAlgorithmID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.370 NAME 'rIDAvailablePool' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.214 NAME 'nextLevelStore' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1145 NAME 'msRADIUSCallbackNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.303 NAME 'msSFU30IntraFieldSeparator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.346 NAME 'desktopProfile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.20 NAME 'cOMInterfaceID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.279 NAME 'printMinXExtent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1213 NAME 'assocNTAccount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.671 NAME 'msiFileList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2032 NAME 'msDFS-GenerationGUIDv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2279 NAME 'msDS-UserTGTLifetime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.10 NAME 'msDFSR-ReplicationGroupType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1790 NAME 'msDS-PerUserTrustTombstonesQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1124 NAME 'msNPCallingStationID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.487 NAME 'fRSRootPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1807 NAME 'msDS-MembersForAzRoleBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1823 NAME 'msieee80211-ID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.791 NAME 'transportType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.674 NAME 'rootTrust' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1641 NAME 'msWMI-PropertyName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.25 NAME 'mayContain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )", + "( 1.2.840.113556.1.4.1438 NAME 'msPKI-RA-Policies' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.769 NAME 'aCSEventLogLevel' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.945 NAME 'mSMQSiteGates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.25 NAME 'internationalISDNNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' )", + "( 1.2.840.113556.1.4.1979 NAME 'msTSAllowLogon' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.274 NAME 'printSpooling' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.242 NAME 'printCollate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1345 NAME 'dSUIShellMaximum' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.693 NAME 'pendingCACertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2257 NAME 'msDS-DeviceObjectVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.852 NAME 'netbootCurrentClientCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.534 NAME 'fRSLevelLimit' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1685 NAME 'msWMI-Parm4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1684 NAME 'msWMI-Parm3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1988 NAME 'msTSDefaultToMainPrinter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1913 NAME 'msRADIUS-FramedInterfaceId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.353 NAME 'displayNamePrintable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1696 NAME 'lastLogonTimestamp' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1683 NAME 'msWMI-Parm2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.330 NAME 'lastUpdateSequence' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.696 NAME 'currentParentCA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.689 NAME 'cRLObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1682 NAME 'msWMI-Parm1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.22 NAME 'governsID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1632 NAME 'msWMI-Int8Default' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.169 NAME 'logonCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.772 NAME 'aCSPolicyName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.38 NAME 'authorityRevocationList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1212 NAME 'isEphemeral' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.324 NAME 'packageType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1435 NAME 'msPKI-Template-Minor-Revision' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2010 NAME 'msTSLSProperty02' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1961 NAME 'msDS-SiteName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2009 NAME 'msTSLSProperty01' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1336 NAME 'replInterval' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2066 NAME 'msDS-RequiredDomainBehaviorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2185 NAME 'msDS-GeoCoordinatesLongitude' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2182 NAME 'msDS-AllowedToActOnBehalfOfOtherIdentity' SYNTAX '1.2.840.113556.1.4.907' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.8 NAME 'msDFSR-ConflictSizeInMb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.357 NAME 'nTMixedDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2191 NAME 'msDS-IngressClaimsTransformationPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1892 NAME 'msPKIRoamingTimeStamp' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2174 NAME 'msKds-PrivateKeyLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.324 NAME 'addressEntryDisplayTable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.218 NAME 'applicationName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1318 NAME 'aCSNonReservedPeakRate' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2023 NAME 'msDS-PasswordSettingsPrecedence' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.99 NAME 'priorSetTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.914 NAME 'allowedAttributesEffective' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.271 NAME 'printOwner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1996 NAME 'msDS-UserPasswordExpiryTimeComputed' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.930 NAME 'mSMQServiceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1780 NAME 'hideFromAB' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.578 NAME 'meetingContactInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2020 NAME 'msDS-PSOAppliesTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1944 NAME 'msDS-PhoneticDepartment' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1792 NAME 'msDS-AzLDAPQuery' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.251 NAME 'cOMTreatAsClassId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.14 NAME 'builtinModifiedCount' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.7 NAME 'shadowMax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.325 NAME 'setupCommand' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1647 NAME 'msWMI-TargetObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.420 NAME 'publicKeyPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1714 NAME 'MSMQ-MulticastAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1677 NAME 'msWMI-Genus' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2281 NAME 'msDS-ComputerTGTLifetime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1671 NAME 'msPKI-OID-Attribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.36 NAME 'dMDLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.810 NAME 'createDialog' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2140 NAME 'msDNS-DSRecordSetTTL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1358 NAME 'schemaInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1624 NAME 'msWMI-ChangeDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1975 NAME 'msDS-RevealedListBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1962 NAME 'msDS-PromotionSettings' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.229 NAME 'driverName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.378 NAME 'dnsAllowDynamic' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1246 NAME 'interSiteTopologyGenerator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.817 NAME 'localizedDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2235 NAME 'msDS-ReplValueMetaDataExt' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1933 NAME 'msDS-IsDomainFor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2213 NAME 'msDS-RIDPoolAllocationEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.73 NAME 'lockoutThreshold' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.50 NAME 'lastContentIndexed' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.824 NAME 'signatureAlgorithms' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.860 NAME 'netbootServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.40 NAME 'msDFSR-StagingCleanupTriggerInPercent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1695 NAME 'msMQ-Recipient-FormatName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1966 NAME 'msTPM-OwnerInformation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.156 NAME 'comment' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.650 NAME 'mhsORAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.929 NAME 'mSMQInRoutingServers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1787 NAME 'msDS-AllowedToDelegateTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1389 NAME 'mS-SQL-Language' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.18 NAME 'msDFSR-ContentSetGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.8 NAME 'possSuperiors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )", + "( 1.2.840.113556.1.4.912 NAME 'allowedChildClassesEffective' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2132 NAME 'msDNS-NSEC3OptOut' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.136 NAME 'trustType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1879 NAME 'msDS-SourceObjectDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.533 NAME 'fRSReplicaSetGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1434 NAME 'msPKI-Template-Schema-Version' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.241 NAME 'printMaxCopies' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.961 NAME 'mSMQSiteForeign' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' )", + "( 1.2.840.113556.1.4.1808 NAME 'msDS-OperationsForAzTask' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1242 NAME 'dNReferenceUpdate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 0.9.2342.19200300.100.1.5 NAME 'drink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1923 NAME 'msDS-KrbTgtLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1402 NAME 'mS-SQL-Publisher' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2018 NAME 'msDS-LockoutDuration' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.688 NAME 'cAWEBURL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.23 NAME 'bootParameter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.536 NAME 'fRSExtensions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.233 NAME 'printStartTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1788 NAME 'msDS-PerUserTrustQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.159 NAME 'accountExpires' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1390 NAME 'mS-SQL-Description' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.224 NAME 'defaultSecurityDescriptor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113549.1.9.2 NAME 'unstructuredName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.695 NAME 'pendingParentCA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1375 NAME 'mS-SQL-MultiProtocol' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2152 NAME 'msAuthz-LastEffectiveSecurityPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.56 NAME 'localPolicyFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1392 NAME 'mS-SQL-InformationDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2159 NAME 'msDS-ClaimIsValueSpaceRestricted' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.708 NAME 'dhcpSites' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.717 NAME 'dhcpState' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.762 NAME 'aCSServiceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.132 NAME 'trustDirection' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.312 NAME 'rpcNsObjectID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1395 NAME 'mS-SQL-Alias' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.18.2 NAME 'modifyTimeStamp' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2145 NAME 'msDNS-DNSKEYRecords' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.301 NAME 'wbemPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.0 NAME 'objectClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.21 NAME 'msDFSR-DfsPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1429 NAME 'msPKI-RA-Signature' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1699 NAME 'msTAPI-ProtocolId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2086 NAME 'msSPP-PhoneLicense' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.120 NAME 'schemaFlagsEx' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1945 NAME 'msDS-PhoneticCompanyName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.916 NAME 'canonicalName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.702 NAME 'dhcpObjName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2238 NAME 'msds-memberTransitive' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.133 NAME 'trustPartner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.927 NAME 'mSMQSites' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.867 NAME 'altSecurityIdentities' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.615 NAME 'shellContextMenu' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.866 NAME 'pekKeyChangeInterval' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2046 NAME 'addressBookRoots2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.27 NAME 'currentValue' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.166 NAME 'groupMembershipSAM' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1926 NAME 'msDS-NeverRevealGroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.6.13.3.28 NAME 'msDFSR-ReadOnly' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1314 NAME 'aCSMaximumSDUSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.457 NAME 'localPolicyReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1189 NAME 'msRASSavedCallbackNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1918 NAME 'msRADIUS-SavedFramedIpv6Route' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 2.5.21.2 NAME 'dITContentRules' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.895 NAME 'transportAddressAttribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1418 NAME 'tokenGroupsGlobalAndUniversal' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.850 NAME 'netbootLimitClients' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.944 NAME 'mSMQSite2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.943 NAME 'mSMQSite1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1664 NAME 'msDS-Replication-Notify-Subsequent-DSA-Delay' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.537 NAME 'dynamicLDAPServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2249 NAME 'msDS-DeviceOSType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.35 NAME 'employeeID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2137 NAME 'msDNS-NSEC3RandomSaltLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2151 NAME 'msAuthz-ProposedSecurityPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.267 NAME 'uSNDSALastObjRemoved' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.963 NAME 'mSMQQueueJournalQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.607 NAME 'queryPolicyObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1978 NAME 'msTSHomeDrive' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.593 NAME 'msExchLabeledURI' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1329 NAME 'pKIMaxIssuingDepth' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2061 NAME 'msDS-EnabledFeature' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.278 NAME 'printMaxYExtent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.16 NAME 'codePage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1802 NAME 'msDS-AzBizRuleLanguage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.363 NAME 'operatingSystem' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.761 NAME 'aCSMaxDurationPerFlow' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.921 NAME 'mSMQJournalQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2106 NAME 'msSPP-CSVLKPartialProductKey' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1190 NAME 'msRASSavedFramedIPAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2171 NAME 'msKds-SecretAgreementAlgorithmID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.703 NAME 'dhcpObjDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.890 NAME 'uPNSuffixes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1720 NAME 'msDS-ReplicationEpoch' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.24 NAME 'bootFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.614 NAME 'adminContextMenu' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.2.231 NAME 'oMSyntax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.8 NAME 'userAccountControl' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.621 NAME 'ipsecID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.511 NAME 'flatName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.784 NAME 'aCSIdentityName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.15 NAME 'msiScriptPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.125 NAME 'supplementalCredentials' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2287 NAME 'msDS-AuthNPolicySiloMembers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.199 NAME 'serviceInstanceVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1347 NAME 'sPNMappings' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.933 NAME 'mSMQComputerType' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.780 NAME 'aCSNonReservedTxLimit' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1227 NAME 'mSMQRoutingServices' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2074 NAME 'msTSPrimaryDesktopBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 2.5.18.1 NAME 'createTimeStamp' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1130 NAME 'msNPSavedCallingStationID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.700 NAME 'dhcpFlags' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.629 NAME 'ipsecFilterReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.40 NAME 'fromServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.568 NAME 'meetingKeyword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2178 NAME 'msKds-UseStartTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1321 NAME 'aCSNonReservedMinPolicedSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.246 NAME 'printLanguage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.2.54 NAME 'tombstoneLifetime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.765 NAME 'aCSPermissionBits' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1398 NAME 'mS-SQL-LastBackupDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2 NAME 'objectGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.146 NAME 'company' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1710 NAME 'msDS-AllowedDNSSuffixes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1841 NAME 'msDS-ObjectReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 2.5.4.8 NAME 'st' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.341 NAME 'msSFU30YpServers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 2.5.4.4 NAME 'sn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.707 NAME 'dhcpRanges' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.282 NAME 'printMemory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.924 NAME 'mSMQPrivacyLevel' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.333 NAME 'oMTIndxGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.205 NAME 'pKTGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2251 NAME 'msDS-DevicePhysicalIDs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1410 NAME 'mS-DS-CreatorSID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.345 NAME 'groupPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2030 NAME 'msDFS-SchemaMajorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.513 NAME 'siteObjectBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.87 NAME 'nETBIOSName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2175 NAME 'msKds-RootKeyData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.24 NAME 'mustContain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )", + "( 2.5.4.51 NAME 'houseIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.3.6.1.1.1.1.26 NAME 'nisMapName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1917 NAME 'msRADIUS-FramedIpv6Route' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.6.18.1.307 NAME 'msSFU30MasterServerName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.98 NAME 'primaryGroupID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1837 NAME 'msDs-masteredBy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.200 NAME 'controlAccessRights' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1158 NAME 'msRADIUSFramedRoute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.107 NAME 'remoteSource' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1971 NAME 'msDS-LastFailedInteractiveLogonTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1958 NAME 'msDS-AuthenticatedAtDC' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.5 NAME 'serialNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.509 NAME 'serviceClassName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2050 NAME 'msPKI-CredentialRoamingTokens' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.4.2008 NAME 'msTSManagingLS4' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2005 NAME 'msTSManagingLS3' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2002 NAME 'msTSManagingLS2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1363 NAME 'mS-SQL-Name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.41 NAME 'mobile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2108 NAME 'msTPM-OwnerInformationTemp' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.886 NAME 'purportedSearch' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1384 NAME 'mS-SQL-PublicationURL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2271 NAME 'msDS-CloudIsManaged' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.41 NAME 'generatedConnection' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.864 NAME 'netbootSCPBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1396 NAME 'mS-SQL-Size' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.115 NAME 'rpcNsInterfaceID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.619 NAME 'dNSHostName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2273 NAME 'msDS-CloudAnchor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.939 NAME 'mSMQNameStyle' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.882 NAME 'fRSVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.777 NAME 'aCSDSBMRefresh' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.80 NAME 'minTicketAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1310 NAME 'mSMQSiteGatesMig' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.83 NAME 'monikerDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2150 NAME 'msAuthz-EffectiveSecurityPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.15 NAME 'hasPartialReplicaNCs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2194 NAME 'msDS-TDOEgressBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1811 NAME 'msDS-TasksForAzTaskBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1987 NAME 'msTSConnectPrinterDrives' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1953 NAME 'ms-net-ieee-80211-GP-PolicyReserved' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1313 NAME 'aCSMaxTokenBucketPerFlow' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.579 NAME 'meetingOwner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.12 NAME 'badPwdCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.39 NAME 'forceLogoff' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.326 NAME 'perRecipDialogDisplayTable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.51 NAME 'lastLogoff' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1796 NAME 'msDS-AzScriptEngineCacheMax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2269 NAME 'msDS-IssuerPublicCertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1639 NAME 'msWMI-Name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.4 NAME 'replUpToDateVector' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.470 NAME 'trustAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.515 NAME 'serverReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.308 NAME 'msSFU30OrderNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1669 NAME 'msDS-Approx-Immed-Subordinates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2141 NAME 'msDNS-SignatureInceptionOffset' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2186 NAME 'msDS-IsPossibleValuesPresent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.78 NAME 'minPwdAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.339 NAME 'msSFU30NisDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1701 NAME 'msTAPI-IpAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.249 NAME 'cOMCLSID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.774 NAME 'aCSMaxNoOfLogFiles' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.494 NAME 'siteServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.849 NAME 'netbootAllowNewClients' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1931 NAME 'msDS-KrbTgtLinkBl' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1789 NAME 'msDS-AllUsersTrustQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2156 NAME 'msAuthz-MemberRulesInCentralAccessPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.721 NAME 'ipPhone' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.613 NAME 'employeeType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1634 NAME 'msWMI-Int8Min' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2248 NAME 'msDS-IsEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1950 NAME 'msDS-AzGenericData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1646 NAME 'msWMI-TargetNameSpace' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.816 NAME 'fileExtPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.712 NAME 'optionDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.321 NAME 'requiredCategories' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.255 NAME 'addressSyntax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2110 NAME 'msTPM-TpmInformationForComputerBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1785 NAME 'msIIS-FTPRoot' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.518 NAME 'defaultHidingValue' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.946 NAME 'mSMQCost' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 2.5.4.44 NAME 'generationQualifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.681 NAME 'indexedScopes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1865 NAME 'msDS-PrincipalName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2073 NAME 'msTSPrimaryDesktop' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.697 NAME 'cACertificateDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1354 NAME 'scopeFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1942 NAME 'msDS-PhoneticFirstName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1997 NAME 'msDS-HABSeniorityIndex' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1307 NAME 'accountNameHistory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.893 NAME 'gPCFunctionalityVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2203 NAME 'msDS-parentdistname' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1687 NAME 'extraColumns' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1834 NAME 'msDS-ExternalStore' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1983 NAME 'msTSMaxIdleTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.687 NAME 'cAConnect' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2048 NAME 'templateRoots2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.154 NAME 'serverState' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1224 NAME 'parentGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.926 NAME 'mSMQTransactional' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.925 NAME 'mSMQOwnerID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2035 NAME 'msDFS-Ttlv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.150 NAME 'adminCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2041 NAME 'msDFS-LinkIdentityGUIDv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.490 NAME 'fRSDSPoll' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2015 NAME 'msDS-PasswordComplexityEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.105 NAME 'remoteServerName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.531 NAME 'nonSecurityMemberBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 2.16.840.1.113730.3.1.36 NAME 'thumbnailLogo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.586 NAME 'meetingRecurrence' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1643 NAME 'msWMI-QueryLanguage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.962 NAME 'mSMQQueueQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1415 NAME 'mSMQLabelEx' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.16 NAME 'nCName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2170 NAME 'msKds-KDFParam' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.567 NAME 'meetingDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1704 NAME 'msDS-NCReplCursors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.23 NAME 'facsimileTelephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.851 NAME 'netbootMaxClients' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2016 NAME 'msDS-PasswordReversibleEncryptionEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1635 NAME 'msWMI-Int8ValidValues' SYNTAX '1.2.840.113556.1.4.906' )", + "( 1.2.840.113556.1.4.719 NAME 'dhcpMaxKey' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1835 NAME 'msDS-Integer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.1208 NAME 'aNR' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1393 NAME 'mS-SQL-Database' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.42 NAME 'pager' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1914 NAME 'msRADIUS-SavedFramedInterfaceId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1391 NAME 'mS-SQL-Type' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.566 NAME 'meetingName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.123 NAME 'serviceClassInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.26 NAME 'creationTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.103 NAME 'proxyLifetime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.660 NAME 'treeName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.892 NAME 'gPOptions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.923 NAME 'mSMQAuthenticate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1432 NAME 'msPKI-Certificate-Name-Flag' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.206 NAME 'pKT' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.287 NAME 'printNetworkAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1431 NAME 'msPKI-Private-Key-Flag' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1346 NAME 'templateRoots' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.657 NAME 'serviceDNSName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.868 NAME 'isCriticalSystemObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.301 NAME 'garbageCollPeriod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.288 NAME 'printMACAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1304 NAME 'sDRightsEffective' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.380 NAME 'extendedCharsAllowed' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.86 NAME 'userWorkstations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1360 NAME 'mS-DS-ConsistencyGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1712 NAME 'msPKI-OIDLocalizedName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.21.5 NAME 'attributeTypes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.31 NAME 'fRSReplicaSetType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.341 NAME 'appliesTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.11 NAME 'ou' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2293 NAME 'msDS-ServiceAuthNPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.346 NAME 'msSFU30PosixMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1973 NAME 'msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 2.5.18.10 NAME 'subSchemaSubEntry' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2262 NAME 'msDS-ApproximateLastLogonTimeStamp' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.222 NAME 'location' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.854 NAME 'netbootAnswerOnlyValidClients' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1949 NAME 'msDS-AzObjectGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 2.16.840.1.113730.3.1.34 NAME 'middleName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2158 NAME 'msDS-ClaimSourceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.706 NAME 'dhcpMask' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.2109 NAME 'msTPM-TpmInformationForComputer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.623 NAME 'ipsecData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1171 NAME 'msRADIUSServiceType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.705 NAME 'dhcpSubnets' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.1999 NAME 'msFVE-KeyPackage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1968 NAME 'msDS-NC-RO-Replica-Locations-BL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.36 NAME 'enabledConnection' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.472 NAME 'domainCrossRef' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.52 NAME 'lastLogon' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.28 NAME 'dnsRoot' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.966 NAME 'mSMQDigestsMig' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.878 NAME 'fRSPrimaryMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1848 NAME 'msDS-QuotaEffective' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1372 NAME 'mS-SQL-UnicodeSortOrder' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.639 NAME 'isMemberOfPartialAttributeSet' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.464 NAME 'wWWHomePage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.711 NAME 'superScopeDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1631 NAME 'msWMI-IntValidValues' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.3.6.1.1.1.1.2 NAME 'gecos' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2063 NAME 'msDS-OptionalFeatureFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.38 NAME 'flags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1240 NAME 'netbootSIFFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.690 NAME 'cAUsages' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2104 NAME 'msDS-MembersOfResourcePropertyListBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.66 NAME 'lSACreationTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.709 NAME 'dhcpReservations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.4.934 NAME 'mSMQForeign' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1963 NAME 'msDS-SupportedEncryptionTypes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1401 NAME 'mS-SQL-Keywords' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1705 NAME 'msDS-NCReplInboundNeighbors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2128 NAME 'msDNS-KeymasterZones' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.19 NAME 'physicalDeliveryOfficeName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1694 NAME 'gPCWQLFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.195 NAME 'systemPossSuperiors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.218 NAME 'oMObjectClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1226 NAME 'mSMQDependentClientServices' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1676 NAME 'msWMI-Class' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2144 NAME 'msDNS-SigningKeys' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1630 NAME 'msWMI-IntMin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.372 NAME 'rIDPreviousAllocationPool' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.848 NAME 'appSchemaVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1981 NAME 'msTSMaxDisconnectionTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1645 NAME 'msWMI-TargetClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.535 NAME 'fRSRootSecurity' SYNTAX '1.2.840.113556.1.4.907' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1423 NAME 'msCOM-PartitionLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.32 NAME 'owner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1436 NAME 'msPKI-Cert-Template-OID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1716 NAME 'msDS-IntId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.18.1.309 NAME 'msSFU30Name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.254 NAME 'cOMTypelibId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1642 NAME 'msWMI-Query' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.155 NAME 'uASCompat' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1623 NAME 'msWMI-Author' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1964 NAME 'msFVE-RecoveryPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.764 NAME 'aCSPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.571 NAME 'meetingType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.783 NAME 'defaultObjectCategory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1365 NAME 'mS-SQL-Contact' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.679 NAME 'creator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.39 NAME 'certificateRevocationList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.699 NAME 'dhcpType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1405 NAME 'mS-SQL-AllowQueuedUpdatingSubscription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.915 NAME 'possibleInferiors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2234 NAME 'netbootDUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.899 NAME 'aCSEnableRSVPAccounting' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.881 NAME 'fRSTimeLastConfigChange' SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.55 NAME 'audio' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.898 NAME 'aCSNonReservedTxSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.771 NAME 'servicePrincipalName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1820 NAME 'msDS-HasDomainNCs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2070 NAME 'msTSEndpointData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.620 NAME 'ipsecName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.458 NAME 'qualityOfService' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2042 NAME 'msDFS-ShortNameLinkPathv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1688 NAME 'msDS-Security-Group-Extra-Classes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2289 NAME 'msDS-UserAuthNPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.83 NAME 'repsTo' SYNTAX 'OctetString' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1357 NAME 'dSCorePropagationData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2196 NAME 'msDS-ManagedPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.647 NAME 'otherMobile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2072 NAME 'msTSEndpointPlugin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.749 NAME 'url' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.701 NAME 'dhcpIdentification' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.122 NAME 'serviceClassID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2058 NAME 'isRecycled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.213 NAME 'defaultClassStore' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.2252 NAME 'msDS-DeviceID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.633 NAME 'policyReplicationFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1693 NAME 'msFRS-Hub-Member' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1328 NAME 'pKIKeyUsage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.459 NAME 'networkAddress' SYNTAX '1.2.840.113556.1.4.905' )", + "( 1.2.840.113556.1.4.1786 NAME 'msIIS-FTPDir' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.806 NAME 'treatAsLeaf' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.820 NAME 'bridgeheadServerListBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.13.3.36 NAME 'msDFSR-OnDemandExclusionDirectoryFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.640 NAME 'partialAttributeSet' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.853 NAME 'netbootAnswerRequests' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 2.5.4.31 NAME 'member' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.6.18.1.323 NAME 'msSFU30Aliases' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1243 NAME 'mSMQQueueNameExt' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1370 NAME 'mS-SQL-CharacterSet' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1622 NAME 'msDS-Entry-Time-To-Die' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.460 NAME 'lDAPDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2031 NAME 'msDFS-SchemaMinorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.12 NAME 'memberUid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1800 NAME 'msDS-AzOperationID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.322 NAME 'categoryId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.60 NAME 'lockoutDuration' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.870 NAME 'frsComputerReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 2.5.4.45 NAME 'x500uniqueIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.6.13.3.25 NAME 'msDFSR-Priority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.847 NAME 'installUiLevel' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1842 NAME 'msDs-MaxValues' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 2.5.4.9 NAME 'street' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2154 NAME 'msAuthz-CentralAccessPolicyID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.3 NAME 'whenChanged' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1433 NAME 'msPKI-Minimal-Key-Size' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1814 NAME 'msDS-TasksForAzRole' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.6.13.3.101 NAME 'msDFSR-ComputerReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.580 NAME 'meetingIP' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.539 NAME 'initialAuthIncoming' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.356 NAME 'foreignIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.565 NAME 'meetingID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.3 NAME 'unixHomeDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1721 NAME 'msDS-UpdateScript' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.557 NAME 'parentCA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.255 NAME 'vendor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.900 NAME 'aCSRSVPAccountFilesLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1320 NAME 'aCSNonReservedMaxSDUSize' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1956 NAME 'ms-net-ieee-8023-GP-PolicyReserved' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.773 NAME 'aCSRSVPLogFilesLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.951 NAME 'mSMQQMID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.102 NAME 'memberOf' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1397 NAME 'mS-SQL-CreationDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2146 NAME 'msDNS-ParentHasSecureDelegation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.113 NAME 'rpcNsBindings' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.656 NAME 'userPrincipalName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1934 NAME 'msDS-IsPartialReplicaFor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2167 NAME 'msDS-PrimaryComputer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.469 NAME 'USNIntersite' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1803 NAME 'msDS-AzLastImportedBizRulePath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2295 NAME 'msDS-AssignedAuthNPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 2.5.4.13 NAME 'description' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.922 NAME 'mSMQLabel' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2024 NAME 'msDS-NcType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2011 NAME 'msDS-MaximumPasswordAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2291 NAME 'msDS-ComputerAuthNPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1832 NAME 'msDS-DateTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' )", + "( 1.2.840.113556.1.2.281 NAME 'nTSecurityDescriptor' SYNTAX '1.2.840.113556.1.4.907' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.722 NAME 'otherIpPhone' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1368 NAME 'mS-SQL-Build' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.219 NAME 'iconPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1417 NAME 'mSMQComputerTypeEx' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.38 NAME 'associatedName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1986 NAME 'msTSConnectClientDrives' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2285 NAME 'msDS-AssignedAuthNPolicySilo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1638 NAME 'msWMI-Mof' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.314 NAME 'rpcNsTransferSyntax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1702 NAME 'msDS-TrustForestTrustInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.557 NAME 'Enabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.21 NAME 'subClassOf' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1845 NAME 'msDS-QuotaAmount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1119 NAME 'msNPAllowDialin' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.33 NAME 'isSingleValued' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.782 NAME 'objectCategory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2177 NAME 'msKds-DomainID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2195 NAME 'msDS-AppliesToResourceTypes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.152 NAME 'groupAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.334 NAME 'volTableIdxGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.272 NAME 'printNotify' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.334 NAME 'searchFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2298 NAME 'msDS-AuthNPolicySiloEnforced' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1428 NAME 'msCOM-ObjectId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.400 NAME 'addressEntryDisplayTableMSDOS' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.81 NAME 'modifiedCountAtLastProm' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.71 NAME 'machineRole' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1123 NAME 'msNPCalledStationID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.654 NAME 'managedObjects' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.638 NAME 'isPrivilegeHolder' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.197 NAME 'systemMustContain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.91 NAME 'otherLoginWorkstations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.13.3.32 NAME 'msDFSR-DisablePacketPrivacy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2297 NAME 'msDS-AuthNPolicyEnforced' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.576 NAME 'meetingMaxParticipants' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.4 NAME 'loginShell' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.779 NAME 'aCSCacheTimeout' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.751 NAME 'userSharedFolder' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.342 NAME 'msSFU30MaxGidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1380 NAME 'mS-SQL-Status' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.13 NAME 'builtinCreationTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.277 NAME 'printMaxXExtent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.230 NAME 'printSeparatorFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1387 NAME 'mS-SQL-GPSHeight' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2054 NAME 'msImaging-PSPString' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.235 NAME 'printFormName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1621 NAME 'msDS-Other-Settings' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.304 NAME 'msSFU30SearchAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.21.9 NAME 'structuralObjectClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )", + "( 1.2.840.113556.1.4.659 NAME 'serviceDNSNameType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.902 NAME 'aCSMaxSizeOfRSVPAccountFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.569 NAME 'meetingLocation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.261 NAME 'division' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1640 NAME 'msWMI-NormalizedClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.300 NAME 'printerName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1960 NAME 'msDS-isRODC' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.268 NAME 'eFSPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1824 NAME 'msDS-AzMajorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2134 NAME 'msDNS-DSRecordAlgorithms' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.270 NAME 'printShareName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1400 NAME 'mS-SQL-Applications' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1312 NAME 'aCSServerList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1376 NAME 'mS-SQL-SPX' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.368 NAME 'rIDManagerReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1371 NAME 'mS-SQL-SortOrder' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.118 NAME 'otherPager' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1894 NAME 'msPKIAccountCredentials' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.6.13.3.16 NAME 'msDFSR-Flags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1301 NAME 'tokenGroups' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1626 NAME 'msWMI-CreationDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.14 NAME 'hasMasterNCs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.153 NAME 'rid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2084 NAME 'msSPP-ConfirmationId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.2 NAME 'msDFSR-Extension' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1846 NAME 'msDS-DefaultQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.35 NAME 'rangeUpper' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1633 NAME 'msWMI-Int8Max' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.48 NAME 'isDeleted' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1327 NAME 'pKIDefaultKeySpec' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1408 NAME 'mS-DS-ReplicatesNCReason' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.4.1816 NAME 'msDS-AzClassId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2088 NAME 'msSPP-IssuanceLicense' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1672 NAME 'msPKI-OID-CPS' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.590 NAME 'meetingBlob' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.72 NAME 'marshalledInterface' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1385 NAME 'mS-SQL-GPSLatitude' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2097 NAME 'msDS-ClaimPossibleValues' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.26 NAME 'msDFSR-DeletedPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1826 NAME 'msDS-RetiredReplNCSignatures' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2143 NAME 'msDNS-SigningKeyDescriptors' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.491 NAME 'fRSFaultCondition' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2278 NAME 'msDS-UserAllowedToAuthenticateFrom' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2017 NAME 'msDS-LockoutObservationWindow' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2130 NAME 'msDNS-IsSigned' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2057 NAME 'msDS-HostServiceAccountBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.683 NAME 'cRLPartitionedRevocationList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.481 NAME 'schemaUpdate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1332 NAME 'pKIOverlapPeriod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.692 NAME 'previousCACertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.573 NAME 'meetingApplication' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1849 NAME 'msDS-QuotaUsed' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.517 NAME 'ipsecPolicyReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1822 NAME 'msieee80211-DataType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.664 NAME 'syncWithObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2183 NAME 'msDS-GeoCoordinatesAltitude' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.284 NAME 'bytesPerMinute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.139 NAME 'profilePath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.40 NAME 'crossCertificatePair' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1929 NAME 'msDS-SecondaryKrbTgtNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2294 NAME 'msDS-ServiceAuthNPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1414 NAME 'dNSTombstoned' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.104 NAME 'ownerBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1930 NAME 'msDS-RevealedDSAs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2240 NAME 'msDS-IssuerCertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1692 NAME 'msFRS-Topology-Pref' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.158 NAME 'domainReplica' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.2 NAME 'whenCreated' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.76 NAME 'maxStorage' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.484 NAME 'fRSDirectoryFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1916 NAME 'msRADIUS-SavedFramedIpv6Prefix' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2087 NAME 'msSPP-ConfigLicense' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.627 NAME 'ipsecNFAReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.351 NAME 'auxiliaryClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )", + "( 1.2.840.113556.1.2.50 NAME 'linkID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1718 NAME 'msDS-AdditionalSamAccountName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.35 NAME 'msDFSR-OnDemandExclusionFileFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.577 NAME 'meetingOriginator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.169 NAME 'showInAdvancedViewOnly' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.582 NAME 'meetingAdvertiseScope' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.48 NAME 'buildingName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2181 NAME 'msImaging-HashAlgorithm' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2101 NAME 'msDS-ClaimSharesPossibleValuesWith' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.24 NAME 'contentIndexingAllowed' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.39 NAME 'msDFSR-CommonStagingSizeInMb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2135 NAME 'msDNS-RFC5011KeyRollovers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.682 NAME 'friendlyNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2071 NAME 'msTSEndpointType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2263 NAME 'msDS-RegisteredUsers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2062 NAME 'msDS-OptionalFeatureGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.767 NAME 'aCSMaxPeakBandwidth' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.919 NAME 'mSMQQuota' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.327 NAME 'packageFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.382 NAME 'dnsRecord' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.755 NAME 'domainIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.872 NAME 'fRSControlInboundBacklog' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.928 NAME 'mSMQOutRoutingServers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.768 NAME 'aCSEnableRSVPMessageLogging' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.585 NAME 'meetingIsEncrypted' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.34 NAME 'rangeLower' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1361 NAME 'mS-DS-ConsistencyChildCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2192 NAME 'msDS-EgressClaimsTransformationPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2292 NAME 'msDS-ComputerAuthNPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.843 NAME 'lDAPAdminLimits' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1847 NAME 'msDS-TombstoneQuotaFactor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1355 NAME 'queryFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.16 NAME 'postalAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.307 NAME 'options' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.74 NAME 'dSASignature' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.380 NAME 'dnsSecureSecondaries' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.634 NAME 'privilegeDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.598 NAME 'dmdName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1399 NAME 'mS-SQL-LastDiagnosticDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2280 NAME 'msDS-ComputerAllowedToAuthenticateTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.350 NAME 'addressType' SYNTAX '1.2.840.113556.1.4.905' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.38 NAME 'msDFSR-CommonStagingPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.672 NAME 'categories' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1675 NAME 'msPKI-RA-Application-Policies' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1244 NAME 'addressBookRoots' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.336 NAME 'volTableGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.65 NAME 'logonWorkstation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2153 NAME 'msAuthz-ResourceCondition' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.34 NAME 'msDFSR-DefaultCompressionExclusionFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.756 NAME 'aCSTimeOfDay' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2276 NAME 'msDS-SyncServerUrl' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.710 NAME 'superScopes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )", + "( 1.2.840.113556.1.2.210 NAME 'proxyAddresses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.348 NAME 'msSFU30NetgroupHostAtDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1306 NAME 'dNSProperty' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.141 NAME 'department' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.871 NAME 'fRSControlDataCreation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.253 NAME 'cOMOtherProgId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1337 NAME 'mSMQUserSid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.37 NAME 'cACertificate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.698 NAME 'dhcpUniqueKey' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1980 NAME 'msTSRemoteControl' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.9 NAME 'host' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2081 NAME 'msSPP-CSVLKSkuId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.483 NAME 'fRSFileFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2168 NAME 'msDS-IsPrimaryComputerFor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.74 NAME 'maxPwdAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1374 NAME 'mS-SQL-NamedPipe' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1972 NAME 'msDS-FailedInteractiveLogonCount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1649 NAME 'msWMI-TargetType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.668 NAME 'domainCAs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.2021 NAME 'msDS-PSOApplied' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.25 NAME 'countryCode' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.160 NAME 'lmPwdHistory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.275 NAME 'printKeepPrintedJobs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2014 NAME 'msDS-PasswordHistoryLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1836 NAME 'msDS-hasMasterNCs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1813 NAME 'msDS-OperationsForAzRoleBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.212 NAME 'dSHeuristics' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.877 NAME 'fRSPartnerAuthLevel' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.13 NAME 'displayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.269 NAME 'linkTrackSecret' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1239 NAME 'mSMQDependentClientService' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.238 NAME 'printMaxResolutionSupported' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.325 NAME 'perMsgDialogDisplayTable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.819 NAME 'bridgeheadTransportList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.540 NAME 'initialAuthOutgoing' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.523 NAME 'proxyGenerationEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.760 NAME 'aCSAggregateTokenRatePerUser' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.381 NAME 'dnsNotifySecondaries' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 2.5.4.21 NAME 'telexNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.117 NAME 'rpcNsPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.6.18.1.300 NAME 'msSFU30SearchContainer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.960 NAME 'mSMQNt4Stub' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.4.844 NAME 'lDAPIPDenyList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.918 NAME 'mSMQJournal' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.343 NAME 'msSFU30MaxUidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1442 NAME 'msDS-Cached-Membership-Time-Stamp' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1458 NAME 'msDS-Auxiliary-Classes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.821 NAME 'siteList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1782 NAME 'msDS-KeyVersionNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 2.5.4.50 NAME 'uniqueMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1797 NAME 'msDS-AzScriptTimeout' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1812 NAME 'msDS-OperationsForAzRole' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.809 NAME 'remoteStorageGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.231 NAME 'priority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.37 NAME 'msDFSR-Options2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2083 NAME 'msSPP-InstallationId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.58 NAME 'attributeCertificateAttribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.6.18.1.302 NAME 'msSFU30FieldSeparator' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.532 NAME 'superiorDNSRoot' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.822 NAME 'siteLinkList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1366 NAME 'mS-SQL-Location' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.94 NAME 'ntPwdHistory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1 NAME 'name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1629 NAME 'msWMI-IntMax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.118 NAME 'rpcNsProfileEntry' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2049 NAME 'msDS-BridgeHeadServersUsed' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.4.1969 NAME 'samDomainUpdates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.889 NAME 'additionalTrustedServiceNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.77 NAME 'maxTicketAge' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1661 NAME 'msDS-NC-Replica-Locations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1783 NAME 'msDS-ExecuteScriptPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.49 NAME 'mAPIID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.9 NAME 'msDFSR-Enabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.250 NAME 'cOMUniqueLIBID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.18 NAME 'postOfficeBox' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2067 NAME 'msDS-LastKnownRDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1344 NAME 'dSUIAdminMaximum' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1153 NAME 'msRADIUSFramedIPAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1799 NAME 'msDS-AzScopeName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2013 NAME 'msDS-MinimumPasswordLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.114 NAME 'rpcNsGroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.146 NAME 'objectSid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.6 NAME 'msDFSR-StagingSizeInMb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.365 NAME 'operatingSystemServicePack' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.21.6 NAME 'objectClasses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1698 NAME 'msTAPI-uid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.256 NAME 'streetAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1191 NAME 'msRASSavedFramedRoute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1965 NAME 'msFVE-RecoveryGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2166 NAME 'msDS-GenerationId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1359 NAME 'otherWellKnownObjects' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.4.1940 NAME 'msDS-RevealedList' SYNTAX '1.2.840.113556.1.4.904' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2282 NAME 'msDS-ServiceAllowedToAuthenticateTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.379 NAME 'dnsAllowXFR' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.628 NAME 'ipsecNegotiationPolicyReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1976 NAME 'msTSProfilePath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2076 NAME 'msPKI-Enrollment-Servers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.53 NAME 'deltaRevocationList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.18 NAME 'otherTelephone' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2077 NAME 'msPKI-Site-Name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1316 NAME 'aCSMinimumLatency' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2157 NAME 'msDS-ClaimSource' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1970 NAME 'msDS-LastSuccessfulInteractiveLogonTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.280 NAME 'printMinYExtent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.415 NAME 'operatingSystemHotfix' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.306 NAME 'msSFU30MapFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.610 NAME 'classDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1381 NAME 'mS-SQL-LastUpdatedDate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1957 NAME 'msDS-AuthenticatedToAccountlist' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1825 NAME 'msDS-AzMinorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2198 NAME 'msDS-ManagedPasswordPreviousId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2068 NAME 'msDS-DeletedObjectLifetime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2095 NAME 'msDS-IsUsedAsResourceSecurityAttribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.786 NAME 'mailAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.373 NAME 'rIDUsedPool' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.19 NAME 'msDFSR-RdcEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.44 NAME 'homeDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.538 NAME 'prefixMap' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2034 NAME 'msDFS-LastModifiedv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2155 NAME 'msAuthz-MemberRulesInCentralAccessPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.947 NAME 'mSMQSignCertificates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.714 NAME 'dhcpOptions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2060 NAME 'msDS-LocalEffectiveRecycleTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.675 NAME 'catalogs' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.134 NAME 'trustPosixOffset' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1404 NAME 'mS-SQL-AllowImmediateUpdatingSubscription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2047 NAME 'globalAddressList2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.135 NAME 'cost' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1331 NAME 'pKIExpirationPeriod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.15 NAME 'businessCategory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.13.3.4 NAME 'msDFSR-RootSizeInMb' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.869 NAME 'frsComputerReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1893 NAME 'msPKIDPAPIMasterKeys' SYNTAX '1.2.840.113556.1.4.903' )", + "( 1.2.840.113556.1.4.1430 NAME 'msPKI-Enrollment-Flag' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.45 NAME 'homeDrive' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2085 NAME 'msSPP-OnlineLicense' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.196 NAME 'systemMayContain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.90 NAME 'unicodePwd' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.763 NAME 'aCSTotalNoOfFlows' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1806 NAME 'msDS-MembersForAzRole' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.873 NAME 'fRSControlOutboundBacklog' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.89 NAME 'nTGroupMembers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.815 NAME 'canUpgradeScript' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.96 NAME 'pwdLastSet' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.228 NAME 'portName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1821 NAME 'msieee80211-Data' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.720 NAME 'dhcpUpdateTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 2.5.4.33 NAME 'roleOccupant' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1818 NAME 'msDS-AzTaskIsRoleDefinition' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.488 NAME 'fRSStagingPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.25 NAME 'dc' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.502 NAME 'timeVolChange' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.303 NAME 'notificationList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.952 NAME 'mSMQMigrated' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2290 NAME 'msDS-UserAuthNPolicyBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.53 NAME 'lastSetTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.894 NAME 'gPCFileSysPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.22 NAME 'teletexTerminalIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.471 NAME 'schemaVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )", + "( 1.2.840.113556.1.2.91 NAME 'repsFrom' SYNTAX 'OctetString' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.5 NAME 'msDFSR-StagingPath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.781 NAME 'lastKnownParent' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 2.5.4.43 NAME 'initials' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.901 NAME 'aCSMaxNoOfAccountFiles' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1928 NAME 'msDS-RevealOnDemandGroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1689 NAME 'msDS-Non-Security-Group-Extra-Classes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.344 NAME 'groupsToIgnore' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.896 NAME 'uSNSource' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.964 NAME 'mSMQNt4Flags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2102 NAME 'msDS-ClaimSharesPossibleValuesWithBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.29 NAME 'presentationAddress' SYNTAX '1.3.6.1.4.1.1466.115.121.1.43' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2051 NAME 'msDS-OIDToGroupLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.369 NAME 'fSMORoleOwner' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1954 NAME 'ms-net-ieee-8023-GP-PolicyGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.648 NAME 'primaryTelexNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2283 NAME 'msDS-ServiceAllowedToAuthenticateFrom' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 2.5.4.12 NAME 'title' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.1 NAME 'uid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1247 NAME 'interSiteTopologyRenew' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1697 NAME 'msDS-Settings' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.247 NAME 'printAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2188 NAME 'msDS-ValueTypeReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2133 NAME 'msDNS-MaintainTrustAnchor' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.324 NAME 'msSFU30KeyValues' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.1378 NAME 'mS-SQL-AppleTalk' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1663 NAME 'msDS-Replication-Notify-First-DSA-Delay' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.121 NAME 'securityIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.748 NAME 'attributeDisplayNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.16.840.1.113730.3.1.35 NAME 'thumbnailPhoto' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2082 NAME 'msSPP-KMSIds' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.758 NAME 'aCSMaxTokenRatePerFlow' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.121 NAME 'uSNLastObjRem' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.875 NAME 'fRSMemberReference' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1349 NAME 'gPCUserExtensionNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.138 NAME 'userParameters' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.36 NAME 'userCertificate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.6.13.3.102 NAME 'msDFSR-MemberReferenceBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.131 NAME 'co' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.3 NAME 'cn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.936 NAME 'mSMQEncryptKey' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.226 NAME 'adminDescription' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.34 NAME 'seeAlso' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.444 NAME 'msExchAssistantName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.667 NAME 'syncWithSID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1998 NAME 'msFVE-VolumeGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2107 NAME 'msTPM-SrkPubThumbprint' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.81 NAME 'info' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1686 NAME 'msWMI-ScopeGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.151 NAME 'oEMInformation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.935 NAME 'mSMQOSType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.374 NAME 'rIDNextRID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2039 NAME 'msDFS-LinkPathv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.141 NAME 'versionNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.505 NAME 'oMTGuid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.88 NAME 'nextRid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2037 NAME 'msDFS-Propertiesv2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1994 NAME 'msTSLicenseVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.16.840.1.113730.3.140 NAME 'userSMIMECertificate' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1985 NAME 'msTSBrokenConnectionAction' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.281 NAME 'printStaplingSupported' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.17 NAME 'msDFSR-Options' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.485 NAME 'fRSUpdateTimeout' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1967 NAME 'msDS-NC-RO-Replica-Locations' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1819 NAME 'msDS-AzApplicationData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.347 NAME 'msSFU30PosixMemberOf' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1425 NAME 'msCOM-UserLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.6.13.3.24 NAME 'msDFSR-DfsLinkTarget' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.512 NAME 'siteObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.584 NAME 'meetingRating' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1794 NAME 'msDS-NonMembersBL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.776 NAME 'aCSDSBMPriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.520 NAME 'machinePasswordChangeInterval' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.669 NAME 'rIDSetReferences' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.941 NAME 'mSMQLongLived' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1241 NAME 'netbootMirrorDataFile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.305 NAME 'msSFU30ResultAttributes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2236 NAME 'msds-memberOfTransitive' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1427 NAME 'msCOM-DefaultPartitionLink' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.519 NAME 'lastBackupRestorationTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.337 NAME 'currMachineId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.32 NAME 'attributeSyntax' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.362 NAME 'siteGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.823 NAME 'certificateTemplates' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.352 NAME 'msSFU30CryptMethod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1946 NAME 'msDS-PhoneticDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.14 NAME 'searchGuide' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2270 NAME 'msDS-IsManaged' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.581 NAME 'meetingScope' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.673 NAME 'retiredReplDSASignatures' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.855 NAME 'netbootNewMachineNamingPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1245 NAME 'globalAddressList' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.2.227 NAME 'extensionName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.884 NAME 'msRRASAttribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.6.18.1.349 NAME 'msSFU30NetgroupUserAtDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 1.2.840.113556.1.4.680 NAME 'queryPoint' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.888 NAME 'iPSECNegotiationPolicyAction' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.29 NAME 'msDFSR-CachePolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.299 NAME 'printMediaSupported' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.503 NAME 'timeRefresh' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.11 NAME 'authenticationOptions' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.198 NAME 'systemAuxiliaryClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.857 NAME 'netbootIntelliMirrorOSes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1406 NAME 'mS-SQL-AllowSnapshotFilesFTPDownloading' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1333 NAME 'pKIExtendedKeyUsage' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.2019 NAME 'msDS-LockoutThreshold' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1844 NAME 'msDS-QuotaTrustee' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.18.1.350 NAME 'msSFU30IsValidContainer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.359 NAME 'netbootGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1719 NAME 'msDS-DnsRootAlias' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.909 NAME 'extendedAttributeInfo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1248 NAME 'interSiteTopologyFailover' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2275 NAME 'msDS-CloudIsEnabled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.887 NAME 'iPSECNegotiationPolicyType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2059 NAME 'msDS-LocalEffectiveDeletionTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.24' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.587 NAME 'meetingStartTime' SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' )", + "( 2.5.4.17 NAME 'postalCode' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.445 NAME 'originalDisplayTable' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1990 NAME 'msTSInitialProgram' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.662 NAME 'lockoutTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.21 NAME 'secretary' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.95 NAME 'pwdHistoryLength' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.759 NAME 'aCSMaxPeakBandwidthPerFlow' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.753 NAME 'nameServiceFlags' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.694 NAME 'previousParentCA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.142 NAME 'winsockAddresses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.2075 NAME 'msTSSecondaryDesktops' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.2105 NAME 'msSPP-CSVLKPid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.49 NAME 'badPasswordTime' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2184 NAME 'msDS-GeoCoordinatesLatitude' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2079 NAME 'msDS-RequiredForestBehaviorVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1955 NAME 'ms-net-ieee-8023-GP-PolicyData' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.237 NAME 'printBinNames' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1382 NAME 'mS-SQL-InformationURL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.6.13.3.13 NAME 'msDFSR-DirectoryFilter' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.148 NAME 'schemaIDGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.2189 NAME 'msDS-TransformationRules' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.10 NAME 'o' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.504 NAME 'seqNotification' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 2.5.4.7 NAME 'l' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.57 NAME 'defaultLocalPolicyObject' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1801 NAME 'msDS-AzBizRule' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.948 NAME 'mSMQDigests' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.2.327 NAME 'helpFileName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.421 NAME 'domainWidePolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 2.5.4.6 NAME 'c' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2139 NAME 'msDNS-DNSKEYRecordSetTTL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.609 NAME 'sIDHistory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1711 NAME 'msDS-SDReferenceDomain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1367 NAME 'mS-SQL-Memory' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.715 NAME 'dhcpClasses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1305 NAME 'moveTreeState' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.757 NAME 'aCSDirection' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.631 NAME 'printPagesPerMinute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.145 NAME 'revision' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.646 NAME 'otherFacsimileTelephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 1.2.840.113556.1.4.1798 NAME 'msDS-AzApplicationName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.366 NAME 'rpcNsAnnotation' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2190 NAME 'msDS-TransformationRulesCompiled' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.4.1636 NAME 'msWMI-StringDefault' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.813 NAME 'upgradeProductCode' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", + "( 1.2.840.113556.1.4.1951 NAME 'ms-net-ieee-80211-GP-PolicyGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2098 NAME 'msDS-ClaimValueType' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.194 NAME 'adminDisplayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.879 NAME 'fRSServiceCommandStatus' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.361 NAME 'netbootMachineFilePath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.67 NAME 'lSAModifiedCount' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.920 NAME 'mSMQBasePriority' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2277 NAME 'msDS-UserAllowedToAuthenticateTo' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2056 NAME 'msDS-HostServiceAccount' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 1.2.840.113556.1.4.1943 NAME 'msDS-PhoneticLastName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.2055 NAME 'msDS-USNLastSyncSuccess' SYNTAX '1.2.840.113556.1.4.906' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.101 NAME 'privateKey' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 2.5.4.42 NAME 'givenName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.685 NAME 'parentCACertificateChain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.1924 NAME 'msDS-RevealedUsers' SYNTAX '1.2.840.113556.1.4.903' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.76 NAME 'objectVersion' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.856 NAME 'netbootNewMachineOU' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )" + ], + "cn": [ + "Aggregate" + ], + "dITContentRules": [ + "( 1.2.840.113556.1.6.13.4.6 NAME 'msDFSR-Content' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.14 NAME 'device' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MAY (uid $ manager $ ipHostNumber $ macAddress $ bootParameter $ bootFile ))", + "( 1.2.840.113556.1.5.205 NAME 'msWMI-IntRangeParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.5 NAME 'samServer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.196 NAME 'msPKI-Enterprise-Oid' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.7000.53 NAME 'crossRefContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.5 NAME 'organizationalUnit' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.152 NAME 'intellimirrorGroup' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.253 NAME 'msFVE-RecoveryInformation' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.262 NAME 'msImaging-PSPs' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.251 NAME 'ms-net-ieee-80211-GroupPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.138 NAME 'aCSSubnet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.43 NAME 'fTDfs' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.27 NAME 'rpcEntry')", + "( 1.2.840.113556.1.5.85 NAME 'dnsZone' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.4.2163 NAME 'msAuthz-CentralAccessRule' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.194 NAME 'msCOM-PartitionSet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.242 NAME 'msDS-QuotaContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.281 NAME 'msDS-ClaimsTransformationPolicies' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.146 NAME 'remoteStorageServicePoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.2 NAME 'samDomainBase')", + "( 1.2.840.113556.1.5.132 NAME 'dHCPClass' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.283 NAME 'msDS-CloudExtensions')", + "( 1.2.840.113556.1.5.89 NAME 'nTFRSSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.24 NAME 'remoteMailRecipient' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (cn ) MAY (telephoneNumber $ userCertificate $ info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ showInAddressBook $ userCert $ legacyExchangeDN $ msDS-PhoneticDisplayName $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ userSMIMECertificate $ textEncodedORAddress $ secretary $ labeledURI ))", + "( 1.2.840.113556.1.5.221 NAME 'msTAPI-RtConference' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.201 NAME 'msWMI-SimplePolicyTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.18.2.212 NAME 'msSFU30NetId' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.49 NAME 'packageRegistration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.139 NAME 'lostAndFound' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.14 NAME 'connectionPoint')", + "( 1.2.840.113556.1.5.6 NAME 'securityPrincipal')", + "( 1.2.840.113556.1.5.147 NAME 'siteLink' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.255 NAME 'msDS-PasswordSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.4.2162 NAME 'msAuthz-CentralAccessRules' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.30 NAME 'serviceInstance' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.156 NAME 'rRASAdministrationDictionary' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.4.2164 NAME 'msAuthz-CentralAccessPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ))", + "( 1.2.840.113556.1.5.52 NAME 'fileLinkTracking' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.18 NAME 'domainPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.18.2.216 NAME 'msSFU30NetworkUser' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject')", + "( 1.2.840.113556.1.5.177 NAME 'pKICertificateTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.293 NAME 'msDS-AuthNPolicies' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.2 NAME 'msDFSR-Subscriber' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.31 NAME 'site' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.222 NAME 'msTAPI-RtPerson' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.68 NAME 'applicationSiteSettings')", + "( 1.2.840.113556.1.3.14 NAME 'attributeSchema' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.267 NAME 'msSPP-ActivationObject' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.220 NAME 'msDS-App-Configuration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.23 NAME 'container' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.10 NAME 'msDFSR-Connection' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.207 NAME 'msWMI-UintRangeParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.23 NAME 'printQueue' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.260 NAME 'msDFS-DeletedLinkv2' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.140 NAME 'interSiteTransportContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.130 NAME 'indexServerCatalog' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.98 NAME 'ipsecPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.0 NAME 'top')", + "( 1.2.840.113556.1.5.36 NAME 'volume' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.236 NAME 'msDS-AzOperation' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.9 NAME 'groupOfNames' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.12 NAME 'configuration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.78 NAME 'licensingSiteSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.69 NAME 'nTDSSiteSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.269 NAME 'msDS-ClaimTypePropertyBase')", + "( 1.2.840.113556.1.5.273 NAME 'msDS-ResourceProperty' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.239 NAME 'msDS-AzRole' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.12 NAME 'bootableDevice')", + "( 1.2.840.113556.1.5.294 NAME 'msDS-AuthNPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.86 NAME 'dnsNode' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.210 NAME 'msWMI-StringSetParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.264 NAME 'msDS-ManagedServiceAccount' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipHostNumber ))", + "( 1.2.840.113556.1.5.15 NAME 'contact' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MAY (userCertificate $ info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ showInAddressBook $ userCert $ legacyExchangeDN $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ userSMIMECertificate $ textEncodedORAddress $ secretary $ labeledURI ))", + "( 1.3.6.1.1.1.2.0 NAME 'posixAccount')", + "( 1.2.840.113556.1.5.266 NAME 'msSPP-ActivationObjectsContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.217 NAME 'msWMI-ObjectEncoding' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.33 NAME 'storage' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.67 NAME 'domainDNS' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MAY (cACertificate $ builtinCreationTime $ builtinModifiedCount $ creationTime $ domainPolicyObject $ forceLogoff $ defaultLocalPolicyObject $ lockoutDuration $ lockOutObservationWindow $ lSACreationTime $ lSAModifiedCount $ lockoutThreshold $ maxPwdAge $ minPwdAge $ minPwdLength $ modifiedCountAtLastProm $ nETBIOSName $ nextRid $ pwdProperties $ pwdHistoryLength $ privateKey $ replicaSource $ objectSid $ oEMInformation $ serverState $ uASCompat $ serverRole $ domainReplica $ modifiedCount $ controlAccessRights $ auditingPolicy $ eFSPolicy $ desktopProfile $ nTMixedDomain $ rIDManagerReference $ treeName $ pekList $ pekKeyChangeInterval $ gPLink $ gPOptions $ ms-DS-MachineAccountQuota $ msDS-LogonTimeSyncInterval $ msDS-PerUserTrustQuota $ msDS-AllUsersTrustQuota $ msDS-PerUserTrustTombstonesQuota ))", + "( 1.2.840.113556.1.5.92 NAME 'linkTrackVolEntry' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.11 NAME 'ieee802Device')", + "( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject')", + "( 1.2.840.113556.1.5.235 NAME 'msDS-AzApplication' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.107 NAME 'sitesContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.263 NAME 'msImaging-PostScanProcess' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.240 NAME 'msieee80211-Policy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.95 NAME 'subnetContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.6 NAME 'document' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.6 NAME 'person' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.274 NAME 'msDS-ResourcePropertyList' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.270 NAME 'msDS-ClaimTypes' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.1 NAME 'shadowAccount')", + "( 1.2.840.113556.1.5.179 NAME 'mSMQMigratedUser' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.185 NAME 'mS-SQL-OLAPServer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.4.1.1466.101.119.2 NAME 'dynamicObject')", + "( 1.2.840.113556.1.5.155 NAME 'nTFRSSubscriber' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.129 NAME 'rIDSet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.58 NAME 'addressTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.154 NAME 'nTFRSSubscriptions' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.7000.47 NAME 'nTDSDSA' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.175 NAME 'infrastructureUpdate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.18.2.215 NAME 'msSFU30DomainInfo' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.213 NAME 'msWMI-Som' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.82 NAME 'rpcProfile' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.164 NAME 'mSMQSiteLink' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.184 NAME 'mS-SQL-SQLServer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.106 NAME 'queryPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.162 NAME 'mSMQConfiguration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.257 NAME 'msDFS-NamespaceAnchor' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.7 NAME 'msDFSR-ContentSet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.276 NAME 'msTPM-InformationObjectsContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.209 NAME 'msWMI-RealRangeParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.7 NAME 'organizationalPerson' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.176 NAME 'msExchConfigurationContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.278 NAME 'msKds-ProvRootKey' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.238 NAME 'msDS-AzTask' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.282 NAME 'msDS-GroupManagedServiceAccount' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipHostNumber ))", + "( 1.3.6.1.1.1.2.9 NAME 'nisMap' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.10 NAME 'nisObject' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.277 NAME 'msKds-ProvServerConfiguration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.18.2.217 NAME 'msSFU30NISMapConfig' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.7000.48 NAME 'serversContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.90 NAME 'linkTrackVolumeTable' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.188 NAME 'mS-SQL-SQLDatabase' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.211 NAME 'msWMI-PolicyType' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.183 NAME 'dSUISettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.157 NAME 'groupPolicyContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.3 NAME 'samDomain' MAY (forceLogoff $ objectSid $ oEMInformation $ serverState $ uASCompat $ serverRole $ domainReplica $ modifiedCount ))", + "( 1.2.840.113556.1.5.234 NAME 'msDS-AzAdminManager' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.214 NAME 'msWMI-Rule' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.254 NAME 'nTDSDSARO' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.286 NAME 'msDS-Device' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.34 NAME 'trustedDomain' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.7 NAME 'room' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.4 NAME 'organization' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.272 NAME 'msDS-ClaimType' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.3 NAME 'ipService' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.80 NAME 'rpcGroup' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.17 NAME 'server' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.28 NAME 'secret' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.163 NAME 'mSMQEnterpriseSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.202 NAME 'msWMI-MergeablePolicyTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.195 NAME 'msPKI-Key-Recovery-Agent' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ))", + "( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.258 NAME 'msDFS-Namespacev2' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.96 NAME 'subnet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.216 NAME 'applicationVersion' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.10 NAME 'residentialPerson' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.19 NAME 'cRLDistributionPoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.137 NAME 'aCSPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.77 NAME 'controlAccessRight' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.219 NAME 'msMQ-Group' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.8 NAME 'group' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (cn $ objectSid $ sAMAccountName ) MAY (telephoneNumber $ userPassword $ userCertificate $ info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-PhoneticDisplayName $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ userSMIMECertificate $ textEncodedORAddress $ secretary $ labeledURI $ gidNumber $ memberUid ))", + "( 1.2.840.113556.1.6.23.2 NAME 'msPrint-ConnectionPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.11 NAME 'crossRef' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.9 NAME 'msDFSR-Member' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.59 NAME 'displayTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.13 NAME 'classSchema' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.200 NAME 'msWMI-PolicyTemplate' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.165 NAME 'mSMQSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.5 NAME 'oncRpc' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.126 NAME 'serviceConnectionPoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.4 NAME 'builtinDomain' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MAY (creationTime $ forceLogoff $ lockoutDuration $ lockOutObservationWindow $ lockoutThreshold $ maxPwdAge $ minPwdAge $ minPwdLength $ modifiedCountAtLastProm $ nextRid $ pwdProperties $ pwdHistoryLength $ objectSid $ oEMInformation $ serverState $ uASCompat $ serverRole $ domainReplica $ modifiedCount ))", + "( 1.2.840.113556.1.5.241 NAME 'msDS-AppData' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.73 NAME 'rpcServerElement' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.150 NAME 'rRASAdministrationConnectionPoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.191 NAME 'aCSResourceLimits' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.3 NAME 'locality' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.6 NAME 'ipHost')", + "( 1.2.840.113556.1.5.275 NAME 'msTPM-InformationObject' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.289 NAME 'msDS-DeviceContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.4.2129 NAME 'msDNS-ServerSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.76 NAME 'foreignSecurityPrincipal' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.44 NAME 'classStore' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.5 NAME 'account' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.26 NAME 'rpcProfileElement' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.215 NAME 'msWMI-WMIGPO' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.243 NAME 'msDS-QuotaControl' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.256 NAME 'msDS-PasswordSettingsContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.187 NAME 'mS-SQL-SQLPublication' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.9 NAME 'user' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ))", + "( 1.2.840.113556.1.5.259 NAME 'msDFS-Linkv2' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.141 NAME 'interSiteTransport' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.4 NAME 'msDFSR-GlobalSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.29 NAME 'serviceClass' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.189 NAME 'mS-SQL-OLAPDatabase' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.16 NAME 'certificationAuthority' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.104 NAME 'meeting' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.287 NAME 'msDS-DeviceRegistrationServiceContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.71 NAME 'nTDSConnection' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.291 NAME 'msDS-AuthNPolicySilos' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.218 NAME 'msMQ-Custom-Recipient' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.72 NAME 'nTDSService' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.9 NAME 'dMD' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.280 NAME 'msDS-ClaimsTransformationPolicyType' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.14 NAME 'rFC822LocalPart' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.190 NAME 'mS-SQL-OLAPCube' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.208 NAME 'msWMI-UintSetParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.3.6.1.1.1.2.2 NAME 'posixGroup')", + "( 2.5.6.17 NAME 'groupOfUniqueNames' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.252 NAME 'ms-net-ieee-8023-GroupPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.119 NAME 'ipsecNegotiationPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.292 NAME 'msDS-AuthNPolicySilo' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.121 NAME 'ipsecNFA' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.42 NAME 'dfsConfiguration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.271 NAME 'msDS-ResourceProperties' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.91 NAME 'linkTrackObjectMoveTable' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.136 NAME 'rpcContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.83 NAME 'rIDManager' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.206 NAME 'msWMI-IntSetParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.5 NAME 'msDFSR-ReplicationGroup' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.125 NAME 'addressBookContainer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.7000.49 NAME 'applicationSettings')", + "( 1.2.840.113556.1.5.265 NAME 'msDS-OptionalFeature' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.94 NAME 'serviceAdministrationPoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.102 NAME 'nTFRSReplicaSet' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.203 NAME 'msWMI-RangeParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.7000.56 NAME 'ipsecBase')", + "( 1.2.840.113556.1.6.13.4.3 NAME 'msDFSR-Subscription' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.223 NAME 'msPKI-PrivateKeyRecoveryAgent' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.178 NAME 'pKIEnrollmentService' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.18.2.211 NAME 'msSFU30MailAliases' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.53 NAME 'typeLibrary' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.8 NAME 'msDFSR-Topology' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.237 NAME 'msDS-AzScope' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.74 NAME 'categoryRegistration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.11 NAME 'comConnectionPoint' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.93 NAME 'linkTrackOMTEntry' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.10 NAME 'classRegistration' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.148 NAME 'siteLinkBridge' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.81 NAME 'rpcServer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.46 NAME 'mailRecipient')", + "( 1.2.840.113556.1.5.1 NAME 'securityObject')", + "( 1.2.840.113556.1.5.20 NAME 'leaf')", + "( 1.2.840.113556.1.5.151 NAME 'intellimirrorSCP' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.6.13.4.1 NAME 'msDFSR-LocalSettings' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.186 NAME 'mS-SQL-SQLRepository' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.8 NAME 'organizationalRole' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.20.1 NAME 'subSchema' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.284 NAME 'msDS-DeviceRegistrationService' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.84 NAME 'displaySpecifier' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.212 NAME 'msWMI-ShadowObject' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.59 NAME 'fileLinkTrackingEntry' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.4.2161 NAME 'msAuthz-CentralAccessPolicies' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.161 NAME 'mSMQQueue' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.193 NAME 'msCOM-Partition' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.118 NAME 'ipsecFilter' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.2 NAME 'country' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.97 NAME 'physicalLocation' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.3.30 NAME 'computer' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ) MUST (objectSid $ sAMAccountName ) MAY (info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ showInAddressBook $ userCert $ legacyExchangeDN $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber $ unixUserPassword $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 $ textEncodedORAddress $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ ipHostNumber ))", + "( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.153 NAME 'nTFRSMember' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.12 NAME 'applicationEntity' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 2.5.6.11 NAME 'applicationProcess' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.279 NAME 'msDS-ValueType' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.204 NAME 'msWMI-UnknownRangeParam' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.66 NAME 'domain')", + "( 2.5.6.13 NAME 'dSA' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))", + "( 1.2.840.113556.1.5.120 NAME 'ipsecISAKMPPolicy' AUX ( mailRecipient $ posixGroup $ ipHost $ samDomain $ dynamicObject $ shadowAccount $ domainRelatedObject $ ieee802Device $ posixAccount $ bootableDevice $ simpleSecurityObject $ securityPrincipal $ msDS-CloudExtensions $ samDomainBase ))" + ], + "dSCorePropagationData": [ + "16010101000000.0Z" + ], + "distinguishedName": [ + "CN=Aggregate,CN=Schema,CN=Configuration,DC=FOREST,DC=LAB" + ], + "instanceType": [ + "4" + ], + "modifyTimeStamp": [ + "20141006121949.0Z" + ], + "name": [ + "Aggregate" + ], + "objectCategory": [ + "CN=SubSchema,CN=Schema,CN=Configuration,DC=FOREST,DC=LAB" + ], + "objectClass": [ + "top", + "subSchema" + ], + "objectClasses": [ + "( 1.2.840.113556.1.6.13.4.6 NAME 'msDFSR-Content' SUP top STRUCTURAL MAY (msDFSR-Extension $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 ) )", + "( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST (cn ) MAY (serialNumber $ l $ o $ ou $ owner $ seeAlso $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.2.840.113556.1.5.205 NAME 'msWMI-IntRangeParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-IntDefault ) MAY (msWMI-IntMax $ msWMI-IntMin ) )", + "( 1.2.840.113556.1.5.5 NAME 'samServer' SUP securityObject STRUCTURAL MAY (samDomainUpdates ) )", + "( 1.2.840.113556.1.5.196 NAME 'msPKI-Enterprise-Oid' SUP top STRUCTURAL MAY (msPKI-Cert-Template-OID $ msPKI-OID-Attribute $ msPKI-OID-CPS $ msPKI-OID-User-Notice $ msPKI-OIDLocalizedName $ msDS-OIDToGroupLink ) )", + "( 1.2.840.113556.1.5.7000.53 NAME 'crossRefContainer' SUP top STRUCTURAL MAY (uPNSuffixes $ msDS-Behavior-Version $ msDS-SPNSuffixes $ msDS-UpdateScript $ msDS-ExecuteScriptPassword $ msDS-EnabledFeature ) )", + "( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL MUST (cn $ ipNetworkNumber ) MAY (l $ description $ uid $ manager $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ ipNetmaskNumber $ nisMapName ) )", + "( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST (ou ) MAY (c $ l $ st $ street $ searchGuide $ businessCategory $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ seeAlso $ userPassword $ co $ countryCode $ desktopProfile $ defaultGroup $ managedBy $ uPNSuffixes $ gPLink $ gPOptions $ msCOM-UserPartitionSetLink $ thumbnailLogo ) )", + "( 1.2.840.113556.1.5.152 NAME 'intellimirrorGroup' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.253 NAME 'msFVE-RecoveryInformation' SUP top STRUCTURAL MUST (msFVE-RecoveryPassword $ msFVE-RecoveryGuid ) MAY (msFVE-VolumeGuid $ msFVE-KeyPackage ) )", + "( 1.2.840.113556.1.5.262 NAME 'msImaging-PSPs' SUP container STRUCTURAL )", + "( 1.2.840.113556.1.5.251 NAME 'ms-net-ieee-80211-GroupPolicy' SUP top STRUCTURAL MAY (ms-net-ieee-80211-GP-PolicyGUID $ ms-net-ieee-80211-GP-PolicyData $ ms-net-ieee-80211-GP-PolicyReserved ) )", + "( 1.2.840.113556.1.5.138 NAME 'aCSSubnet' SUP top STRUCTURAL MAY (aCSMaxTokenRatePerFlow $ aCSMaxPeakBandwidthPerFlow $ aCSMaxDurationPerFlow $ aCSAllocableRSVPBandwidth $ aCSMaxPeakBandwidth $ aCSEnableRSVPMessageLogging $ aCSEventLogLevel $ aCSEnableACSService $ aCSRSVPLogFilesLocation $ aCSMaxNoOfLogFiles $ aCSMaxSizeOfRSVPLogFile $ aCSDSBMPriority $ aCSDSBMRefresh $ aCSDSBMDeadTime $ aCSCacheTimeout $ aCSNonReservedTxLimit $ aCSNonReservedTxSize $ aCSEnableRSVPAccounting $ aCSRSVPAccountFilesLocation $ aCSMaxNoOfAccountFiles $ aCSMaxSizeOfRSVPAccountFile $ aCSServerList $ aCSNonReservedPeakRate $ aCSNonReservedTokenSize $ aCSNonReservedMaxSDUSize $ aCSNonReservedMinPolicedSize ) )", + "( 1.2.840.113556.1.5.43 NAME 'fTDfs' SUP top STRUCTURAL MUST (remoteServerName $ pKTGuid $ pKT ) MAY (keywords $ uNCName $ managedBy ) )", + "( 1.2.840.113556.1.5.27 NAME 'rpcEntry' SUP connectionPoint ABSTRACT )", + "( 1.2.840.113556.1.5.85 NAME 'dnsZone' SUP top STRUCTURAL MUST (dc ) MAY (dnsAllowDynamic $ dnsAllowXFR $ dnsSecureSecondaries $ dnsNotifySecondaries $ managedBy $ dNSProperty $ msDNS-IsSigned $ msDNS-SignWithNSEC3 $ msDNS-NSEC3OptOut $ msDNS-MaintainTrustAnchor $ msDNS-DSRecordAlgorithms $ msDNS-RFC5011KeyRollovers $ msDNS-NSEC3HashAlgorithm $ msDNS-NSEC3RandomSaltLength $ msDNS-NSEC3Iterations $ msDNS-DNSKEYRecordSetTTL $ msDNS-DSRecordSetTTL $ msDNS-SignatureInceptionOffset $ msDNS-SecureDelegationPollingPeriod $ msDNS-SigningKeyDescriptors $ msDNS-SigningKeys $ msDNS-DNSKEYRecords $ msDNS-ParentHasSecureDelegation $ msDNS-PropagationTime $ msDNS-NSEC3UserSalt $ msDNS-NSEC3CurrentSalt ) )", + "( 1.2.840.113556.1.4.2163 NAME 'msAuthz-CentralAccessRule' SUP top STRUCTURAL MAY (Enabled $ msAuthz-EffectiveSecurityPolicy $ msAuthz-ProposedSecurityPolicy $ msAuthz-LastEffectiveSecurityPolicy $ msAuthz-ResourceCondition $ msAuthz-MemberRulesInCentralAccessPolicyBL ) )", + "( 1.2.840.113556.1.5.194 NAME 'msCOM-PartitionSet' SUP top STRUCTURAL MAY (msCOM-PartitionLink $ msCOM-DefaultPartitionLink $ msCOM-ObjectId ) )", + "( 1.2.840.113556.1.5.242 NAME 'msDS-QuotaContainer' SUP top STRUCTURAL MUST (cn ) MAY (msDS-DefaultQuota $ msDS-TombstoneQuotaFactor $ msDS-QuotaEffective $ msDS-QuotaUsed $ msDS-TopQuotaUsage ) )", + "( 1.2.840.113556.1.5.281 NAME 'msDS-ClaimsTransformationPolicies' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.146 NAME 'remoteStorageServicePoint' SUP serviceAdministrationPoint STRUCTURAL MAY (remoteStorageGUID ) )", + "( 1.2.840.113556.1.5.2 NAME 'samDomainBase' SUP top AUXILIARY MAY (nTSecurityDescriptor $ creationTime $ forceLogoff $ lockoutDuration $ lockOutObservationWindow $ lockoutThreshold $ maxPwdAge $ minPwdAge $ minPwdLength $ modifiedCountAtLastProm $ nextRid $ pwdProperties $ pwdHistoryLength $ revision $ objectSid $ oEMInformation $ serverState $ uASCompat $ serverRole $ domainReplica $ modifiedCount ) )", + "( 1.2.840.113556.1.5.132 NAME 'dHCPClass' SUP top STRUCTURAL MUST (dhcpUniqueKey $ dhcpType $ dhcpFlags $ dhcpIdentification ) MAY (networkAddress $ dhcpObjName $ dhcpObjDescription $ dhcpServers $ dhcpSubnets $ dhcpMask $ dhcpRanges $ dhcpSites $ dhcpReservations $ superScopes $ superScopeDescription $ optionDescription $ optionsLocation $ dhcpOptions $ dhcpClasses $ mscopeId $ dhcpState $ dhcpProperties $ dhcpMaxKey $ dhcpUpdateTime ) )", + "( 1.2.840.113556.1.5.283 NAME 'msDS-CloudExtensions' SUP top AUXILIARY MAY (msDS-cloudExtensionAttribute1 $ msDS-cloudExtensionAttribute2 $ msDS-cloudExtensionAttribute3 $ msDS-cloudExtensionAttribute4 $ msDS-cloudExtensionAttribute5 $ msDS-cloudExtensionAttribute6 $ msDS-cloudExtensionAttribute7 $ msDS-cloudExtensionAttribute8 $ msDS-cloudExtensionAttribute9 $ msDS-cloudExtensionAttribute10 $ msDS-cloudExtensionAttribute11 $ msDS-cloudExtensionAttribute12 $ msDS-cloudExtensionAttribute13 $ msDS-cloudExtensionAttribute14 $ msDS-cloudExtensionAttribute15 $ msDS-cloudExtensionAttribute16 $ msDS-cloudExtensionAttribute17 $ msDS-cloudExtensionAttribute18 $ msDS-cloudExtensionAttribute19 $ msDS-cloudExtensionAttribute20 ) )", + "( 1.2.840.113556.1.5.89 NAME 'nTFRSSettings' SUP applicationSettings STRUCTURAL MAY (fRSExtensions $ managedBy ) )", + "( 1.2.840.113556.1.5.24 NAME 'remoteMailRecipient' SUP top STRUCTURAL MAY (remoteSource $ remoteSourceType $ managedBy ) )", + "( 1.2.840.113556.1.5.221 NAME 'msTAPI-RtConference' SUP top STRUCTURAL MUST (msTAPI-uid ) MAY (msTAPI-ProtocolId $ msTAPI-ConferenceBlob ) )", + "( 1.2.840.113556.1.5.201 NAME 'msWMI-SimplePolicyTemplate' SUP msWMI-PolicyTemplate STRUCTURAL MUST (msWMI-TargetObject ) )", + "( 1.2.840.113556.1.6.18.2.212 NAME 'msSFU30NetId' SUP top STRUCTURAL MAY (msSFU30Name $ msSFU30KeyValues $ msSFU30NisDomain $ nisMapName ) )", + "( 1.2.840.113556.1.5.49 NAME 'packageRegistration' SUP top STRUCTURAL MAY (msiScriptPath $ cOMClassID $ cOMInterfaceID $ cOMProgID $ localeID $ machineArchitecture $ iconPath $ cOMTypelibId $ vendor $ packageType $ setupCommand $ packageName $ packageFlags $ versionNumberHi $ versionNumberLo $ lastUpdateSequence $ managedBy $ msiFileList $ categories $ upgradeProductCode $ msiScript $ canUpgradeScript $ fileExtPriority $ productCode $ msiScriptName $ msiScriptSize $ installUiLevel ) )", + "( 1.2.840.113556.1.5.139 NAME 'lostAndFound' SUP top STRUCTURAL MAY (moveTreeState ) )", + "( 1.2.840.113556.1.5.14 NAME 'connectionPoint' SUP leaf ABSTRACT MUST (cn ) MAY (keywords $ managedBy $ msDS-Settings ) )", + "( 1.2.840.113556.1.5.6 NAME 'securityPrincipal' SUP top AUXILIARY MUST (objectSid $ sAMAccountName ) MAY (nTSecurityDescriptor $ securityIdentifier $ supplementalCredentials $ rid $ sAMAccountType $ sIDHistory $ altSecurityIdentities $ tokenGroups $ tokenGroupsNoGCAcceptable $ accountNameHistory $ tokenGroupsGlobalAndUniversal $ msDS-KeyVersionNumber ) )", + "( 1.2.840.113556.1.5.147 NAME 'siteLink' SUP top STRUCTURAL MUST (siteList ) MAY (cost $ schedule $ options $ replInterval ) )", + "( 1.2.840.113556.1.5.255 NAME 'msDS-PasswordSettings' SUP top STRUCTURAL MUST (msDS-MaximumPasswordAge $ msDS-MinimumPasswordAge $ msDS-MinimumPasswordLength $ msDS-PasswordHistoryLength $ msDS-PasswordComplexityEnabled $ msDS-PasswordReversibleEncryptionEnabled $ msDS-LockoutObservationWindow $ msDS-LockoutDuration $ msDS-LockoutThreshold $ msDS-PasswordSettingsPrecedence ) MAY (msDS-PSOAppliesTo ) )", + "( 1.2.840.113556.1.4.2162 NAME 'msAuthz-CentralAccessRules' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.30 NAME 'serviceInstance' SUP connectionPoint STRUCTURAL MUST (displayName $ serviceClassID ) MAY (winsockAddresses $ serviceInstanceVersion ) )", + "( 1.2.840.113556.1.5.156 NAME 'rRASAdministrationDictionary' SUP top STRUCTURAL MAY (msRRASVendorAttributeEntry ) )", + "( 1.2.840.113556.1.4.2164 NAME 'msAuthz-CentralAccessPolicy' SUP top STRUCTURAL MAY (msAuthz-CentralAccessPolicyID $ msAuthz-MemberRulesInCentralAccessPolicy ) )", + "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP user STRUCTURAL MAY (o $ businessCategory $ userCertificate $ givenName $ initials $ x500uniqueIdentifier $ displayName $ employeeNumber $ employeeType $ homePostalAddress $ userSMIMECertificate $ uid $ mail $ roomNumber $ photo $ manager $ homePhone $ secretary $ mobile $ pager $ audio $ jpegPhoto $ carLicense $ departmentNumber $ preferredLanguage $ userPKCS12 $ labeledURI ) )", + "( 1.2.840.113556.1.5.52 NAME 'fileLinkTracking' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.18 NAME 'domainPolicy' SUP leaf STRUCTURAL MAY (authenticationOptions $ forceLogoff $ defaultLocalPolicyObject $ lockoutDuration $ lockOutObservationWindow $ lockoutThreshold $ maxPwdAge $ maxRenewAge $ maxTicketAge $ minPwdAge $ minPwdLength $ minTicketAge $ pwdProperties $ pwdHistoryLength $ proxyLifetime $ eFSPolicy $ publicKeyPolicy $ domainWidePolicy $ domainPolicyReference $ qualityOfService $ ipsecPolicyReference $ managedBy $ domainCAs ) )", + "( 1.2.840.113556.1.6.18.2.216 NAME 'msSFU30NetworkUser' SUP top STRUCTURAL MAY (msSFU30Name $ msSFU30KeyValues $ msSFU30NisDomain $ nisMapName ) )", + "( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' SUP top AUXILIARY MAY (userPassword ) )", + "( 1.2.840.113556.1.5.177 NAME 'pKICertificateTemplate' SUP top STRUCTURAL MAY (displayName $ flags $ pKIDefaultKeySpec $ pKIKeyUsage $ pKIMaxIssuingDepth $ pKICriticalExtensions $ pKIExpirationPeriod $ pKIOverlapPeriod $ pKIExtendedKeyUsage $ pKIDefaultCSPs $ pKIEnrollmentAccess $ msPKI-RA-Signature $ msPKI-Enrollment-Flag $ msPKI-Private-Key-Flag $ msPKI-Certificate-Name-Flag $ msPKI-Minimal-Key-Size $ msPKI-Template-Schema-Version $ msPKI-Template-Minor-Revision $ msPKI-Cert-Template-OID $ msPKI-Supersede-Templates $ msPKI-RA-Policies $ msPKI-Certificate-Policy $ msPKI-Certificate-Application-Policy $ msPKI-RA-Application-Policies ) )", + "( 1.2.840.113556.1.5.293 NAME 'msDS-AuthNPolicies' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.6.13.4.2 NAME 'msDFSR-Subscriber' SUP top STRUCTURAL MUST (msDFSR-ReplicationGroupGuid $ msDFSR-MemberReference ) MAY (msDFSR-Extension $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.31 NAME 'site' SUP top STRUCTURAL MAY (location $ notificationList $ managedBy $ gPLink $ gPOptions $ mSMQSiteID $ mSMQNt4Stub $ mSMQSiteForeign $ mSMQInterval1 $ mSMQInterval2 $ msDS-BridgeHeadServersUsed ) )", + "( 1.2.840.113556.1.5.222 NAME 'msTAPI-RtPerson' SUP top STRUCTURAL MAY (msTAPI-uid $ msTAPI-IpAddress ) )", + "( 1.2.840.113556.1.5.68 NAME 'applicationSiteSettings' SUP top ABSTRACT MAY (applicationName $ notificationList ) )", + "( 1.2.840.113556.1.3.14 NAME 'attributeSchema' SUP top STRUCTURAL MUST (cn $ attributeID $ attributeSyntax $ isSingleValued $ oMSyntax $ lDAPDisplayName $ schemaIDGUID ) MAY (rangeLower $ rangeUpper $ mAPIID $ linkID $ oMObjectClass $ searchFlags $ extendedCharsAllowed $ schemaFlagsEx $ attributeSecurityGUID $ systemOnly $ classDisplayName $ isMemberOfPartialAttributeSet $ isDefunct $ isEphemeral $ msDs-Schema-Extensions $ msDS-IntId ) )", + "( 1.2.840.113556.1.5.267 NAME 'msSPP-ActivationObject' SUP top STRUCTURAL MUST (msSPP-CSVLKSkuId $ msSPP-KMSIds $ msSPP-CSVLKPid $ msSPP-CSVLKPartialProductKey ) MAY (msSPP-InstallationId $ msSPP-ConfirmationId $ msSPP-OnlineLicense $ msSPP-PhoneLicense $ msSPP-ConfigLicense $ msSPP-IssuanceLicense ) )", + "( 1.2.840.113556.1.5.220 NAME 'msDS-App-Configuration' SUP applicationSettings STRUCTURAL MAY (owner $ keywords $ managedBy $ msDS-ByteArray $ msDS-DateTime $ msDS-Integer $ msDS-ObjectReference ) )", + "( 1.2.840.113556.1.3.23 NAME 'container' SUP top STRUCTURAL MUST (cn ) MAY (schemaVersion $ defaultClassStore $ msDS-ObjectReference ) )", + "( 1.2.840.113556.1.6.13.4.10 NAME 'msDFSR-Connection' SUP top STRUCTURAL MUST (fromServer ) MAY (msDFSR-Extension $ msDFSR-Enabled $ msDFSR-Schedule $ msDFSR-Keywords $ msDFSR-Flags $ msDFSR-Options $ msDFSR-RdcEnabled $ msDFSR-RdcMinFileSizeInKb $ msDFSR-Priority $ msDFSR-DisablePacketPrivacy $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.207 NAME 'msWMI-UintRangeParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-IntDefault ) MAY (msWMI-IntMax $ msWMI-IntMin ) )", + "( 1.2.840.113556.1.5.23 NAME 'printQueue' SUP connectionPoint STRUCTURAL MUST (uNCName $ versionNumber $ serverName $ printerName $ shortServerName ) MAY (location $ portName $ driverName $ printSeparatorFile $ priority $ defaultPriority $ printStartTime $ printEndTime $ printFormName $ printBinNames $ printMaxResolutionSupported $ printOrientationsSupported $ printMaxCopies $ printCollate $ printColor $ printLanguage $ printAttributes $ printShareName $ printOwner $ printNotify $ printStatus $ printSpooling $ printKeepPrintedJobs $ driverVersion $ printMaxXExtent $ printMaxYExtent $ printMinXExtent $ printMinYExtent $ printStaplingSupported $ printMemory $ assetNumber $ bytesPerMinute $ printRate $ printRateUnit $ printNetworkAddress $ printMACAddress $ printMediaReady $ printNumberUp $ printMediaSupported $ operatingSystem $ operatingSystemVersion $ operatingSystemServicePack $ operatingSystemHotfix $ physicalLocationObject $ printPagesPerMinute $ printDuplexSupported ) )", + "( 1.2.840.113556.1.5.260 NAME 'msDFS-DeletedLinkv2' SUP top STRUCTURAL MUST (msDFS-NamespaceIdentityGUIDv2 $ msDFS-LastModifiedv2 $ msDFS-LinkPathv2 $ msDFS-LinkIdentityGUIDv2 ) MAY (msDFS-Commentv2 $ msDFS-ShortNameLinkPathv2 ) )", + "( 1.2.840.113556.1.5.140 NAME 'interSiteTransportContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.130 NAME 'indexServerCatalog' SUP connectionPoint STRUCTURAL MUST (creator ) MAY (uNCName $ queryPoint $ indexedScopes $ friendlyNames ) )", + "( 1.2.840.113556.1.5.98 NAME 'ipsecPolicy' SUP ipsecBase STRUCTURAL MAY (ipsecISAKMPReference $ ipsecNFAReference ) )", + "( 2.5.6.0 NAME 'top' ABSTRACT MUST (objectClass $ instanceType $ nTSecurityDescriptor $ objectCategory ) MAY (cn $ description $ distinguishedName $ whenCreated $ whenChanged $ subRefs $ displayName $ uSNCreated $ isDeleted $ dSASignature $ objectVersion $ repsTo $ repsFrom $ memberOf $ ownerBL $ uSNChanged $ uSNLastObjRem $ showInAdvancedViewOnly $ adminDisplayName $ proxyAddresses $ adminDescription $ extensionName $ uSNDSALastObjRemoved $ displayNamePrintable $ directReports $ wWWHomePage $ USNIntersite $ name $ objectGUID $ replPropertyMetaData $ replUpToDateVector $ flags $ revision $ wbemPath $ fSMORoleOwner $ systemFlags $ siteObjectBL $ serverReferenceBL $ nonSecurityMemberBL $ queryPolicyBL $ wellKnownObjects $ isPrivilegeHolder $ partialAttributeSet $ managedObjects $ partialAttributeDeletionList $ url $ lastKnownParent $ bridgeheadServerListBL $ netbootSCPBL $ isCriticalSystemObject $ frsComputerReferenceBL $ fRSMemberReferenceBL $ uSNSource $ fromEntry $ allowedChildClasses $ allowedChildClassesEffective $ allowedAttributes $ allowedAttributesEffective $ possibleInferiors $ canonicalName $ proxiedObjectName $ sDRightsEffective $ dSCorePropagationData $ otherWellKnownObjects $ mS-DS-ConsistencyGuid $ mS-DS-ConsistencyChildCount $ masteredBy $ msCOM-PartitionSetLink $ msCOM-UserLink $ msDS-Approx-Immed-Subordinates $ msDS-NCReplCursors $ msDS-NCReplInboundNeighbors $ msDS-NCReplOutboundNeighbors $ msDS-ReplAttributeMetaData $ msDS-ReplValueMetaData $ msDS-NonMembersBL $ msDS-MembersForAzRoleBL $ msDS-OperationsForAzTaskBL $ msDS-TasksForAzTaskBL $ msDS-OperationsForAzRoleBL $ msDS-TasksForAzRoleBL $ msDs-masteredBy $ msDS-ObjectReferenceBL $ msDS-PrincipalName $ msDS-RevealedDSAs $ msDS-KrbTgtLinkBl $ msDS-IsFullReplicaFor $ msDS-IsDomainFor $ msDS-IsPartialReplicaFor $ msDS-AuthenticatedToAccountlist $ msDS-NC-RO-Replica-Locations-BL $ msDS-RevealedListBL $ msDS-PSOApplied $ msDS-NcType $ msDS-OIDToGroupLinkBl $ msDS-HostServiceAccountBL $ isRecycled $ msDS-LocalEffectiveDeletionTime $ msDS-LocalEffectiveRecycleTime $ msDS-LastKnownRDN $ msDS-EnabledFeatureBL $ msDS-ClaimSharesPossibleValuesWithBL $ msDS-MembersOfResourcePropertyListBL $ msDS-IsPrimaryComputerFor $ msDS-ValueTypeReferenceBL $ msDS-TDOIngressBL $ msDS-TDOEgressBL $ msDS-parentdistname $ msDS-ReplValueMetaDataExt $ msds-memberOfTransitive $ msds-memberTransitive $ structuralObjectClass $ createTimeStamp $ modifyTimeStamp $ subSchemaSubEntry $ msSFU30PosixMemberOf $ msDFSR-MemberReferenceBL $ msDFSR-ComputerReferenceBL ) )", + "( 1.2.840.113556.1.5.36 NAME 'volume' SUP connectionPoint STRUCTURAL MUST (uNCName ) MAY (contentIndexingAllowed $ lastContentIndexed ) )", + "( 1.2.840.113556.1.5.236 NAME 'msDS-AzOperation' SUP top STRUCTURAL MUST (msDS-AzOperationID ) MAY (description $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST (cn $ member ) MAY (o $ ou $ businessCategory $ owner $ seeAlso ) )", + "( 1.2.840.113556.1.5.12 NAME 'configuration' SUP top STRUCTURAL MUST (cn ) MAY (gPLink $ gPOptions $ msDS-USNLastSyncSuccess ) )", + "( 1.2.840.113556.1.5.78 NAME 'licensingSiteSettings' SUP applicationSiteSettings STRUCTURAL MAY (siteServer ) )", + "( 1.2.840.113556.1.5.69 NAME 'nTDSSiteSettings' SUP applicationSiteSettings STRUCTURAL MAY (schedule $ options $ queryPolicyObject $ managedBy $ interSiteTopologyGenerator $ interSiteTopologyRenew $ interSiteTopologyFailover $ msDS-Preferred-GC-Site ) )", + "( 1.2.840.113556.1.5.269 NAME 'msDS-ClaimTypePropertyBase' SUP top ABSTRACT MAY (Enabled $ msDS-ClaimPossibleValues $ msDS-ClaimSharesPossibleValuesWith ) )", + "( 1.2.840.113556.1.5.273 NAME 'msDS-ResourceProperty' SUP msDS-ClaimTypePropertyBase STRUCTURAL MUST (msDS-ValueTypeReference ) MAY (msDS-IsUsedAsResourceSecurityAttribute $ msDS-AppliesToResourceTypes ) )", + "( 1.2.840.113556.1.5.239 NAME 'msDS-AzRole' SUP top STRUCTURAL MAY (description $ msDS-MembersForAzRole $ msDS-OperationsForAzRole $ msDS-TasksForAzRole $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY MAY (cn $ bootParameter $ bootFile ) )", + "( 1.2.840.113556.1.5.294 NAME 'msDS-AuthNPolicy' SUP top STRUCTURAL MAY (msDS-UserAllowedToAuthenticateTo $ msDS-UserAllowedToAuthenticateFrom $ msDS-UserTGTLifetime $ msDS-ComputerAllowedToAuthenticateTo $ msDS-ComputerTGTLifetime $ msDS-ServiceAllowedToAuthenticateTo $ msDS-ServiceAllowedToAuthenticateFrom $ msDS-ServiceTGTLifetime $ msDS-UserAuthNPolicyBL $ msDS-ComputerAuthNPolicyBL $ msDS-ServiceAuthNPolicyBL $ msDS-AssignedAuthNPolicyBL $ msDS-AuthNPolicyEnforced ) )", + "( 1.2.840.113556.1.5.86 NAME 'dnsNode' SUP top STRUCTURAL MUST (dc ) MAY (dnsRecord $ dNSProperty $ dNSTombstoned ) )", + "( 1.2.840.113556.1.5.210 NAME 'msWMI-StringSetParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-StringDefault ) MAY (msWMI-StringValidValues ) )", + "( 1.2.840.113556.1.5.264 NAME 'msDS-ManagedServiceAccount' SUP computer STRUCTURAL )", + "( 1.2.840.113556.1.5.15 NAME 'contact' SUP organizationalPerson STRUCTURAL MUST (cn ) MAY (notes $ msDS-SourceObjectDN ) )", + "( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY MAY (cn $ description $ userPassword $ homeDirectory $ unixUserPassword $ uid $ uidNumber $ gidNumber $ gecos $ unixHomeDirectory $ loginShell ) )", + "( 1.2.840.113556.1.5.266 NAME 'msSPP-ActivationObjectsContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.217 NAME 'msWMI-ObjectEncoding' SUP top STRUCTURAL MUST (msWMI-ID $ msWMI-TargetObject $ msWMI-Class $ msWMI-Genus $ msWMI-intFlags1 $ msWMI-intFlags2 $ msWMI-intFlags3 $ msWMI-intFlags4 $ msWMI-Parm1 $ msWMI-Parm2 $ msWMI-Parm3 $ msWMI-Parm4 $ msWMI-ScopeGuid ) )", + "( 1.2.840.113556.1.5.33 NAME 'storage' SUP connectionPoint STRUCTURAL MAY (moniker $ monikerDisplayName $ iconPath ) )", + "( 1.2.840.113556.1.5.67 NAME 'domainDNS' SUP domain STRUCTURAL MAY (managedBy $ msDS-Behavior-Version $ msDS-AllowedDNSSuffixes $ msDS-USNLastSyncSuccess $ msDS-EnabledFeature ) )", + "( 1.2.840.113556.1.5.92 NAME 'linkTrackVolEntry' SUP leaf STRUCTURAL MAY (linkTrackSecret $ volTableIdxGUID $ volTableGUID $ currMachineId $ timeVolChange $ timeRefresh $ seqNotification $ objectCount ) )", + "( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY MAY (cn $ macAddress ) )", + "( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' SUP top AUXILIARY MAY (associatedDomain ) )", + "( 1.2.840.113556.1.5.235 NAME 'msDS-AzApplication' SUP top STRUCTURAL MAY (description $ msDS-AzApplicationName $ msDS-AzGenerateAudits $ msDS-AzClassId $ msDS-AzApplicationVersion $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 1.2.840.113556.1.5.107 NAME 'sitesContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.263 NAME 'msImaging-PostScanProcess' SUP top STRUCTURAL MUST (displayName $ msImaging-PSPIdentifier ) MAY (serverName $ msImaging-PSPString ) )", + "( 1.2.840.113556.1.5.240 NAME 'msieee80211-Policy' SUP top STRUCTURAL MAY (msieee80211-Data $ msieee80211-DataType $ msieee80211-ID ) )", + "( 1.2.840.113556.1.5.95 NAME 'subnetContainer' SUP top STRUCTURAL )", + "( 0.9.2342.19200300.100.4.6 NAME 'document' SUP top STRUCTURAL MAY (cn $ l $ o $ ou $ description $ seeAlso $ documentIdentifier $ documentTitle $ documentVersion $ documentAuthor $ documentLocation $ documentPublisher ) )", + "( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST (cn ) MAY (sn $ serialNumber $ telephoneNumber $ seeAlso $ userPassword $ attributeCertificateAttribute ) )", + "( 1.2.840.113556.1.5.274 NAME 'msDS-ResourcePropertyList' SUP top STRUCTURAL MAY (msDS-MembersOfResourcePropertyList ) )", + "( 1.2.840.113556.1.5.270 NAME 'msDS-ClaimTypes' SUP top STRUCTURAL )", + "( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY MAY (description $ userPassword $ uid $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ) )", + "( 1.2.840.113556.1.5.179 NAME 'mSMQMigratedUser' SUP top STRUCTURAL MAY (objectSid $ mSMQSignCertificates $ mSMQDigests $ mSMQDigestsMig $ mSMQSignCertificatesMig $ mSMQUserSid ) )", + "( 1.2.840.113556.1.5.185 NAME 'mS-SQL-OLAPServer' SUP serviceConnectionPoint STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-RegisteredOwner $ mS-SQL-Contact $ mS-SQL-Build $ mS-SQL-ServiceAccount $ mS-SQL-Status $ mS-SQL-InformationURL $ mS-SQL-PublicationURL $ mS-SQL-Version $ mS-SQL-Language $ mS-SQL-Keywords ) )", + "( 1.3.6.1.4.1.1466.101.119.2 NAME 'dynamicObject' SUP top AUXILIARY MAY (msDS-Entry-Time-To-Die $ entryTTL ) )", + "( 1.2.840.113556.1.5.155 NAME 'nTFRSSubscriber' SUP top STRUCTURAL MUST (fRSRootPath $ fRSStagingPath ) MAY (schedule $ fRSUpdateTimeout $ fRSFaultCondition $ fRSServiceCommand $ fRSExtensions $ fRSFlags $ fRSMemberReference $ fRSServiceCommandStatus $ fRSTimeLastCommand $ fRSTimeLastConfigChange ) )", + "( 1.2.840.113556.1.5.129 NAME 'rIDSet' SUP top STRUCTURAL MUST (rIDAllocationPool $ rIDPreviousAllocationPool $ rIDUsedPool $ rIDNextRID ) )", + "( 1.2.840.113556.1.3.58 NAME 'addressTemplate' SUP displayTemplate STRUCTURAL MUST (displayName ) MAY (addressSyntax $ perMsgDialogDisplayTable $ perRecipDialogDisplayTable $ addressType $ proxyGenerationEnabled ) )", + "( 1.2.840.113556.1.5.154 NAME 'nTFRSSubscriptions' SUP top STRUCTURAL MAY (fRSWorkingPath $ fRSExtensions $ fRSVersion ) )", + "( 1.2.840.113556.1.5.7000.47 NAME 'nTDSDSA' SUP applicationSettings STRUCTURAL MAY (hasMasterNCs $ hasPartialReplicaNCs $ dMDLocation $ invocationId $ networkAddress $ options $ fRSRootPath $ serverReference $ lastBackupRestorationTime $ queryPolicyObject $ managedBy $ retiredReplDSASignatures $ msDS-Behavior-Version $ msDS-HasInstantiatedNCs $ msDS-ReplicationEpoch $ msDS-HasDomainNCs $ msDS-RetiredReplNCSignatures $ msDS-hasMasterNCs $ msDS-RevealedUsers $ msDS-hasFullReplicaNCs $ msDS-NeverRevealGroup $ msDS-RevealOnDemandGroup $ msDS-isGC $ msDS-isRODC $ msDS-SiteName $ msDS-IsUserCachableAtRodc $ msDS-EnabledFeature ) )", + "( 1.2.840.113556.1.5.175 NAME 'infrastructureUpdate' SUP top STRUCTURAL MAY (dNReferenceUpdate ) )", + "( 1.2.840.113556.1.6.18.2.215 NAME 'msSFU30DomainInfo' SUP top STRUCTURAL MAY (msSFU30SearchContainer $ msSFU30MasterServerName $ msSFU30OrderNumber $ msSFU30Domains $ msSFU30YpServers $ msSFU30MaxGidNumber $ msSFU30MaxUidNumber $ msSFU30IsValidContainer $ msSFU30CryptMethod ) )", + "( 1.2.840.113556.1.5.213 NAME 'msWMI-Som' SUP top STRUCTURAL MUST (msWMI-ID $ msWMI-Name ) MAY (msWMI-Author $ msWMI-ChangeDate $ msWMI-CreationDate $ msWMI-SourceOrganization $ msWMI-intFlags1 $ msWMI-intFlags2 $ msWMI-intFlags3 $ msWMI-intFlags4 $ msWMI-Parm1 $ msWMI-Parm2 $ msWMI-Parm3 $ msWMI-Parm4 ) )", + "( 1.2.840.113556.1.5.82 NAME 'rpcProfile' SUP rpcEntry STRUCTURAL )", + "( 1.2.840.113556.1.5.164 NAME 'mSMQSiteLink' SUP top STRUCTURAL MUST (mSMQSite1 $ mSMQSite2 $ mSMQCost ) MAY (mSMQSiteGates $ mSMQSiteGatesMig ) )", + "( 1.2.840.113556.1.5.184 NAME 'mS-SQL-SQLServer' SUP serviceConnectionPoint STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-RegisteredOwner $ mS-SQL-Contact $ mS-SQL-Location $ mS-SQL-Memory $ mS-SQL-Build $ mS-SQL-ServiceAccount $ mS-SQL-CharacterSet $ mS-SQL-SortOrder $ mS-SQL-UnicodeSortOrder $ mS-SQL-Clustered $ mS-SQL-NamedPipe $ mS-SQL-MultiProtocol $ mS-SQL-SPX $ mS-SQL-TCPIP $ mS-SQL-AppleTalk $ mS-SQL-Vines $ mS-SQL-Status $ mS-SQL-LastUpdatedDate $ mS-SQL-InformationURL $ mS-SQL-GPSLatitude $ mS-SQL-GPSLongitude $ mS-SQL-GPSHeight $ mS-SQL-Keywords ) )", + "( 1.2.840.113556.1.5.106 NAME 'queryPolicy' SUP top STRUCTURAL MAY (lDAPAdminLimits $ lDAPIPDenyList ) )", + "( 1.2.840.113556.1.5.162 NAME 'mSMQConfiguration' SUP top STRUCTURAL MAY (mSMQQuota $ mSMQJournalQuota $ mSMQOwnerID $ mSMQSites $ mSMQOutRoutingServers $ mSMQInRoutingServers $ mSMQServiceType $ mSMQComputerType $ mSMQForeign $ mSMQOSType $ mSMQEncryptKey $ mSMQSignKey $ mSMQDependentClientServices $ mSMQRoutingServices $ mSMQDsServices $ mSMQComputerTypeEx ) )", + "( 1.2.840.113556.1.5.257 NAME 'msDFS-NamespaceAnchor' SUP top STRUCTURAL MUST (msDFS-SchemaMajorVersion ) )", + "( 1.2.840.113556.1.6.13.4.7 NAME 'msDFSR-ContentSet' SUP top STRUCTURAL MAY (description $ msDFSR-Extension $ msDFSR-RootSizeInMb $ msDFSR-StagingSizeInMb $ msDFSR-ConflictSizeInMb $ msDFSR-FileFilter $ msDFSR-DirectoryFilter $ msDFSR-Flags $ msDFSR-Options $ msDFSR-DfsPath $ msDFSR-Priority $ msDFSR-DeletedSizeInMb $ msDFSR-DefaultCompressionExclusionFilter $ msDFSR-OnDemandExclusionFileFilter $ msDFSR-OnDemandExclusionDirectoryFilter $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.276 NAME 'msTPM-InformationObjectsContainer' SUP top STRUCTURAL MUST (cn ) )", + "( 1.2.840.113556.1.5.209 NAME 'msWMI-RealRangeParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-Int8Default ) MAY (msWMI-Int8Max $ msWMI-Int8Min ) )", + "( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL MAY (c $ l $ st $ street $ o $ ou $ title $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ givenName $ initials $ generationQualifier $ houseIdentifier $ otherTelephone $ otherPager $ co $ department $ company $ streetAddress $ otherHomePhone $ msExchHouseIdentifier $ personalTitle $ homePostalAddress $ countryCode $ employeeID $ comment $ division $ otherFacsimileTelephoneNumber $ otherMobile $ primaryTelexNumber $ primaryInternationalISDNNumber $ mhsORAddress $ otherMailbox $ assistant $ ipPhone $ otherIpPhone $ msDS-AllowedToDelegateTo $ msDS-PhoneticFirstName $ msDS-PhoneticLastName $ msDS-PhoneticDepartment $ msDS-PhoneticCompanyName $ msDS-PhoneticDisplayName $ msDS-HABSeniorityIndex $ msDS-AllowedToActOnBehalfOfOtherIdentity $ mail $ manager $ homePhone $ mobile $ pager $ middleName $ thumbnailPhoto $ thumbnailLogo ) )", + "( 1.2.840.113556.1.5.176 NAME 'msExchConfigurationContainer' SUP container STRUCTURAL MAY (addressBookRoots $ globalAddressList $ templateRoots $ addressBookRoots2 $ globalAddressList2 $ templateRoots2 ) )", + "( 1.2.840.113556.1.5.278 NAME 'msKds-ProvRootKey' SUP top STRUCTURAL MUST (cn $ msKds-KDFAlgorithmID $ msKds-SecretAgreementAlgorithmID $ msKds-PublicKeyLength $ msKds-PrivateKeyLength $ msKds-RootKeyData $ msKds-Version $ msKds-DomainID $ msKds-UseStartTime $ msKds-CreateTime ) MAY (msKds-KDFParam $ msKds-SecretAgreementParam ) )", + "( 1.2.840.113556.1.5.238 NAME 'msDS-AzTask' SUP top STRUCTURAL MAY (description $ msDS-AzBizRule $ msDS-AzBizRuleLanguage $ msDS-AzLastImportedBizRulePath $ msDS-OperationsForAzTask $ msDS-TasksForAzTask $ msDS-AzTaskIsRoleDefinition $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 1.2.840.113556.1.5.282 NAME 'msDS-GroupManagedServiceAccount' SUP computer STRUCTURAL MUST (msDS-ManagedPasswordInterval ) MAY (msDS-ManagedPassword $ msDS-ManagedPasswordId $ msDS-ManagedPasswordPreviousId $ msDS-GroupMSAMembership ) )", + "( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL MUST (cn $ nisMapName ) MAY (description ) )", + "( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL MUST (cn $ nisMapName $ nisMapEntry ) MAY (description $ msSFU30Name $ msSFU30NisDomain ) )", + "( 1.2.840.113556.1.5.277 NAME 'msKds-ProvServerConfiguration' SUP top STRUCTURAL MUST (msKds-Version ) MAY (msKds-KDFAlgorithmID $ msKds-KDFParam $ msKds-SecretAgreementAlgorithmID $ msKds-SecretAgreementParam $ msKds-PublicKeyLength $ msKds-PrivateKeyLength ) )", + "( 1.2.840.113556.1.6.18.2.217 NAME 'msSFU30NISMapConfig' SUP top STRUCTURAL MAY (msSFU30KeyAttributes $ msSFU30FieldSeparator $ msSFU30IntraFieldSeparator $ msSFU30SearchAttributes $ msSFU30ResultAttributes $ msSFU30MapFilter $ msSFU30NSMAPFieldPosition ) )", + "( 1.2.840.113556.1.5.7000.48 NAME 'serversContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.90 NAME 'linkTrackVolumeTable' SUP fileLinkTracking STRUCTURAL )", + "( 1.2.840.113556.1.5.188 NAME 'mS-SQL-SQLDatabase' SUP top STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $ mS-SQL-InformationURL $ mS-SQL-Description $ mS-SQL-Alias $ mS-SQL-Size $ mS-SQL-CreationDate $ mS-SQL-LastBackupDate $ mS-SQL-LastDiagnosticDate $ mS-SQL-Applications $ mS-SQL-Keywords ) )", + "( 1.2.840.113556.1.5.211 NAME 'msWMI-PolicyType' SUP top STRUCTURAL MUST (msWMI-ID $ msWMI-TargetObject ) MAY (msWMI-Author $ msWMI-ChangeDate $ msWMI-CreationDate $ msWMI-SourceOrganization $ msWMI-intFlags1 $ msWMI-intFlags2 $ msWMI-intFlags3 $ msWMI-intFlags4 $ msWMI-Parm1 $ msWMI-Parm2 $ msWMI-Parm3 $ msWMI-Parm4 ) )", + "( 1.2.840.113556.1.5.183 NAME 'dSUISettings' SUP top STRUCTURAL MAY (dSUIAdminNotification $ dSUIAdminMaximum $ dSUIShellMaximum $ msDS-Security-Group-Extra-Classes $ msDS-Non-Security-Group-Extra-Classes $ msDS-FilterContainers ) )", + "( 1.2.840.113556.1.5.157 NAME 'groupPolicyContainer' SUP container STRUCTURAL MAY (flags $ versionNumber $ gPCFunctionalityVersion $ gPCFileSysPath $ gPCMachineExtensionNames $ gPCUserExtensionNames $ gPCWQLFilter ) )", + "( 1.2.840.113556.1.5.3 NAME 'samDomain' SUP top AUXILIARY MAY (description $ cACertificate $ builtinCreationTime $ builtinModifiedCount $ creationTime $ domainPolicyObject $ defaultLocalPolicyObject $ lockoutDuration $ lockOutObservationWindow $ lSACreationTime $ lSAModifiedCount $ lockoutThreshold $ maxPwdAge $ minPwdAge $ minPwdLength $ modifiedCountAtLastProm $ nETBIOSName $ nextRid $ pwdProperties $ pwdHistoryLength $ privateKey $ replicaSource $ controlAccessRights $ auditingPolicy $ eFSPolicy $ desktopProfile $ nTMixedDomain $ rIDManagerReference $ treeName $ pekList $ pekKeyChangeInterval $ gPLink $ gPOptions $ ms-DS-MachineAccountQuota $ msDS-LogonTimeSyncInterval $ msDS-PerUserTrustQuota $ msDS-AllUsersTrustQuota $ msDS-PerUserTrustTombstonesQuota ) )", + "( 1.2.840.113556.1.5.234 NAME 'msDS-AzAdminManager' SUP top STRUCTURAL MAY (description $ msDS-AzDomainTimeout $ msDS-AzScriptEngineCacheMax $ msDS-AzScriptTimeout $ msDS-AzGenerateAudits $ msDS-AzApplicationData $ msDS-AzMajorVersion $ msDS-AzMinorVersion $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 1.2.840.113556.1.5.214 NAME 'msWMI-Rule' SUP top STRUCTURAL MUST (msWMI-Query $ msWMI-QueryLanguage $ msWMI-TargetNameSpace ) )", + "( 1.2.840.113556.1.5.254 NAME 'nTDSDSARO' SUP nTDSDSA STRUCTURAL )", + "( 1.2.840.113556.1.5.286 NAME 'msDS-Device' SUP top STRUCTURAL MUST (displayName $ altSecurityIdentities $ msDS-IsEnabled $ msDS-DeviceID ) MAY (msDS-DeviceOSType $ msDS-DeviceOSVersion $ msDS-DevicePhysicalIDs $ msDS-DeviceObjectVersion $ msDS-RegisteredOwner $ msDS-ApproximateLastLogonTimeStamp $ msDS-RegisteredUsers $ msDS-IsManaged $ msDS-CloudIsManaged $ msDS-CloudAnchor ) )", + "( 1.2.840.113556.1.5.34 NAME 'trustedDomain' SUP leaf STRUCTURAL MAY (securityIdentifier $ trustAuthIncoming $ trustDirection $ trustPartner $ trustPosixOffset $ trustAuthOutgoing $ trustType $ trustAttributes $ domainCrossRef $ flatName $ initialAuthIncoming $ initialAuthOutgoing $ domainIdentifier $ additionalTrustedServiceNames $ mS-DS-CreatorSID $ msDS-TrustForestTrustInfo $ msDS-SupportedEncryptionTypes $ msDS-IngressClaimsTransformationPolicy $ msDS-EgressClaimsTransformationPolicy ) )", + "( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURAL MUST (cn ) MAY (description $ telephoneNumber $ seeAlso $ location $ roomNumber ) )", + "( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST (o ) MAY (l $ st $ street $ searchGuide $ businessCategory $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ seeAlso $ userPassword ) )", + "( 1.2.840.113556.1.5.272 NAME 'msDS-ClaimType' SUP msDS-ClaimTypePropertyBase STRUCTURAL MAY (msDS-ClaimValueType $ msDS-ClaimAttributeSource $ msDS-ClaimTypeAppliesToClass $ msDS-ClaimSource $ msDS-ClaimSourceType $ msDS-ClaimIsValueSpaceRestricted $ msDS-ClaimIsSingleValued ) )", + "( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL MUST (cn $ ipServicePort $ ipServiceProtocol ) MAY (description $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL MUST (cn $ ipProtocolNumber ) MAY (description $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.2.840.113556.1.5.80 NAME 'rpcGroup' SUP rpcEntry STRUCTURAL MAY (rpcNsGroup $ rpcNsObjectID ) )", + "( 1.2.840.113556.1.5.17 NAME 'server' SUP top STRUCTURAL MAY (serialNumber $ serverReference $ dNSHostName $ managedBy $ mailAddress $ bridgeheadTransportList $ msDS-isGC $ msDS-isRODC $ msDS-SiteName $ msDS-IsUserCachableAtRodc ) )", + "( 1.2.840.113556.1.5.28 NAME 'secret' SUP leaf STRUCTURAL MAY (currentValue $ lastSetTime $ priorSetTime $ priorValue ) )", + "( 1.2.840.113556.1.5.163 NAME 'mSMQEnterpriseSettings' SUP top STRUCTURAL MAY (mSMQNameStyle $ mSMQCSPName $ mSMQLongLived $ mSMQVersion $ mSMQInterval1 $ mSMQInterval2 ) )", + "( 1.2.840.113556.1.5.202 NAME 'msWMI-MergeablePolicyTemplate' SUP msWMI-PolicyTemplate STRUCTURAL )", + "( 1.2.840.113556.1.5.195 NAME 'msPKI-Key-Recovery-Agent' SUP user STRUCTURAL )", + "( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP country STRUCTURAL MUST (co ) )", + "( 1.2.840.113556.1.5.258 NAME 'msDFS-Namespacev2' SUP top STRUCTURAL MUST (msDFS-SchemaMajorVersion $ msDFS-SchemaMinorVersion $ msDFS-GenerationGUIDv2 $ msDFS-NamespaceIdentityGUIDv2 $ msDFS-LastModifiedv2 $ msDFS-Ttlv2 $ msDFS-Propertiesv2 $ msDFS-TargetListv2 ) MAY (msDFS-Commentv2 ) )", + "( 1.2.840.113556.1.5.96 NAME 'subnet' SUP top STRUCTURAL MAY (location $ siteObject $ physicalLocationObject ) )", + "( 1.2.840.113556.1.5.216 NAME 'applicationVersion' SUP applicationSettings STRUCTURAL MAY (owner $ keywords $ versionNumber $ vendor $ versionNumberHi $ versionNumberLo $ managedBy $ appSchemaVersion ) )", + "( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MAY (l $ st $ street $ ou $ title $ businessCategory $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod ) )", + "( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL MUST (cn ) MAY (authorityRevocationList $ certificateRevocationList $ deltaRevocationList $ cRLPartitionedRevocationList $ certificateAuthorityObject ) )", + "( 1.2.840.113556.1.5.137 NAME 'aCSPolicy' SUP top STRUCTURAL MAY (aCSTimeOfDay $ aCSDirection $ aCSMaxTokenRatePerFlow $ aCSMaxPeakBandwidthPerFlow $ aCSAggregateTokenRatePerUser $ aCSMaxDurationPerFlow $ aCSServiceType $ aCSTotalNoOfFlows $ aCSPriority $ aCSPermissionBits $ aCSIdentityName $ aCSMaxAggregatePeakRatePerUser $ aCSMaxTokenBucketPerFlow $ aCSMaximumSDUSize $ aCSMinimumPolicedSize $ aCSMinimumLatency $ aCSMinimumDelayVariation ) )", + "( 1.2.840.113556.1.5.77 NAME 'controlAccessRight' SUP top STRUCTURAL MAY (rightsGuid $ appliesTo $ localizationDisplayId $ validAccesses ) )", + "( 1.2.840.113556.1.5.219 NAME 'msMQ-Group' SUP top STRUCTURAL MUST (member ) )", + "( 1.2.840.113556.1.5.8 NAME 'group' SUP top STRUCTURAL MUST (groupType ) MAY (member $ nTGroupMembers $ operatorCount $ adminCount $ groupAttributes $ groupMembershipSAM $ controlAccessRights $ desktopProfile $ nonSecurityMember $ managedBy $ primaryGroupToken $ msDS-AzLDAPQuery $ msDS-NonMembers $ msDS-AzBizRule $ msDS-AzBizRuleLanguage $ msDS-AzLastImportedBizRulePath $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData $ msDS-PrimaryComputer $ mail $ msSFU30Name $ msSFU30NisDomain $ msSFU30PosixMember ) )", + "( 1.2.840.113556.1.6.23.2 NAME 'msPrint-ConnectionPolicy' SUP top STRUCTURAL MUST (cn ) MAY (uNCName $ serverName $ printAttributes $ printerName ) )", + "( 1.2.840.113556.1.3.11 NAME 'crossRef' SUP top STRUCTURAL MUST (cn $ nCName $ dnsRoot ) MAY (Enabled $ nETBIOSName $ nTMixedDomain $ trustParent $ superiorDNSRoot $ rootTrust $ msDS-Behavior-Version $ msDS-NC-Replica-Locations $ msDS-Replication-Notify-First-DSA-Delay $ msDS-Replication-Notify-Subsequent-DSA-Delay $ msDS-SDReferenceDomain $ msDS-DnsRootAlias $ msDS-NC-RO-Replica-Locations ) )", + "( 1.2.840.113556.1.6.13.4.9 NAME 'msDFSR-Member' SUP top STRUCTURAL MUST (msDFSR-ComputerReference ) MAY (serverReference $ msDFSR-Extension $ msDFSR-Keywords $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.3.59 NAME 'displayTemplate' SUP top STRUCTURAL MUST (cn ) MAY (helpData32 $ originalDisplayTableMSDOS $ addressEntryDisplayTable $ helpFileName $ addressEntryDisplayTableMSDOS $ helpData16 $ originalDisplayTable ) )", + "( 1.2.840.113556.1.3.13 NAME 'classSchema' SUP top STRUCTURAL MUST (cn $ subClassOf $ governsID $ objectClassCategory $ schemaIDGUID $ defaultObjectCategory ) MAY (possSuperiors $ mustContain $ mayContain $ rDNAttID $ auxiliaryClass $ lDAPDisplayName $ schemaFlagsEx $ systemOnly $ systemPossSuperiors $ systemMayContain $ systemMustContain $ systemAuxiliaryClass $ defaultSecurityDescriptor $ defaultHidingValue $ classDisplayName $ isDefunct $ msDs-Schema-Extensions $ msDS-IntId ) )", + "( 1.2.840.113556.1.5.200 NAME 'msWMI-PolicyTemplate' SUP top STRUCTURAL MUST (msWMI-ID $ msWMI-Name $ msWMI-NormalizedClass $ msWMI-TargetClass $ msWMI-TargetNameSpace $ msWMI-TargetPath ) MAY (msWMI-Author $ msWMI-ChangeDate $ msWMI-CreationDate $ msWMI-SourceOrganization $ msWMI-TargetType $ msWMI-intFlags1 $ msWMI-intFlags2 $ msWMI-intFlags3 $ msWMI-intFlags4 $ msWMI-Parm1 $ msWMI-Parm2 $ msWMI-Parm3 $ msWMI-Parm4 ) )", + "( 1.2.840.113556.1.5.165 NAME 'mSMQSettings' SUP top STRUCTURAL MAY (mSMQOwnerID $ mSMQServices $ mSMQQMID $ mSMQMigrated $ mSMQNt4Flags $ mSMQSiteName $ mSMQRoutingService $ mSMQDsService $ mSMQDependentClientService $ mSMQSiteNameEx ) )", + "( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL MUST (cn $ oncRpcNumber ) MAY (description $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.2.840.113556.1.5.126 NAME 'serviceConnectionPoint' SUP connectionPoint STRUCTURAL MAY (versionNumber $ vendor $ versionNumberHi $ versionNumberLo $ serviceClassName $ serviceBindingInformation $ serviceDNSName $ serviceDNSNameType $ appSchemaVersion ) )", + "( 1.2.840.113556.1.5.4 NAME 'builtinDomain' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.241 NAME 'msDS-AppData' SUP applicationSettings STRUCTURAL MAY (owner $ keywords $ managedBy $ msDS-ByteArray $ msDS-DateTime $ msDS-Integer $ msDS-ObjectReference ) )", + "( 1.2.840.113556.1.5.73 NAME 'rpcServerElement' SUP rpcEntry STRUCTURAL MUST (rpcNsBindings $ rpcNsInterfaceID $ rpcNsTransferSyntax ) )", + "( 1.2.840.113556.1.5.150 NAME 'rRASAdministrationConnectionPoint' SUP serviceAdministrationPoint STRUCTURAL MAY (msRRASAttribute ) )", + "( 1.2.840.113556.1.5.191 NAME 'aCSResourceLimits' SUP top STRUCTURAL MAY (aCSMaxTokenRatePerFlow $ aCSMaxPeakBandwidthPerFlow $ aCSServiceType $ aCSAllocableRSVPBandwidth $ aCSMaxPeakBandwidth ) )", + "( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL MUST (l ) MAY (st $ street $ searchGuide $ seeAlso ) )", + "( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY MAY (cn $ l $ description $ uid $ manager $ ipHostNumber ) )", + "( 1.2.840.113556.1.5.275 NAME 'msTPM-InformationObject' SUP top STRUCTURAL MUST (msTPM-OwnerInformation ) MAY (msTPM-SrkPubThumbprint $ msTPM-OwnerInformationTemp ) )", + "( 1.2.840.113556.1.5.289 NAME 'msDS-DeviceContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.4.2129 NAME 'msDNS-ServerSettings' SUP top STRUCTURAL MAY (msDNS-KeymasterZones ) )", + "( 1.2.840.113556.1.5.76 NAME 'foreignSecurityPrincipal' SUP top STRUCTURAL MUST (objectSid ) MAY (foreignIdentifier ) )", + "( 1.2.840.113556.1.5.44 NAME 'classStore' SUP top STRUCTURAL MAY (versionNumber $ nextLevelStore $ lastUpdateSequence $ appSchemaVersion ) )", + "( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL MAY (l $ o $ ou $ description $ seeAlso $ uid $ host ) )", + "( 1.2.840.113556.1.5.26 NAME 'rpcProfileElement' SUP rpcEntry STRUCTURAL MUST (rpcNsInterfaceID $ rpcNsPriority ) MAY (rpcNsProfileEntry $ rpcNsAnnotation ) )", + "( 1.2.840.113556.1.5.215 NAME 'msWMI-WMIGPO' SUP top STRUCTURAL MUST (msWMI-TargetClass ) MAY (msWMI-intFlags1 $ msWMI-intFlags2 $ msWMI-intFlags3 $ msWMI-intFlags4 $ msWMI-Parm1 $ msWMI-Parm2 $ msWMI-Parm3 $ msWMI-Parm4 ) )", + "( 1.2.840.113556.1.5.243 NAME 'msDS-QuotaControl' SUP top STRUCTURAL MUST (cn $ msDS-QuotaTrustee $ msDS-QuotaAmount ) )", + "( 1.2.840.113556.1.5.256 NAME 'msDS-PasswordSettingsContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.187 NAME 'mS-SQL-SQLPublication' SUP top STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-Status $ mS-SQL-Description $ mS-SQL-Type $ mS-SQL-Database $ mS-SQL-AllowAnonymousSubscription $ mS-SQL-Publisher $ mS-SQL-AllowKnownPullSubscription $ mS-SQL-AllowImmediateUpdatingSubscription $ mS-SQL-AllowQueuedUpdatingSubscription $ mS-SQL-AllowSnapshotFilesFTPDownloading $ mS-SQL-ThirdParty ) )", + "( 1.2.840.113556.1.5.9 NAME 'user' SUP organizationalPerson STRUCTURAL MAY (o $ businessCategory $ userCertificate $ givenName $ initials $ x500uniqueIdentifier $ displayName $ networkAddress $ employeeNumber $ employeeType $ homePostalAddress $ userAccountControl $ badPwdCount $ codePage $ homeDirectory $ homeDrive $ badPasswordTime $ lastLogoff $ lastLogon $ dBCSPwd $ localeID $ scriptPath $ logonHours $ logonWorkstation $ maxStorage $ userWorkstations $ unicodePwd $ otherLoginWorkstations $ ntPwdHistory $ pwdLastSet $ preferredOU $ primaryGroupID $ userParameters $ profilePath $ operatorCount $ adminCount $ accountExpires $ lmPwdHistory $ groupMembershipSAM $ logonCount $ controlAccessRights $ defaultClassStore $ groupsToIgnore $ groupPriority $ desktopProfile $ dynamicLDAPServer $ userPrincipalName $ lockoutTime $ userSharedFolder $ userSharedFolderOther $ servicePrincipalName $ aCSPolicyName $ terminalServer $ mSMQSignCertificates $ mSMQDigests $ mSMQDigestsMig $ mSMQSignCertificatesMig $ msNPAllowDialin $ msNPCallingStationID $ msNPSavedCallingStationID $ msRADIUSCallbackNumber $ msRADIUSFramedIPAddress $ msRADIUSFramedRoute $ msRADIUSServiceType $ msRASSavedCallbackNumber $ msRASSavedFramedIPAddress $ msRASSavedFramedRoute $ mS-DS-CreatorSID $ msCOM-UserPartitionSetLink $ msDS-Cached-Membership $ msDS-Cached-Membership-Time-Stamp $ msDS-Site-Affinity $ msDS-User-Account-Control-Computed $ lastLogonTimestamp $ msIIS-FTPRoot $ msIIS-FTPDir $ msDRM-IdentityCertificate $ msDS-SourceObjectDN $ msPKIRoamingTimeStamp $ msPKIDPAPIMasterKeys $ msPKIAccountCredentials $ msRADIUS-FramedInterfaceId $ msRADIUS-SavedFramedInterfaceId $ msRADIUS-FramedIpv6Prefix $ msRADIUS-SavedFramedIpv6Prefix $ msRADIUS-FramedIpv6Route $ msRADIUS-SavedFramedIpv6Route $ msDS-SecondaryKrbTgtNumber $ msDS-AuthenticatedAtDC $ msDS-SupportedEncryptionTypes $ msDS-LastSuccessfulInteractiveLogonTime $ msDS-LastFailedInteractiveLogonTime $ msDS-FailedInteractiveLogonCount $ msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon $ msTSProfilePath $ msTSHomeDirectory $ msTSHomeDrive $ msTSAllowLogon $ msTSRemoteControl $ msTSMaxDisconnectionTime $ msTSMaxConnectionTime $ msTSMaxIdleTime $ msTSReconnectionAction $ msTSBrokenConnectionAction $ msTSConnectClientDrives $ msTSConnectPrinterDrives $ msTSDefaultToMainPrinter $ msTSWorkDirectory $ msTSInitialProgram $ msTSProperty01 $ msTSProperty02 $ msTSExpireDate $ msTSLicenseVersion $ msTSManagingLS $ msDS-UserPasswordExpiryTimeComputed $ msTSExpireDate2 $ msTSLicenseVersion2 $ msTSManagingLS2 $ msTSExpireDate3 $ msTSLicenseVersion3 $ msTSManagingLS3 $ msTSExpireDate4 $ msTSLicenseVersion4 $ msTSManagingLS4 $ msTSLSProperty01 $ msTSLSProperty02 $ msDS-ResultantPSO $ msPKI-CredentialRoamingTokens $ msTSPrimaryDesktop $ msTSSecondaryDesktops $ msDS-PrimaryComputer $ msDS-SyncServerUrl $ msDS-AssignedAuthNPolicySilo $ msDS-AuthNPolicySiloMembersBL $ msDS-AssignedAuthNPolicy $ userSMIMECertificate $ uid $ mail $ roomNumber $ photo $ manager $ homePhone $ secretary $ mobile $ pager $ audio $ jpegPhoto $ carLicense $ departmentNumber $ preferredLanguage $ userPKCS12 $ labeledURI $ msSFU30Name $ msSFU30NisDomain ) )", + "( 1.2.840.113556.1.5.259 NAME 'msDFS-Linkv2' SUP top STRUCTURAL MUST (msDFS-GenerationGUIDv2 $ msDFS-NamespaceIdentityGUIDv2 $ msDFS-LastModifiedv2 $ msDFS-Ttlv2 $ msDFS-Propertiesv2 $ msDFS-TargetListv2 $ msDFS-LinkPathv2 $ msDFS-LinkIdentityGUIDv2 ) MAY (msDFS-Commentv2 $ msDFS-LinkSecurityDescriptorv2 $ msDFS-ShortNameLinkPathv2 ) )", + "( 1.2.840.113556.1.5.141 NAME 'interSiteTransport' SUP top STRUCTURAL MUST (transportDLLName $ transportAddressAttribute ) MAY (options $ replInterval ) )", + "( 1.2.840.113556.1.6.13.4.4 NAME 'msDFSR-GlobalSettings' SUP top STRUCTURAL MAY (msDFSR-Extension $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.29 NAME 'serviceClass' SUP leaf STRUCTURAL MUST (displayName $ serviceClassID ) MAY (serviceClassInfo ) )", + "( 1.2.840.113556.1.5.189 NAME 'mS-SQL-OLAPDatabase' SUP top STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $ mS-SQL-LastUpdatedDate $ mS-SQL-InformationURL $ mS-SQL-ConnectionURL $ mS-SQL-PublicationURL $ mS-SQL-Description $ mS-SQL-Type $ mS-SQL-Size $ mS-SQL-LastBackupDate $ mS-SQL-Applications $ mS-SQL-Keywords ) )", + "( 2.5.6.16 NAME 'certificationAuthority' SUP top STRUCTURAL MUST (cn $ cACertificate $ authorityRevocationList $ certificateRevocationList ) MAY (searchGuide $ teletexTerminalIdentifier $ supportedApplicationContext $ crossCertificatePair $ deltaRevocationList $ domainPolicyObject $ parentCA $ dNSHostName $ parentCACertificateChain $ domainID $ cAConnect $ cAWEBURL $ cRLObject $ cAUsages $ previousCACertificates $ pendingCACertificates $ previousParentCA $ pendingParentCA $ currentParentCA $ cACertificateDN $ certificateTemplates $ signatureAlgorithms $ enrollmentProviders ) )", + "( 1.2.840.113556.1.5.104 NAME 'meeting' SUP top STRUCTURAL MUST (meetingName ) MAY (meetingID $ meetingDescription $ meetingKeyword $ meetingLocation $ meetingProtocol $ meetingType $ meetingApplication $ meetingLanguage $ meetingMaxParticipants $ meetingOriginator $ meetingContactInfo $ meetingOwner $ meetingIP $ meetingScope $ meetingAdvertiseScope $ meetingURL $ meetingRating $ meetingIsEncrypted $ meetingRecurrence $ meetingStartTime $ meetingEndTime $ meetingBandwidth $ meetingBlob ) )", + "( 1.2.840.113556.1.5.287 NAME 'msDS-DeviceRegistrationServiceContainer' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.71 NAME 'nTDSConnection' SUP leaf STRUCTURAL MUST (enabledConnection $ fromServer $ options ) MAY (generatedConnection $ schedule $ transportType $ mS-DS-ReplicatesNCReason ) )", + "( 1.2.840.113556.1.5.291 NAME 'msDS-AuthNPolicySilos' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.218 NAME 'msMQ-Custom-Recipient' SUP top STRUCTURAL MAY (msMQ-Recipient-FormatName ) )", + "( 1.2.840.113556.1.5.72 NAME 'nTDSService' SUP top STRUCTURAL MAY (tombstoneLifetime $ dSHeuristics $ garbageCollPeriod $ replTopologyStayOfExecution $ sPNMappings $ msDS-Other-Settings $ msDS-DeletedObjectLifetime ) )", + "( 1.2.840.113556.1.3.9 NAME 'dMD' SUP top STRUCTURAL MUST (cn ) MAY (dmdName $ schemaUpdate $ prefixMap $ schemaInfo $ msDs-Schema-Extensions $ msDS-IntId $ msDS-USNLastSyncSuccess ) )", + "( 1.2.840.113556.1.5.280 NAME 'msDS-ClaimsTransformationPolicyType' SUP top STRUCTURAL MAY (msDS-TransformationRules $ msDS-TransformationRulesCompiled ) )", + "( 0.9.2342.19200300.100.4.14 NAME 'rFC822LocalPart' SUP domain STRUCTURAL MAY (cn $ sn $ street $ description $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ seeAlso ) )", + "( 1.2.840.113556.1.5.190 NAME 'mS-SQL-OLAPCube' SUP top STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $ mS-SQL-LastUpdatedDate $ mS-SQL-InformationURL $ mS-SQL-PublicationURL $ mS-SQL-Description $ mS-SQL-Size $ mS-SQL-Keywords ) )", + "( 1.2.840.113556.1.5.208 NAME 'msWMI-UintSetParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-IntDefault ) MAY (msWMI-IntValidValues ) )", + "( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY MAY (cn $ description $ userPassword $ unixUserPassword $ gidNumber $ memberUid ) )", + "( 2.5.6.17 NAME 'groupOfUniqueNames' SUP top STRUCTURAL MUST (cn $ uniqueMember ) MAY (o $ ou $ description $ businessCategory $ owner $ seeAlso ) )", + "( 1.2.840.113556.1.5.252 NAME 'ms-net-ieee-8023-GroupPolicy' SUP top STRUCTURAL MAY (ms-net-ieee-8023-GP-PolicyGUID $ ms-net-ieee-8023-GP-PolicyData $ ms-net-ieee-8023-GP-PolicyReserved ) )", + "( 1.2.840.113556.1.5.119 NAME 'ipsecNegotiationPolicy' SUP ipsecBase STRUCTURAL MAY (iPSECNegotiationPolicyType $ iPSECNegotiationPolicyAction ) )", + "( 1.2.840.113556.1.5.292 NAME 'msDS-AuthNPolicySilo' SUP top STRUCTURAL MAY (msDS-AssignedAuthNPolicySiloBL $ msDS-AuthNPolicySiloMembers $ msDS-UserAuthNPolicy $ msDS-ComputerAuthNPolicy $ msDS-ServiceAuthNPolicy $ msDS-AuthNPolicySiloEnforced ) )", + "( 1.2.840.113556.1.5.121 NAME 'ipsecNFA' SUP ipsecBase STRUCTURAL MAY (ipsecNegotiationPolicyReference $ ipsecFilterReference ) )", + "( 1.2.840.113556.1.5.42 NAME 'dfsConfiguration' SUP top STRUCTURAL )", + "( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top STRUCTURAL MUST (cn ) MAY (l $ o $ ou $ description $ telephoneNumber $ seeAlso ) )", + "( 1.2.840.113556.1.5.271 NAME 'msDS-ResourceProperties' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.91 NAME 'linkTrackObjectMoveTable' SUP fileLinkTracking STRUCTURAL )", + "( 1.2.840.113556.1.5.136 NAME 'rpcContainer' SUP container STRUCTURAL MAY (nameServiceFlags ) )", + "( 1.2.840.113556.1.5.83 NAME 'rIDManager' SUP top STRUCTURAL MUST (rIDAvailablePool ) MAY (msDS-RIDPoolAllocationEnabled ) )", + "( 1.2.840.113556.1.5.206 NAME 'msWMI-IntSetParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-IntDefault ) MAY (msWMI-IntValidValues ) )", + "( 1.2.840.113556.1.6.13.4.5 NAME 'msDFSR-ReplicationGroup' SUP top STRUCTURAL MUST (msDFSR-ReplicationGroupType ) MAY (description $ msDFSR-Version $ msDFSR-Extension $ msDFSR-RootSizeInMb $ msDFSR-StagingSizeInMb $ msDFSR-ConflictSizeInMb $ msDFSR-TombstoneExpiryInMin $ msDFSR-FileFilter $ msDFSR-DirectoryFilter $ msDFSR-Schedule $ msDFSR-Flags $ msDFSR-Options $ msDFSR-DeletedSizeInMb $ msDFSR-DefaultCompressionExclusionFilter $ msDFSR-OnDemandExclusionFileFilter $ msDFSR-OnDemandExclusionDirectoryFilter $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.125 NAME 'addressBookContainer' SUP top STRUCTURAL MUST (displayName ) MAY (purportedSearch ) )", + "( 1.2.840.113556.1.5.7000.49 NAME 'applicationSettings' SUP top ABSTRACT MAY (applicationName $ notificationList $ msDS-Settings ) )", + "( 1.2.840.113556.1.5.265 NAME 'msDS-OptionalFeature' SUP top STRUCTURAL MUST (msDS-OptionalFeatureGUID $ msDS-OptionalFeatureFlags ) MAY (msDS-RequiredDomainBehaviorVersion $ msDS-RequiredForestBehaviorVersion ) )", + "( 1.2.840.113556.1.5.94 NAME 'serviceAdministrationPoint' SUP serviceConnectionPoint STRUCTURAL )", + "( 1.2.840.113556.1.5.102 NAME 'nTFRSReplicaSet' SUP top STRUCTURAL MAY (fRSReplicaSetType $ fRSVersionGUID $ schedule $ fRSFileFilter $ fRSDirectoryFilter $ fRSDSPoll $ fRSServiceCommand $ fRSReplicaSetGUID $ fRSLevelLimit $ fRSRootSecurity $ fRSExtensions $ managedBy $ fRSFlags $ fRSPartnerAuthLevel $ fRSPrimaryMember $ msFRS-Topology-Pref $ msFRS-Hub-Member ) )", + "( 1.2.840.113556.1.5.203 NAME 'msWMI-RangeParam' SUP top STRUCTURAL MUST (msWMI-PropertyName $ msWMI-TargetClass $ msWMI-TargetType ) )", + "( 1.2.840.113556.1.5.7000.56 NAME 'ipsecBase' SUP top ABSTRACT MAY (ipsecName $ ipsecID $ ipsecDataType $ ipsecData $ ipsecOwnersReference ) )", + "( 1.2.840.113556.1.6.13.4.3 NAME 'msDFSR-Subscription' SUP top STRUCTURAL MUST (msDFSR-ContentSetGuid $ msDFSR-ReplicationGroupGuid ) MAY (msDFSR-Extension $ msDFSR-RootPath $ msDFSR-RootSizeInMb $ msDFSR-StagingPath $ msDFSR-StagingSizeInMb $ msDFSR-ConflictPath $ msDFSR-ConflictSizeInMb $ msDFSR-Enabled $ msDFSR-Flags $ msDFSR-Options $ msDFSR-RootFence $ msDFSR-DfsLinkTarget $ msDFSR-DeletedPath $ msDFSR-DeletedSizeInMb $ msDFSR-ReadOnly $ msDFSR-CachePolicy $ msDFSR-MinDurationCacheInMin $ msDFSR-MaxAgeInCacheInMin $ msDFSR-OnDemandExclusionFileFilter $ msDFSR-OnDemandExclusionDirectoryFilter $ msDFSR-Options2 $ msDFSR-StagingCleanupTriggerInPercent ) )", + "( 1.2.840.113556.1.5.223 NAME 'msPKI-PrivateKeyRecoveryAgent' SUP top STRUCTURAL MUST (userCertificate ) )", + "( 1.2.840.113556.1.5.178 NAME 'pKIEnrollmentService' SUP top STRUCTURAL MAY (cACertificate $ dNSHostName $ cACertificateDN $ certificateTemplates $ signatureAlgorithms $ enrollmentProviders $ msPKI-Enrollment-Servers $ msPKI-Site-Name ) )", + "( 1.2.840.113556.1.6.18.2.211 NAME 'msSFU30MailAliases' SUP top STRUCTURAL MAY (msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.2.840.113556.1.5.53 NAME 'typeLibrary' SUP top STRUCTURAL MAY (cOMClassID $ cOMInterfaceID $ cOMUniqueLIBID ) )", + "( 1.2.840.113556.1.6.13.4.8 NAME 'msDFSR-Topology' SUP top STRUCTURAL MAY (msDFSR-Extension $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 ) )", + "( 1.2.840.113556.1.5.237 NAME 'msDS-AzScope' SUP top STRUCTURAL MUST (msDS-AzScopeName ) MAY (description $ msDS-AzApplicationData $ msDS-AzObjectGuid $ msDS-AzGenericData ) )", + "( 1.2.840.113556.1.5.74 NAME 'categoryRegistration' SUP leaf STRUCTURAL MAY (localeID $ categoryId $ managedBy $ localizedDescription ) )", + "( 1.2.840.113556.1.5.11 NAME 'comConnectionPoint' SUP connectionPoint STRUCTURAL MUST (cn ) MAY (marshalledInterface $ moniker $ monikerDisplayName ) )", + "( 1.2.840.113556.1.5.93 NAME 'linkTrackOMTEntry' SUP leaf STRUCTURAL MAY (birthLocation $ oMTIndxGuid $ currentLocation $ timeRefresh $ oMTGuid ) )", + "( 1.2.840.113556.1.5.10 NAME 'classRegistration' SUP leaf STRUCTURAL MAY (cOMInterfaceID $ cOMProgID $ cOMCLSID $ cOMTreatAsClassId $ cOMOtherProgId $ implementedCategories $ requiredCategories $ managedBy ) )", + "( 1.2.840.113556.1.5.148 NAME 'siteLinkBridge' SUP top STRUCTURAL MUST (siteLinkList ) )", + "( 1.2.840.113556.1.5.81 NAME 'rpcServer' SUP rpcEntry STRUCTURAL MAY (rpcNsObjectID $ rpcNsCodeset $ rpcNsEntryFlags ) )", + "( 1.2.840.113556.1.3.46 NAME 'mailRecipient' SUP top AUXILIARY MUST (cn ) MAY (telephoneNumber $ userCertificate $ info $ garbageCollPeriod $ msExchAssistantName $ msExchLabeledURI $ showInAddressBook $ userCert $ legacyExchangeDN $ msDS-PhoneticDisplayName $ msDS-GeoCoordinatesAltitude $ msDS-GeoCoordinatesLatitude $ msDS-GeoCoordinatesLongitude $ userSMIMECertificate $ textEncodedORAddress $ secretary $ labeledURI ) )", + "( 1.2.840.113556.1.5.1 NAME 'securityObject' SUP top ABSTRACT MUST (cn ) )", + "( 1.2.840.113556.1.5.20 NAME 'leaf' SUP top ABSTRACT )", + "( 1.2.840.113556.1.5.151 NAME 'intellimirrorSCP' SUP serviceAdministrationPoint STRUCTURAL MAY (netbootMachineFilePath $ netbootAllowNewClients $ netbootLimitClients $ netbootMaxClients $ netbootCurrentClientCount $ netbootAnswerRequests $ netbootAnswerOnlyValidClients $ netbootNewMachineNamingPolicy $ netbootNewMachineOU $ netbootIntelliMirrorOSes $ netbootTools $ netbootLocallyInstalledOSes $ netbootServer ) )", + "( 1.2.840.113556.1.6.13.4.1 NAME 'msDFSR-LocalSettings' SUP top STRUCTURAL MAY (msDFSR-Version $ msDFSR-Extension $ msDFSR-Flags $ msDFSR-Options $ msDFSR-Options2 $ msDFSR-CommonStagingPath $ msDFSR-CommonStagingSizeInMb $ msDFSR-StagingCleanupTriggerInPercent ) )", + "( 1.2.840.113556.1.5.186 NAME 'mS-SQL-SQLRepository' SUP top STRUCTURAL MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Build $ mS-SQL-Status $ mS-SQL-Version $ mS-SQL-Description $ mS-SQL-InformationDirectory ) )", + "( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST (cn ) MAY (l $ st $ street $ ou $ postalAddress $ postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $ teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ roleOccupant $ seeAlso ) )", + "( 2.5.20.1 NAME 'subSchema' SUP top STRUCTURAL MAY (extendedClassInfo $ extendedAttributeInfo $ dITContentRules $ attributeTypes $ objectClasses $ modifyTimeStamp ) )", + "( 1.2.840.113556.1.5.284 NAME 'msDS-DeviceRegistrationService' SUP top STRUCTURAL MUST (msDS-IsEnabled $ msDS-DeviceLocation ) MAY (msDS-IssuerCertificates $ msDS-RegistrationQuota $ msDS-MaximumRegistrationInactivityPeriod $ msDS-IssuerPublicCertificates $ msDS-CloudIssuerPublicCertificates $ msDS-CloudIsEnabled ) )", + "( 1.2.840.113556.1.5.84 NAME 'displaySpecifier' SUP top STRUCTURAL MAY (iconPath $ creationWizard $ contextMenu $ adminPropertyPages $ shellPropertyPages $ classDisplayName $ adminContextMenu $ shellContextMenu $ attributeDisplayNames $ treatAsLeaf $ createDialog $ createWizardExt $ scopeFlags $ queryFilter $ extraColumns $ adminMultiselectPropertyPages ) )", + "( 1.2.840.113556.1.5.212 NAME 'msWMI-ShadowObject' SUP top STRUCTURAL MUST (msWMI-TargetObject ) )", + "( 1.2.840.113556.1.5.59 NAME 'fileLinkTrackingEntry' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.4.2161 NAME 'msAuthz-CentralAccessPolicies' SUP top STRUCTURAL )", + "( 1.2.840.113556.1.5.161 NAME 'mSMQQueue' SUP top STRUCTURAL MAY (mSMQQueueType $ mSMQJournal $ mSMQBasePriority $ mSMQLabel $ mSMQAuthenticate $ mSMQPrivacyLevel $ mSMQOwnerID $ mSMQTransactional $ mSMQQueueQuota $ mSMQQueueJournalQuota $ mSMQQueueNameExt $ mSMQLabelEx $ MSMQ-SecuredSource $ MSMQ-MulticastAddress ) )", + "( 1.2.840.113556.1.5.193 NAME 'msCOM-Partition' SUP top STRUCTURAL MAY (msCOM-ObjectId ) )", + "( 1.2.840.113556.1.5.118 NAME 'ipsecFilter' SUP ipsecBase STRUCTURAL )", + "( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST (c ) MAY (searchGuide $ co ) )", + "( 1.2.840.113556.1.5.97 NAME 'physicalLocation' SUP locality STRUCTURAL MAY (managedBy ) )", + "( 1.2.840.113556.1.3.30 NAME 'computer' SUP user STRUCTURAL MAY (cn $ networkAddress $ localPolicyFlags $ defaultLocalPolicyObject $ machineRole $ location $ netbootInitialization $ netbootGUID $ netbootMachineFilePath $ siteGUID $ operatingSystem $ operatingSystemVersion $ operatingSystemServicePack $ operatingSystemHotfix $ volumeCount $ physicalLocationObject $ dNSHostName $ policyReplicationFlags $ managedBy $ rIDSetReferences $ catalogs $ netbootSIFFile $ netbootMirrorDataFile $ msDS-AdditionalDnsHostName $ msDS-AdditionalSamAccountName $ msDS-ExecuteScriptPassword $ msDS-KrbTgtLink $ msDS-RevealedUsers $ msDS-NeverRevealGroup $ msDS-RevealOnDemandGroup $ msDS-RevealedList $ msDS-AuthenticatedAtDC $ msDS-isGC $ msDS-isRODC $ msDS-SiteName $ msDS-PromotionSettings $ msTPM-OwnerInformation $ msTSProperty01 $ msTSProperty02 $ msDS-IsUserCachableAtRodc $ msDS-HostServiceAccount $ msTSEndpointData $ msTSEndpointType $ msTSEndpointPlugin $ msTSPrimaryDesktopBL $ msTSSecondaryDesktopBL $ msTPM-TpmInformationForComputer $ msDS-GenerationId $ msImaging-ThumbprintHash $ msImaging-HashAlgorithm $ netbootDUID $ msSFU30Name $ msSFU30Aliases $ msSFU30NisDomain $ nisMapName ) )", + "( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL MUST (cn ) MAY (description $ msSFU30Name $ msSFU30NisDomain $ msSFU30NetgroupHostAtDomain $ msSFU30NetgroupUserAtDomain $ memberNisNetgroup $ nisNetgroupTriple $ nisMapName ) )", + "( 1.2.840.113556.1.5.153 NAME 'nTFRSMember' SUP top STRUCTURAL MAY (fRSUpdateTimeout $ fRSServiceCommand $ serverReference $ fRSRootSecurity $ fRSExtensions $ frsComputerReference $ fRSControlDataCreation $ fRSControlInboundBacklog $ fRSControlOutboundBacklog $ fRSFlags $ fRSPartnerAuthLevel ) )", + "( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL MUST (cn $ presentationAddress ) MAY (l $ o $ ou $ supportedApplicationContext $ seeAlso ) )", + "( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST (cn ) MAY (l $ ou $ seeAlso ) )", + "( 1.2.840.113556.1.5.279 NAME 'msDS-ValueType' SUP top STRUCTURAL MUST (msDS-ClaimValueType $ msDS-ClaimIsValueSpaceRestricted $ msDS-ClaimIsSingleValued $ msDS-IsPossibleValuesPresent ) )", + "( 1.2.840.113556.1.5.204 NAME 'msWMI-UnknownRangeParam' SUP msWMI-RangeParam STRUCTURAL MUST (msWMI-NormalizedClass $ msWMI-TargetObject ) )", + "( 1.2.840.113556.1.5.66 NAME 'domain' SUP top ABSTRACT MUST (dc ) )", + "( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL MAY (knowledgeInformation ) )", + "( 1.2.840.113556.1.5.120 NAME 'ipsecISAKMPPolicy' SUP ipsecBase STRUCTURAL )" + ], + "objectGUID": [ + { + "encoded": "sr4GScorekOq9Mmm+aY8Ow==", + "encoding": "base64" + } + ], + "systemFlags": [ + "134217728" + ], + "uSNChanged": [ + "5" + ], + "uSNCreated": [ + "5" + ], + "whenChanged": [ + "20130521164433.0Z" + ], + "whenCreated": [ + "20130521164433.0Z" + ] + }, + "schema_entry": "CN=Aggregate,CN=Schema,CN=Configuration,DC=AD2012,DC=LAB", + "type": "SchemaInfo" +} +""" +ad_2012_r2_dsa_info = """ +{ + "raw": { + "configurationNamingContext": [ + "CN=Configuration,DC=AD2012,DC=LAB" + ], + "currentTime": [ + "20141111080100.0Z" + ], + "defaultNamingContext": [ + "DC=AD2012,DC=LAB" + ], + "dnsHostName": [ + "WIN1.AD2012.LAB" + ], + "domainControllerFunctionality": [ + "6" + ], + "domainFunctionality": [ + "6" + ], + "dsServiceName": [ + "CN=NTDS Settings,CN=WIN1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=AD2012,DC=LAB" + ], + "forestFunctionality": [ + "6" + ], + "highestCommittedUSN": [ + "22591" + ], + "isGlobalCatalogReady": [ + "TRUE" + ], + "isSynchronized": [ + "TRUE" + ], + "ldapServiceName": [ + "AD2012.LAB:win1$@AD2012.LAB" + ], + "namingContexts": [ + "DC=AD2012,DC=LAB", + "CN=Configuration,DC=AD2012,DC=LAB", + "CN=Schema,CN=Configuration,DC=AD2012,DC=LAB", + "DC=DomainDnsZones,DC=AD2012,DC=LAB", + "DC=ForestDnsZones,DC=AD2012,DC=LAB" + ], + "rootDomainNamingContext": [ + "DC=AD2012,DC=LAB" + ], + "schemaNamingContext": [ + "CN=Schema,CN=Configuration,DC=AD2012,DC=LAB" + ], + "serverName": [ + "CN=WIN1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=AD2012,DC=LAB" + ], + "subschemaSubentry": [ + "CN=Aggregate,CN=Schema,CN=Configuration,DC=AD2012,DC=LAB" + ], + "supportedCapabilities": [ + "1.2.840.113556.1.4.800", + "1.2.840.113556.1.4.1670", + "1.2.840.113556.1.4.1791", + "1.2.840.113556.1.4.1935", + "1.2.840.113556.1.4.2080", + "1.2.840.113556.1.4.2237" + ], + "supportedControl": [ + "1.2.840.113556.1.4.319", + "1.2.840.113556.1.4.801", + "1.2.840.113556.1.4.473", + "1.2.840.113556.1.4.528", + "1.2.840.113556.1.4.417", + "1.2.840.113556.1.4.619", + "1.2.840.113556.1.4.841", + "1.2.840.113556.1.4.529", + "1.2.840.113556.1.4.805", + "1.2.840.113556.1.4.521", + "1.2.840.113556.1.4.970", + "1.2.840.113556.1.4.1338", + "1.2.840.113556.1.4.474", + "1.2.840.113556.1.4.1339", + "1.2.840.113556.1.4.1340", + "1.2.840.113556.1.4.1413", + "2.16.840.1.113730.3.4.9", + "2.16.840.1.113730.3.4.10", + "1.2.840.113556.1.4.1504", + "1.2.840.113556.1.4.1852", + "1.2.840.113556.1.4.802", + "1.2.840.113556.1.4.1907", + "1.2.840.113556.1.4.1948", + "1.2.840.113556.1.4.1974", + "1.2.840.113556.1.4.1341", + "1.2.840.113556.1.4.2026", + "1.2.840.113556.1.4.2064", + "1.2.840.113556.1.4.2065", + "1.2.840.113556.1.4.2066", + "1.2.840.113556.1.4.2090", + "1.2.840.113556.1.4.2205", + "1.2.840.113556.1.4.2204", + "1.2.840.113556.1.4.2206", + "1.2.840.113556.1.4.2211", + "1.2.840.113556.1.4.2239", + "1.2.840.113556.1.4.2255", + "1.2.840.113556.1.4.2256" + ], + "supportedExtension": [ + "1.3.6.1.4.1.1466.20037", + "1.3.6.1.4.1.1466.101.119.1", + "1.2.840.113556.1.4.1781", + "1.3.6.1.4.1.4203.1.11.3", + "1.2.840.113556.1.4.2212" + ], + "supportedLDAPPolicies": [ + "MaxPoolThreads", + "MaxPercentDirSyncRequests", + "MaxDatagramRecv", + "MaxReceiveBuffer", + "InitRecvTimeout", + "MaxConnections", + "MaxConnIdleTime", + "MaxPageSize", + "MaxBatchReturnMessages", + "MaxQueryDuration", + "MaxTempTableSize", + "MaxResultSetSize", + "MinResultSets", + "MaxResultSetsPerConn", + "MaxNotificationPerConn", + "MaxValRange", + "MaxValRangeTransitive", + "ThreadMemoryLimit", + "SystemMemoryLimitPercent" + ], + "supportedLDAPVersion": [ + "3", + "2" + ], + "supportedSASLMechanisms": [ + "GSSAPI", + "GSS-SPNEGO", + "EXTERNAL", + "DIGEST-MD5" + ] + }, + "type": "DsaInfo" +} +""" diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ds389.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ds389.py new file mode 100644 index 00000000..51e48940 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/ds389.py @@ -0,0 +1,1715 @@ +""" +""" + +# Created on 2014.11.11 +# +# 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 . + +ds389_1_3_3_schema = """ +{ + "raw": { + "aci": [ + "(target=\\"ldap:///cn=schema\\")(targetattr !=\\"aci\\")(version 3.0;acl \\"anonymous, no acis\\"; allow (read, search, compare) userdn = \\"ldap:///anyone\\";)" + ], + "attributeTypes": [ + "( 2.16.840.1.113730.3.1.582 NAME 'nsDS5ReplicaCredentials' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 2.16.840.1.113730.3.1.2274 NAME 'nsslapd-instancedir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.532 NAME 'ntUserCountryCode' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.18.0.2.4.1139 NAME 'printer-info' DESC 'Descriptive information about this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'LDAP referrals attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'LDAPv3 referrals Internet Draft' )", + "( 1.3.6.1.4.1.13769.2.4 NAME ( 'nsAIMid' 'nscpaimscreenname' ) EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'Mozilla Address Book' )", + "( sslVersionMin-oid NAME 'sslVersionMin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.204 NAME 'replicaNickName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2243 NAME 'nsslapd-securelistenhost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2108 NAME 'nsPagedLookThroughLimit' DESC 'Binder-based simple paged search operation look through limit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389' )", + "( 1.3.6.1.4.1.6981.11.3.7 NAME 'FTPStatus' DESC 'Account status: enabled or disabled' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.2091 NAME 'nsslapd-suffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.5.4.51 NAME 'houseIdentifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( nsUserRDNComponent-oid NAME 'nsUserRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.18.0.2.4.1117 NAME 'printer-media-local-supported' DESC 'Site-specific names of media supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2301 NAME 'nsslapd-plugin-logging' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822mailbox' ) EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 4524' X-DEPRECATED 'rfc822mailbox' )", + "( 2.16.840.1.113730.3.1.607 NAME 'nsDS5Flags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsTaskLabel-oid NAME 'nsTaskLabel' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2068 NAME 'pamExcludeSuffix' DESC 'Suffixes to exclude from PAM authentication' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2157 NAME 'dnaRemoteBindCred' DESC 'Remote bind credentials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2261 NAME 'nsslapd-attribute-name-exceptions' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.250.1.2 NAME 'multiLineDescription' DESC 'Pilot attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Internet White Pages Pilot' )", + "( 2.16.840.1.113730.3.1.102 NAME ( 'passwordChange' 'pwdAllowUserChange' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.527 NAME 'ntUserLastLogoff' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.21 NAME 'mailQuota' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.2.840.113556.1.4.482 NAME 'calOtherCalURIs' DESC 'RFC2739: multi-value URI for snapshots of other calendars' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.2238 NAME 'nsslapd-security' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'Fully qualified name of distinguished Java class or interface' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.240 NAME 'replicatedattributelist' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2175 NAME 'nsslapd-accesslog-logrotationsync-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsRevisionNumber-oid NAME 'nsRevisionNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2207 NAME 'nsslapd-rootdn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsHelpRef-oid NAME 'nsHelpRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.43 NAME 'ntUserDeleteAccount' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.217 NAME 'replicaCFUpdated' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.6 NAME 'targetDn' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.5.4.25 NAME 'internationalISDNNumber' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.998 NAME ( 'passwordGraceUserTime' 'pwdGraceUserTime' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2225 NAME 'nsslapd-workingdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.65 NAME 'ntUserLogonServer' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.781 NAME 'mgrpAddHeader' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.2295 NAME 'nsslapd-allowed-sasl-mechanisms' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2162 NAME 'winSyncDirectoryFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 X-ORIGIN 'SUDO' )", + "( 1.3.18.0.2.4.1121 NAME 'printer-resolution-supported' DESC 'List of resolutions supported for printing documents by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2139 NAME 'winSyncMoveAction' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsExpirationDate-oid NAME 'nsExpirationDate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.5923.1.1.1.1 NAME 'eduPersonAffiliation' DESC 'Affiliation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( nsVendor-oid NAME 'nsVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.87 NAME 'cirUpdateSchedule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.32 NAME 'owner' SUP distinguishedName EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.253 NAME 'nsValueSyntax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( nsLdapSchemaVersion-oid NAME 'nsLdapSchemaVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2100 NAME 'autoMemberInclusiveRegex' DESC 'Auto Membership inclusive regex rule' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2089 NAME 'mepMappedAttr' DESC 'Managed Entries mapped attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2212 NAME 'nsslapd-useroc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2282 NAME 'nsslapd-rundir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.3.3 NAME 'mozillaHomeLocalityName' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.5.4.10 NAME ( 'o' 'organizationname' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'organizationname' )", + "( 2.16.840.1.113730.3.1.2259 NAME 'nsslapd-return-exact-case' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminAccessAddresses-oid NAME 'nsAdminAccessAddresses' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( nsAdminUsers-oid NAME 'nsAdminUsers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.19 NAME 'mailMessageStore' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.221 NAME 'passwordStorageScheme' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2126 NAME 'dnaHostname' DESC 'DNA hostname of replica to get new range of values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2230 NAME 'nsslapd-ldapiautobind' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2196 NAME 'nsslapd-accesslog-logexpirationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.576 NAME 'nsRoleFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.70 NAME 'serverRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 5.3.6.1.1.1.1.0 NAME 'trustModel' DESC 'Access scheme' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'nss_ldap/pam_ldap' )", + "( 2.16.840.1.113730.3.1.248 NAME 'nsValueDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.1466.101.120.41 NAME 'parentOrganization' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( nsAdminEnableDSGW-oid NAME 'nsAdminEnableDSGW' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.18.0.2.4.1132 NAME 'printer-multiple-document-jobs-supported' DESC 'Indicates whether or not this printer supports more than one document per job.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 1.3.6.1.4.1.13769.2.1 NAME ( 'mozillaNickname' 'xmozillanickname' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Mozilla Address Book' )", + "( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.92 NAME ( 'passwordExpWarned' 'pwdExpirationWarned' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2246 NAME 'nsslapd-maxdescriptors' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2113 NAME 'internalModifiersName' DESC 'plugin dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2094 NAME 'nsslapd-parent-suffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.692 NAME 'inetUserStatus' DESC '\\"active\\", \\"inactive\\", or \\"deleted\\" status of a user' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape subscriber interoperability' )", + "( 1.3.18.0.2.4.1110 NAME 'printer-job-priority-supported' DESC 'Indicates the number of job priority levels supported by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2183 NAME 'nsslapd-audit-logrotationsyncmin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2304 NAME 'nsslapd-dynamic-plugins' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.789 NAME 'mgrpNoDuplicateChecks' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.602 NAME 'entrydn' DESC 'internal server defined attribute type' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113730.3.1.1098 NAME 'nsds5replicaSessionPauseTime' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2073 NAME 'pamSecure' DESC 'Require secure (TLS/SSL) connection for PAM auth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2264 NAME 'nsslapd-max-filter-nest-level' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.2 NAME 'dITContentRules' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.522 NAME 'ntUserComment' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.18.0.2.4.1129 NAME 'printer-color-supported' DESC 'Indicates whether this printer is capable of any type of color printing at all, including highlight color.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.24 NAME 'mailRoutingAddress' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( nsmsgDisallowAccess-oid NAME 'nsmsgDisallowAccess' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.2.840.113556.1.4.485 NAME 'calOtherCalAdrURIs' DESC 'RFC2739: multi-value URI to other request destinations' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.2131 NAME 'pamFilter' DESC 'Filter to match entries that should use PAM authentication' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.234 NAME 'nsSNMPLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.5923.1.1.1.9 NAME 'eduPersonScopedAffiliation' DESC 'Scoped Affiliation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( nsHostLocation-oid NAME 'nsHostLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.590 NAME 'nsDS5ReplicaName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2178 NAME 'nsslapd-accesslog-logrotationsynchour' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2081 NAME ( 'passwordMaxRepeats' 'pwdMaxRepeats' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.687 NAME 'nsds5replicaChangesSentSinceStartup' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1107 NAME 'printer-xri-supported' DESC 'The unordered list of XRI (extended resource identifiers) supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.46 NAME 'ntGroupDeleteGroup' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.9 NAME 'newRdn' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.1.2147 NAME 'rootdn-allow-host' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2251 NAME 'nsslapd-accesscontrol' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.11 NAME 'newSuperior' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.1.229 NAME 'nsslapd-pluginVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2228 NAME 'nsslapd-ldapifilepath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.5.4.47 NAME 'enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.68 NAME 'ntUserPasswordExpired' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2298 NAME 'nsslapd-enable-turbo-mode' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.585 NAME 'nsDS5ReplicatedAttributeList' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2165 NAME 'schemaUpdateObjectclassAccept' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2277 NAME 'nsslapd-tmpdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.1002 NAME 'nsds7NewWinUserSyncEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.23 NAME 'lastModifiedTime' DESC 'old variant of modifyTimestamp' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 1274' )", + "( 2.16.840.1.113730.3.1.110 NAME 'ntGroupId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.535 NAME 'ntUserHomeDirDrive' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.33 NAME 'mgrpModerator' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.207 NAME 'vlvBase' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( nsServerMigrationClassname-oid NAME 'nsServerMigrationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( nsSSLPersonalitySSL-oid NAME 'nsSSLPersonalitySSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.5.4.35 NAME 'userPassword' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4519' )", + "( 1.3.6.1.1.4 NAME 'vendorName' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )", + "( 1.3.6.1.4.1.6981.11.3.4 NAME 'FTPDownloadRatio' DESC 'Ratio (compared with FTPRatioUp) for downloaded files' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.801 NAME 'mgrpRemoveHeader' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.2215 NAME 'nsslapd-allow-unauthenticated-binds' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1118 NAME 'printer-copies-supported' DESC 'The maximum number of copies of a document that may be printed as a single job on this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.55 NAME 'aci' DESC 'Netscape defined access control information attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2285 NAME 'nsslapd-hash-filters' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.5.4.7 NAME ( 'l' 'locality' 'localityname' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'locality localityname' )", + "( nsSSL3SessionTimeout-oid NAME 'nsSSL3SessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2152 NAME 'nsds5ReplicaProtocolTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.105 NAME ( 'passwordLockout' 'pwdLockOut' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2129 NAME 'dnaNextRange' DESC 'DNA range of values to get from replica' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( nsSSL3-oid NAME 'nsSSL3' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2199 NAME 'nsslapd-accesslog-logexpirationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.571 NAME 'nsSizeLimit' DESC 'Binder-based search operation size limit (entries)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.77 NAME 'changeTime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.243 NAME 'nsValueCIS' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( 2.16.840.1.113730.3.1.2170 NAME 'nsslapd-accesslog-level' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2202 NAME 'nsslapd-accesslog-logging-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC 'Information used by the autofs automounter' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis' )", + "( 2.16.840.1.113730.3.1.1 NAME 'carLicense' DESC 'vehicle license or registration plate' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2798' )", + "( nsCertConfig-oid NAME 'nsCertConfig' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Certificate Management System' )", + "( 2.16.840.1.113730.3.1.99 NAME ( 'passwordMinLength' 'pwdMinLength' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2249 NAME 'nsslapd-idletimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2116 NAME 'dnaPrefix' DESC 'DNA string prefix for dna value' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2220 NAME 'nsslapd-minssf-exclude-rootdse' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2186 NAME 'nsslapd-auditlog-logrotationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.60 NAME 'ntUserAuthFlags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2290 NAME 'nsslapd-disk-monitoring-threshold' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2076 NAME ( 'passwordMinAlphas' 'pwdMinAlphas' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.406 NAME 'nsSynchUserIDFormat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.5 NAME 'attributeTypes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.18.0.2.4.1122 NAME 'printer-media-supported' DESC 'The standard names/types/sizes (and optional color suffixes) of the media supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( nsAdminEnableEnduser-oid NAME 'nsAdminEnableEnduser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.1.1.1.26 NAME 'nisMapName' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2134 NAME 'nsds5ReplicaStripAttrs' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.544 NAME 'nsParentUniqueId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.5923.1.1.1.4 NAME 'eduPersonOrgUnitDN' DESC 'Organizational Unit DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.82 NAME 'cirBindDn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' DESC 'a JPEG image' SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 X-ORIGIN 'RFC 2798' )", + "( 1.3.6.1.4.1.42.2.27.4.1.13 NAME 'javaClassNames' DESC 'Fully qualified Java class or interface name' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.2103 NAME 'autoMemberDisabled' DESC 'Auto Membership disabled attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.809 NAME 'nsds5replicaLastInitStatus' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2084 NAME 'nsSymmetricKey' DESC 'A symmetric key - currently used by attribute encryption' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'attribute encryption' )", + "( 2.16.840.1.113730.3.1.682 NAME 'nsds5ReplicaPurgeDelay' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 4524' )", + "( nsTLS1-oid NAME 'nsTLS1' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2063 NAME 'nsEncryptionAlgorithm' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.3.4 NAME 'mozillaHomeState' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2254 NAME 'nsslapd-pwpolicy-local' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2121 NAME 'dnaScope' DESC 'DNA base DN for finding entries' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.14 NAME 'mailAutoReplyMode' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.224 NAME 'nsslapd-pluginPath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.11.1.3.2.1.2 NAME 'acctPolicySubentry' DESC 'Account policy pointer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Account Policy Plugin' )", + "( 2.16.840.1.113730.3.1.2191 NAME 'nsslapd-errorlog-logmaxdiskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2233 NAME 'nsslapd-ldapiuidnumbertype' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.579 NAME 'nsDS5ReplicaPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.610 NAME 'nsAccountLock' DESC 'Operational attribute for Account Inactivation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.707 NAME 'vacationstartdate' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.580 NAME 'nsDS5ReplicaTransportInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2168 NAME 'schemaUpdateAttributeReject' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 1.3.18.0.2.4.1137 NAME 'printer-generated-natural-language-supported' DESC 'Natural language(s) supported for this directory entry.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.1005 NAME 'nsds7DirsyncCookie' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.24 NAME 'lastModifiedBy' DESC 'old variant of modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 1274' )", + "( 2.16.840.1.113730.3.1.530 NAME 'ntUserLogonHours' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.36 NAME 'nsLicensedFor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.202 NAME 'replicaCredentials' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.2.2 NAME ( 'mozillaSecondEmail' 'xmozillasecondemail' ) EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.3023 NAME 'nsViewFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsSSL2Ciphers-oid NAME 'nsSSL2Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( nsServerAddress-oid NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.91 NAME 'passwordExpirationTime' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2241 NAME 'nsslapd-errorlog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsProductName-oid NAME 'nsProductName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2027 NAME 'nsruvReplicaLastModified' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.38 NAME 'authorityRevocationList' DESC 'X.509 authority revocation list' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( 2.16.840.1.113730.3.1.2097 NAME 'autoMemberScope' DESC 'Auto Membership scope criteria' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.695 NAME 'inetSubscriberChallenge' DESC 'Used to confirm subscriberIdentity. This attribute holds the challenge phrase and is used in conjunction with the inetSubscriberResponse' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape subscriber interoperability' )", + "( 2.16.840.1.113730.3.1.2218 NAME 'nsslapd-localssf' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1115 NAME 'printer-stacking-order-supported' DESC 'The possible stacking order of pages as they are printed and ejected from this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 1.2.840.113556.1.4.479 NAME 'calFBURL' DESC 'RFC2739: URI to the users default freebusy data' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.2307 NAME 'nsslapd-allow-hashed-passwords' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.58 NAME 'replicaBindDn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.605 NAME 'entryid' DESC 'internal server defined attribute type' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113730.3.1.2288 NAME 'nsslapd-defaultnamingcontext' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.3.9 NAME 'mozillaWorkUrl' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2155 NAME 'nsds5ReplicaBackoffMax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2267 NAME 'nsslapd-certmap-basedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.100 NAME 'passwordKeepHistory' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.525 NAME 'ntUserWorkstations' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.23 NAME 'mgrpAllowedDomain' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.2.840.113556.1.4.480 NAME 'calCAPURI' DESC 'RFC2739: URI used to communicate with the users calendar' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.237 NAME 'nsSNMPMasterHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsDefaultAcceptLanguage-oid NAME 'nsDefaultAcceptLanguage' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.593 NAME 'nsSNMPName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2205 NAME 'nsslapd-auditlog-logging-hide-unhashed-pw' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1108 NAME 'printer-aliases' DESC 'List of site-specific administrative names of this printer in addition to the value specified for printer-name.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.45 NAME 'ntGroupCreateNewGroup' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.215 NAME 'oid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2142 NAME 'nsSaslMapPriority' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.4 NAME 'employeeType' DESC 'type of employment for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.1.2119 NAME 'dnaMagicRegen' DESC 'DNA value that will trigger regeneration of attribute value' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.5.4.42 NAME 'givenName' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2189 NAME 'nsslapd-auditlog-logrotationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.67 NAME 'ntUserProfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2079 NAME ( 'passwordMinSpecials' 'pwdMinSpecials' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.588 NAME 'nsDS5ReplicaId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2160 NAME 'dnaRemoteBindMethod' DESC 'Remote bind method: SIMPLE, SSL, SASL/DIGEST-MD5, or SASL/GSSAPI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 1.3.6.1.4.1.13769.4.3 NAME 'mozillaCustom3' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2272 NAME 'nsslapd-plugin-binddn-tracking' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.8 NAME 'matchingRuleUse' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.250.1.57 NAME ( 'labeledURI' 'labeledurl' ) EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2079' X-DEPRECATED 'labeledurl' )", + "( 1.3.6.1.1.1.1.23 NAME 'bootParameter' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.89 NAME 'cirSyncInterval' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.251 NAME 'nsValueFlags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( 2.16.840.1.113730.3.1.2106 NAME 'nsIDListScanLimit' DESC 'Binder-based search operation ID list scan limit (candidate entries)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389' )", + "( 1.3.6.1.4.1.6981.11.3.1 NAME 'FTPQuotaFiles' DESC 'Quota (in number of files) for an FTP user' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.804 NAME 'nsSchemaCSN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( nsServerSecurity-oid NAME 'nsServerSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2210 NAME 'nsslapd-auditlog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDrink' ) EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' X-DEPRECATED 'favouriteDrink' )", + "( 2.16.840.1.113730.3.1.50 NAME 'replicaBeginOrc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2280 NAME 'nsslapd-bakdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.4 NAME ( 'sn' 'surName' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'surName' )", + "( 2.16.840.1.113730.3.1.2066 NAME 'nsSaslMapFilterTemplate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.3.1 NAME 'mozillaHomeStreet' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.198 NAME 'memberURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.108 NAME 'passwordUnlock' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2307' )", + "( nsSSLClientAuth-oid NAME 'nsSSLClientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2124 NAME 'dnaRemainingValues' DESC 'DNA remaining values left to assign' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2236 NAME 'nsslapd-anonlimitsdn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2194 NAME 'nsslapd-errorlog-logminfreediskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.574 NAME 'nsRole' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminGroupName-oid NAME 'nsAdminGroupName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.72 NAME 'serverVersionNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.246 NAME 'nsValueInt' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.1466.101.120.43 NAME 'preferredTimeZone' DESC 'preferred time zone for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2173 NAME 'nsslapd-errorlog-maxlogsize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 1.3.18.0.2.4.1130 NAME 'printer-document-format-supported' DESC 'The possible source document formats which may be interpreted and printed by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.552 NAME 'costargettree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.94 NAME 'retryCountResetTime' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 X-ORIGIN 'RFC 4519' X-DEPRECATED 'fax' )", + "( 2.16.840.1.113730.3.1.2244 NAME 'nnslapd-threadnumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.2.840.113556.1.2.102 NAME 'memberOf' DESC 'Group that the entry belongs to' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Delegated Administrator' )", + "( 2.16.840.1.113730.3.1.2111 NAME 'tombstoneNumSubordinates' DESC 'count of immediate subordinates for tombstone entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN '389 directory server' )", + "( nsDirectoryURL-oid NAME 'nsDirectoryURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.690 NAME 'inetDomainBaseDN' DESC 'Base DN of user subtree for a DNS domain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape subscriber interoperability' )", + "( 2.16.840.1.113730.3.1.2223 NAME 'nsslapd-localhost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2181 NAME 'nsslapd-accesslog-logrotationsyncmin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.569 NAME 'cosPriority' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsOsVersion-oid NAME 'nsOsVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( nsJarfilename-oid NAME 'nsJarfilename' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2293 NAME 'nsslapd-ndn-cache-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2071 NAME 'pamIDAttr' DESC 'Name of attribute holding PAM ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2158 NAME 'dnaRemoteBindDN' DESC 'Remote bind DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 1.3.18.0.2.4.1127 NAME 'printer-pages-per-minute' DESC 'The nominal number of pages per minute which may be output by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 0.9.2342.19200300.100.1.54 NAME 'ditRedirect' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 1274' )", + "( 2.16.840.1.113730.3.1.520 NAME 'nswmExtendedUserPrefs' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.26 NAME 'mgrpErrorsTo' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.3.6.1.4.1.4203.1.3.5 NAME 'supportedFeatures' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.232 NAME 'nsSNMPEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2137 NAME 'nsds5ReplicaAbortCleanRUV' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.17 NAME 'ldapSchemas' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 2927' )", + "( 1.3.6.1.4.1.5923.1.1.1.7 NAME 'eduPersonEntitlement' DESC 'Entitlement' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.81 NAME 'cirPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.6981.11.3.9 NAME 'FTPgid' DESC 'System uid (overrides gidNumber if present)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.2087 NAME 'mepManagedEntry' DESC 'Managed Entries pointer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.685 NAME 'nsds5replicaLastUpdateStart' DESC 'Netscape defined attribute type' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminSIEDN-oid NAME 'nsAdminSIEDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2208 NAME 'nsslapd-rootdnpw' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.48 NAME 'replicaPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.210 NAME 'vlvSort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2145 NAME 'rootdn-close-time' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2257 NAME 'nsslapd-accesslog-logbuffering' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlycountryname' ) EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' X-DEPRECATED 'friendlycountryname' )", + "( 2.16.840.1.113730.3.1.13 NAME 'mailAlternateAddress' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.227 NAME 'nsslapd-pluginId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.45 NAME 'x500UniqueIdentifier' EQUALITY bitStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.613 NAME 'copiedFrom' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( nsServerPort-oid NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.42.2.27.4.1.8 NAME 'javaSerializedData' DESC 'Serialized form of a Java object' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.583 NAME 'nsDS5ReplicaBindMethod' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2275 NAME 'nsslapd-schemadir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsSSLActivation-oid NAME 'nsSSLActivation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.1000 NAME 'nsds7WindowsReplicaSubtree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.21 NAME 'secretary' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.533 NAME 'ntUserCodePage' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.18.0.2.4.1138 NAME 'printer-make-and-model' DESC 'Make and model of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.35 NAME 'changeLog' DESC 'the distinguished name of the entry which contains the set of entries comprising this servers changelog' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.1.205 NAME 'changeLogMaximumConcurrentWrites' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsDirectoryInfoRef-oid NAME 'nsDirectoryInfoRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.6981.11.3.6 NAME 'FTPDownloadBandwidth' DESC 'Bandwidth (in KB/s) to limit download speeds to' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.2109 NAME 'nsPagedIDListScanLimit' DESC 'Binder-based simple paged search operation ID list scan limit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389' )", + "( 2.16.840.1.113730.3.1.2092 NAME 'nsslapd-ldapiautodnsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.5.4.52 NAME 'supportedAlgorithms' DESC 'X.509 supported algorithms' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( 1.3.18.0.2.4.1116 NAME 'printer-output-features-supported' DESC 'The possible output features supported by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2302 NAME 'nsslapd-listen-backlog-size' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.57 NAME 'replicaRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.608 NAME 'nsDS5Task' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.9 NAME ( 'street' 'streetaddress' ) EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'streetaddress' )", + "( 2.16.840.1.113730.3.1.2069 NAME 'pamMissingSuffix' DESC 'How to handle missing include or exclude suffixes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2150 NAME 'rootdn-deny-ip' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsGroupRDNComponent-oid NAME 'nsGroupRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.2262 NAME 'nsslapd-maxbersize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.19 NAME 'physicalDeliveryOfficeName' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.528 NAME 'ntUserAcctExpires' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.103 NAME ( 'passwordCheckSyntax' 'pwdCheckSyntax' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2307' )", + "( 1.2.840.113556.1.4.483 NAME 'calOtherFBURLs' DESC 'RFC2739: multi-value URI for other free/busy data' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.2239 NAME 'nsslapd-SSL3ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.79 NAME 'cirReplicaRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.241 NAME 'displayName' DESC 'preferred name of a person to be used when displaying entries' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2798' )", + "( nsProductVersion-oid NAME 'nsProductVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2176 NAME 'nsslapd-errorlog-logrotationsync-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2200 NAME 'nsslapd-errorlog-logexpirationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' DESC 'signed message used to support S/MIME' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'RFC 2798' )", + "( nsSecureServerPort-oid NAME 'nsSecureServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.218 NAME 'replicaAbandonedChanges' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.7 NAME 'changeType' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.999 NAME ( 'passwordGraceLimit' 'pwdGraceLoginLimit' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2114 NAME 'internalCreatorsName' DESC 'plugin dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN '389 Directory Server' )", + "( nsBindPassword-oid NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.812 NAME 'netscapeReversiblePassword' DESC 'password for HTTP Digest/MD5 authentication' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'Netscape Web Server' )", + "( 2.16.840.1.113730.3.1.2226 NAME 'nsslapd-listenhost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.6 NAME 'shadowMin' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2184 NAME 'nsslapd-accesslog-logrotationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.10 NAME 'manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.62 NAME 'ntUserParms' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2296 NAME 'nsslapd-ignore-virtual-attrs' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2074 NAME 'pamService' DESC 'Service name to pass to pam_start' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2163 NAME 'winSyncWindowsFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.4.4 NAME 'mozillaCustom4' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 1.3.18.0.2.4.1120 NAME 'printer-print-quality-supported' DESC 'List of print qualities supported for printing documents on this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 1.3.6.1.1.1.1.24 NAME 'bootFile' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.4.1.5923.1.1.1.2 NAME 'eduPersonNickName' DESC 'NickName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.542 NAME 'nsUniqueId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.84 NAME 'cirUseSsl' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4519' )", + "( nsServerID-oid NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.254 NAME 'nsValueHelpURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape servers - value item' )", + "( 2.16.840.1.113730.3.1.807 NAME 'nsds5replicaLastInitStart' DESC 'Netscape defined attribute type' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2101 NAME 'autoMemberDefaultGroup' DESC 'Auto Membership default group' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2213 NAME 'nsslapd-userat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2283 NAME 'nsslapd-SSLclientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.8 NAME 'userClass' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.5.4.1 NAME 'aliasedObjectName' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.13769.3.2 NAME 'mozillaHomeStreet2' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2148 NAME 'rootdn-deny-host' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'organizationalUnitName' )", + "( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.16 NAME 'mailDeliveryOption' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.2127 NAME 'dnaPortNum' DESC 'DNA port number of replica to get new range of values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.222 NAME ( 'passwordMinAge' 'pwdMinAge' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113719.1.1.4.1.35 NAME 'lastLoginTime' DESC 'Last login time' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Account Policy Plugin' )", + "( 2.16.840.1.113730.3.1.2231 NAME 'nsslapd-ldapimaprootdn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2197 NAME 'nsslapd-errorlog-logexpirationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.577 NAME 'cosIndirectSpecifier' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.71 NAME 'serverProductName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 5.3.6.1.1.1.1.1 NAME 'accessTo' DESC 'Access to which servers user is allowed' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'nss_ldap/pam_ldap' )", + "( 2.16.840.1.113730.3.1.249 NAME 'nsValueType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 2.16.840.1.113730.3.1.2278 NAME 'nsslapd-certdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1135 NAME 'printer-name' DESC 'The site-specific administrative name of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.38 NAME 'nsLicenseEndTime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.200 NAME 'changeLogMaximumAge' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.93 NAME 'passwordRetryCount' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2247 NAME 'nsslapd-conntablesize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2095 NAME 'connection' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( nsSuiteSpotUser-oid NAME 'nsSuiteSpotUser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.693 NAME 'inetUserHttpURL' DESC 'A users Web addresses' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape subscriber interoperability' )", + "( 1.3.18.0.2.4.1113 NAME 'printer-service-person' DESC 'The identity of the current human service person responsible for servicing this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2305 NAME 'nsslapd-moddn-aci' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.603 NAME 'dncomp' DESC 'internal server defined attribute type' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113730.3.1.1099 NAME 'winSyncInterval' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2265 NAME 'nsslapd-versionstring' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.523 NAME 'ntUserFlags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.18.0.2.4.1128 NAME 'printer-compression-supported' DESC 'Compression algorithms supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2132 NAME 'nsds5ReplicaEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsExecRef-oid NAME 'nsExecRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.25 NAME 'mgrpDeliverTo' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.235 NAME 'nsSNMPContact' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.591 NAME 'nsDS5ReplicaReferral' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2179 NAME 'nsslapd-errorlog-logrotationsynchour' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2082 NAME ( 'passwordMinCategories' 'pwdMinCategories' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.688 NAME 'nsds5replicaLastUpdateStatus' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.213 NAME 'vlvEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2140 NAME 'passwordTrackUpdateTime' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2252 NAME 'nsslapd-groupevalnestlevel' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2229 NAME 'nsslapd-ldapilisten' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.40 NAME 'crossCertificatePair' DESC 'X.509 cross certificate pair' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.69 NAME 'subtreeACI' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server 1.0' )", + "( 2.16.840.1.113730.3.1.2299 NAME 'nsslapd-connection-buffer' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2166 NAME 'schemaUpdateObjectclassReject' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.586 NAME 'nsDS5ReplicaUpdateSchedule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.4.1 NAME 'mozillaCustom1' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2270 NAME 'nsslapd-auditlog-list' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.1003 NAME 'nsds7NewWinGroupSyncEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.111 NAME 'ntUniqueId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.536 NAME 'ntGroupAttributes' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.30 NAME 'mgrpRFC822MailMember' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.208 NAME 'vlvScope' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )", + "( nsNickName-oid NAME 'nsNickName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.5.4.36 NAME 'userCertificate' DESC 'X.509 user certificate' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( 2.16.840.1.113730.3.1.2104 NAME 'nsslapd-pluginConfigArea' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.5 NAME 'vendorVersion' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )", + "( 1.3.6.1.4.1.6981.11.3.3 NAME 'FTPUploadRatio' DESC 'Ratio (compared with FTPRatioDown) for uploaded files' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.802 NAME 'nsds5ReplicaLegacyConsumer' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2216 NAME 'nsslapd-require-secure-binds' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsKeyfile-oid NAME 'nsKeyfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.52 NAME 'replicaUpdateSchedule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23 X-ORIGIN 'RFC 1274' )", + "( 2.5.4.6 NAME ( 'c' 'countryName' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.11 SINGLE-VALUE X-ORIGIN 'RFC 4519' X-DEPRECATED 'countryName' )", + "( 2.16.840.1.113730.3.1.2064 NAME 'nsSaslMapRegexString' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2286 NAME 'nsslapd-outbound-ldap-io-timeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2153 NAME ( 'passwordAdminDN' 'pwdAdminDN' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.14 NAME 'searchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.106 NAME ( 'passwordMaxFailure' 'pwdMaxFailure' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2234 NAME 'nsslapd-ldapigidnumbertype' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.572 NAME 'nsTimeLimit' DESC 'Binder-based search operation time limit (seconds)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.74 NAME 'administratorContactInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( nsClassname-oid NAME 'nsClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.244 NAME 'nsValueCES' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.5322.17.2.1 NAME 'authorizedService' DESC 'IANA GSS-API authorized service name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'NSS LDAP schema' )", + "( 2.16.840.1.113730.3.1.2171 NAME 'nsslapd-accesslog-maxlogsperdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2203 NAME 'nsslapd-errorlog-logging-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsDeleteclassname-oid NAME 'nsDeleteclassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( nsmsgNumMsgQuota-oid NAME 'nsmsgNumMsgQuota' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( nsAdminCgiWaitPid-oid NAME 'nsAdminCgiWaitPid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' DESC 'identifies a department within an organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.1.550 NAME 'cosAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.96 NAME ( 'passwordHistory' 'pwdHistory' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.21 NAME 'telexNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2117 NAME 'dnaNextValue' DESC 'DNA next available value for assignment' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2098 NAME 'autoMemberFilter' DESC 'Auto Membership filter criteria' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2187 NAME 'nsslapd-accesslog-logrotationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2221 NAME 'nsslapd-validate-cert' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2308 NAME 'nstombstonecsn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.61 NAME 'ntUserUsrComment' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2291 NAME 'nsslapd-disk-monitoring-grace-period' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2077 NAME ( 'passwordMinUppers' 'pwdMinUppers' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.407 NAME 'nsSynchUniqueAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2268 NAME 'nsslapd-accesslog-list' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1125 NAME 'printer-finishings-supported' DESC 'The possible finishing operations supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.5.21.6 NAME 'objectClasses' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.28 NAME 'mgrpMsgRejectAction' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.230 NAME 'nsslapd-pluginDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2135 NAME 'nsds5ReplicaCleanRUV' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminCacheLifetime-oid NAME 'nsAdminCacheLifetime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.327 NAME 'nsIndexType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.545 NAME 'nscpEntryDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.5923.1.1.1.5 NAME 'eduPersonPrimaryAffiliation' DESC 'Primary Affiliation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.83 NAME 'cirUsePersistentSearch' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.42.2.27.4.1.10 NAME 'javaFactory' DESC 'Fully qualified Java class name of a JNDI object factory' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2713' )", + "( 2.5.18.10 NAME 'subschemaSubentry' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.2085 NAME 'isReplicated' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.683 NAME 'nsds5ReplicaTombstonePurgeInterval' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.38 NAME 'associatedName' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.1100 NAME 'oneWaySync' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsConfigRoot-oid NAME 'nsConfigRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.13769.3.7 NAME 'mozillaHomeUrl' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2255 NAME 'passwordIsGlobalPolicy' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.41 NAME ( 'mobile' 'mobileTelephoneNumber' ) EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'RFC 4524' X-DEPRECATED 'mobileTelephoneNumber' )", + "( 2.16.840.1.113730.3.1.2122 NAME 'dnaMaxValue' DESC 'DNA maximum value to assign' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( nsAdminDomainName-oid NAME 'nsAdminDomainName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.15 NAME 'mailAutoReplyText' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.225 NAME 'nsslapd-pluginInitfunc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminEndUserHTMLIndex-oid NAME 'nsAdminEndUserHTMLIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.4.1.11.1.3.2.1.3 NAME 'accountInactivityLimit' DESC 'Account inactivity limit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Account Policy Plugin' )", + "( 2.16.840.1.113730.3.1.2192 NAME 'nsslapd-auditlog-logmaxdiskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsBuildSecurity-oid NAME 'nsBuildSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.708 NAME 'vacationenddate' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.581 NAME 'nsDS5ReplicaBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2169 NAME 'nsslapd-pagedsizelimit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( mgrpApprovePassword-oid NAME 'mgrpApprovePassword' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.3.18.0.2.4.1136 NAME 'printer-location' DESC 'The physical location of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.531 NAME 'ntUserBadPwCount' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.37 NAME 'nsLicenseStartTime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.203 NAME 'replicaEntryFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2242 NAME 'nsslapd-securePort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.39 NAME 'certificateRevocationList' DESC 'X.509 certificate revocation list' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( nsAdminAccountInfo-oid NAME 'nsAdminAccountInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.2090 NAME 'mepRDNAttr' DESC 'Managed Entries RDN attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.696 NAME 'inetSubscriberResponse' DESC 'Used to confirm subscriberIdentity. This attribute holds the response phrase and is used in conjunction with the inetSubscriberChallenge' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape subscriber interoperability' )", + "( 2.5.4.50 NAME 'uniqueMember' EQUALITY uniqueMemberMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2219 NAME 'nsslapd-minssf' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1114 NAME 'printer-delivery-orientation-supported' DESC 'The possible delivery orientations of pages as they are printed and ejected from this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 1.3.6.1.4.1.250.1.60 NAME ( 'ttl' 'timeToLive' ) DESC 'time to live in seconds for cached objects' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'LDAP Caching Internet Draft' )", + "( 2.16.840.1.113730.3.1.2300 NAME 'nsslapd-connection-nocanon' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.59 NAME 'ntUserPriv' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2289 NAME 'nsslapd-disk-monitoring' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsDefaultObjectClass-oid NAME 'nsDefaultObjectClass' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.4.1.13769.3.8 NAME 'mozillaWorkStreet2' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2156 NAME 'nsslapd-sasl-max-buffer-size' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2260 NAME 'nsslapd-result-tweak' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.101 NAME ( 'passwordInHistory' 'pwdInHistory' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.526 NAME 'ntUserLastLogon' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.20 NAME 'mailProgramDeliveryInfo' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 1.2.840.113556.1.4.481 NAME 'calCalAdrURI' DESC 'RFC2739: URI for event equests destination' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.238 NAME 'nsSNMPMasterPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'SUDO' )", + "( 1.3.6.1.4.1.42.2.27.4.1.7 NAME 'javaCodebase' DESC 'URL(s) specifying the location of class definition' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.594 NAME 'nsDS5ReplicatedAttributeListTotal' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2174 NAME 'nsslapd-auditlog-maxlogsize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2206 NAME 'nsslapd-unhashed-pw-switch' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.42 NAME 'ntUserCreateNewAccount' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' DESC 'PKCS #12 PFX PDU for exchange of personal identity information' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.1.2143 NAME 'nsslapd-sasl-mapping-fallback' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.5 NAME 'changeNumber' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.5.18.9 NAME 'hasSubordinates' DESC 'if TRUE, subordinate entries may exist' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'numSubordinates Internet Draft' )", + "( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.997 NAME 'pwdpolicysubentry' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.43 NAME 'initials' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2224 NAME 'nsslapd-port' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.4 NAME 'loginShell' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.64 NAME 'ntUserNumLogons' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2294 NAME 'nsslapd-ndn-cache-max-size' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2161 NAME 'nsIndexIDListScanLimit' DESC 'fine grained idlistscanlimit - per index/type/value' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.589 NAME 'nsDS5ReplicaType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.4.2 NAME 'mozillaCustom2' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 X-ORIGIN 'SUDO' )", + "( 2.16.840.1.113730.3.1.2273 NAME 'nsslapd-config' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.9 NAME 'structuralObjectClass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( nsDisplayName-oid NAME 'nsDisplayName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.1.1.1.22 NAME 'macAddress' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2138 NAME 'nsslapd-readonly' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.86 NAME 'cirLastUpdateApplied' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.31 NAME 'member' SUP distinguishedName EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4519' )", + "( sslVersionMax-oid NAME 'sslVersionMax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.252 NAME 'nsValueDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( 2.16.840.1.113730.3.1.2107 NAME 'nsPagedSizeLimit' DESC 'Binder-based simple paged search operation size limit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389' )", + "( 2.16.840.1.113730.3.1.805 NAME 'nsds5replicaTimeout' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2088 NAME 'mepStaticAttr' DESC 'Managed Entries static attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2211 NAME 'nsslapd-dynamicconf' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.51 NAME 'replicaUpdateReplayed' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2281 NAME 'nsslapd-saslpath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.3 NAME ( 'cn' 'commonName' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'commonName' )", + "( 2.16.840.1.113730.3.1.2067 NAME 'pamIncludeSuffix' DESC 'Suffixes to include for PAM authentication' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.199 NAME 'memberCertificateDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.2312.4.3.3.1 NAME 'sabayonProfileURL' DESC 'The URL of a sabayon profile' SUP labeledURI EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Sabayon' )", + "( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2258 NAME 'nsslapd-csnlogging' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsSSL2-oid NAME 'nsSSL2' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.109 NAME ( 'passwordLockoutDuration' 'pwdLockoutDuration' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.18 NAME 'mailHost' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.220 NAME ( 'passwordMustChange' 'pwdMustChange' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2125 NAME 'dnaThreshold' DESC 'DNA threshold for getting next range of values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2237 NAME 'nsslapd-counters' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2195 NAME 'nsslapd-auditlog-logminfreediskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.575 NAME 'nsRoleDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.73 NAME 'installationTimeStamp' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.247 NAME 'nsValueBin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 1.3.18.0.2.4.1133 NAME 'printer-ipp-versions-supported' DESC 'IPP protocol version(s) that this printer supports.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.95 NAME 'accountUnlockTime' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2245 NAME 'nsslapd-maxthreadsperconn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2112 NAME 'ntGroupType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.691 NAME 'inetDomainStatus' DESC '\\"active\\", \\"inactive\\", or \\"deleted\\" status of a domain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape subscriber interoperability' )", + "( 1.3.18.0.2.4.1111 NAME 'printer-job-k-octets-supported' DESC 'The maximum size in kilobytes (1,024 octets actually) incoming print job that this printer will accept.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2182 NAME 'nsslapd-errorlog-logrotationsyncmin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.788 NAME 'mgrpBroadcasterPolicy' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.601 NAME 'adminRole' DESC 'Administrative role' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Delegated Administrator' )", + "( 2.16.840.1.113730.3.1.2072 NAME 'pamFallback' DESC 'Fallback to regular LDAP BIND if PAM auth fails' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.2159 NAME 'dnaRemoteConnProtocol' DESC 'Connection protocol: LDAP, TLS, or SSL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( nsLogSuppress-oid NAME 'nsLogSuppress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.5.21.1 NAME 'dITStructureRules' EQUALITY integerFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.521 NAME 'ntUserHomeDir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 1.3.18.0.2.4.1126 NAME 'printer-pages-per-minute-color' DESC 'The nominal number of color pages per minute which may be output by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 1.2.840.113556.1.4.484 NAME 'calOtherCAPURIs' DESC 'RFC2739: multi-value URI to other calendars' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.2130 NAME 'dnaRangeRequestTimeout' DESC 'DNA timeout for querying replica for next range of values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.233 NAME 'nsSNMPOrganization' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.5923.1.1.1.8 NAME 'eduPersonPrimaryOrgUnitDN' DESC 'Primary Organizational Unit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( nsHardwarePlatform-oid NAME 'nsHardwarePlatform' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.6981.11.3.8 NAME 'FTPuid' DESC 'System uid (overrides uidNumber if present)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.686 NAME 'nsds5replicaLastUpdateEnd' DESC 'Netscape defined attribute type' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2080 NAME ( 'passwordMin8bit' 'pwdMin8bit' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2209 NAME 'nsslapd-rootpwstoragescheme' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.49 NAME 'replicaUpdateFailedAt' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.8 NAME 'changes' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.1.2146 NAME 'rootdn-days-allowed' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2250 NAME 'nsslapd-ioblocktimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 0.9.2342.19200300.100.1.42 NAME ( 'pager' 'pagerTelephoneNumber' ) EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'RFC 4524' X-DEPRECATED 'pagerTelephoneNumber' )", + "( 2.16.840.1.113730.3.1.10 NAME 'deleteOldRdn' DESC 'Changelog attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.1.228 NAME 'nsslapd-pluginVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.46 NAME 'dnQualifier' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.614 NAME 'copyingFrom' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( nsSSLToken-oid NAME 'nsSSLToken' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.584 NAME 'nsDS5ReplicaRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2164 NAME 'winSyncSubtreePair' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2276 NAME 'nsslapd-lockdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.1001 NAME 'nsds7DirectoryReplicaSubtree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.534 NAME 'ntUserPrimaryGroupId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 0.9.2342.19200300.100.1.20 NAME ( 'homePhone' 'homeTelephoneNumber' ) EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'RFC 4524' X-DEPRECATED 'homeTelephoneNumber' )", + "( 2.16.840.1.113730.3.1.32 NAME 'mgrpMsgMaxSize' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.206 NAME 'filterInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1140 NAME 'printer-uri' DESC 'A URI supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4519' )", + "( nsSSL3Ciphers-oid NAME 'nsSSL3Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.6981.11.3.5 NAME 'FTPUploadBandwidth' DESC 'Bandwidth (in KB/s) to limit upload speeds to' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.2093 NAME 'nsslapd-changelogsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2214 NAME 'nsslapd-svrtab' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.53 NAME 'deltaRevocationList' DESC 'X.509 delta revocation list' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( nsUniqueAttribute-oid NAME 'nsUniqueAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.18.0.2.4.1119 NAME 'printer-natural-language-configured' DESC 'The configured natural language in which error and status messages will be generated (by default) by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2303 NAME 'nsslapd-ignore-time-skew' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.54 NAME 'replicaUseSSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'userid' )", + "( 2.16.840.1.113730.3.1.609 NAME 'nsds5BeginReplicaRefresh' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2284 NAME 'nsslapd-ssl-check-hostname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' X-DEPRECATED 'stateOrProvinceName' )", + "( 2.16.840.1.113730.3.1.1097 NAME 'nsds5replicaBusyWaitTime' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2151 NAME 'nsslapd-plugin-depends-on-type' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsViewConfiguration-oid NAME 'nsViewConfiguration' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.2263 NAME 'nsslapd-maxsasliosize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.529 NAME 'ntUserMaxStorage' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.104 NAME ( 'passwordWarning' 'pwdExpireWarning' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.12 NAME 'memberUid' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2307' )", + "( nsAccessLog-oid NAME 'nsAccessLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2128 NAME 'dnaSecurePortNum' DESC 'DNA secure port number of replica to get new range of values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( nsPidLog-oid NAME 'nsPidLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2198 NAME 'nsslapd-auditlog-logexpirationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.570 NAME 'nsLookThroughLimit' DESC 'Binder-based search operation look through limit (candidate entries)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( nsCertfile-oid NAME 'nsCertfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.76 NAME 'serverHostName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.242 NAME 'nsSystemIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2177 NAME 'nsslapd-auditlog-logrotationsync-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2201 NAME 'nsslapd-auditlog-logexpirationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsServerCreationClassname-oid NAME 'nsServerCreationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.41 NAME 'ntUserDomainId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.219 NAME 'vlvUses' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.973 NAME 'nsds5ReplConflict' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.98 NAME 'passwordExp' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2248 NAME 'nsslapd-reservedescriptors' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2115 NAME 'dnaType' DESC 'DNA attribute type to maintain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.2227 NAME 'nsslapd-snmp-index' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.7 NAME 'shadowMax' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2185 NAME 'nsslapd-errorlog-logrotationtime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.63 NAME 'ntUserUnitsPerWeek' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2297 NAME 'nsslapd-search-return-original-type-switch' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2075 NAME ( 'passwordMinDigits' 'pwdMinDigits' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.4 NAME 'matchingRules' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.18.0.2.4.1123 NAME 'printer-sides-supported' DESC 'The number of impression sides (one or two) and the two-sided impression rotations supported by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.4.1.5923.1.1.1.3 NAME 'eduPersonOrgDN' DESC 'Organization DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.543 NAME 'nsState' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.85 NAME 'cirBindCredentials' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.42.2.27.4.1.12 NAME 'javaDoc' DESC 'The Java documentation for the class' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.2102 NAME 'autoMemberGroupingAttr' DESC 'Auto Membership grouping attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.808 NAME 'nsds5replicaLastInitEnd' DESC 'Netscape defined attribute type' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( nsUserIDFormat-oid NAME 'nsUserIDFormat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 0.9.2342.19200300.100.1.9 NAME 'host' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 4512' )", + "( nsAdminOneACLDir-oid NAME 'nsAdminOneACLDir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( nsBuildNumber-oid NAME 'nsBuildNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.13769.3.5 NAME 'mozillaHomePostalCode' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2149 NAME 'rootdn-allow-ip' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.2312.4.3.3.2 NAME 'sabayonProfileName' DESC 'The Name of a sabayon profile' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Sabayon' )", + "( 2.5.4.12 NAME 'title' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.17 NAME 'mailForwardingAddress' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.2120 NAME 'dnaFilter' DESC 'DNA filter for finding entries' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.223 NAME ( 'passwordResetFailureCount' 'pwdFailureCountInterval' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.49 NAME ( 'distinguishedName' 'dn' ) EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4519' X-DEPRECATED 'dn' )", + "( 2.16.840.1.113730.3.1.578 NAME 'nsDS5ReplicaHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2190 NAME 'nsslapd-accesslog-logmaxdiskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2232 NAME 'nsslapd-ldapimaptoentries' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.21.10 NAME 'governingStructureRule' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )", + "( 2.16.840.1.113730.3.1.2279 NAME 'nsslapd-ldifdir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1134 NAME 'printer-more-info' DESC 'A URI for more information about this specific printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 0.9.2342.19200300.100.1.25 NAME ( 'dc' 'domaincomponent' ) EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 4519' X-DEPRECATED 'domaincomponent' )", + "( 2.16.840.1.113730.3.1.1004 NAME 'nsds7WindowsDomain' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' DESC '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 X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.1.201 NAME 'changeLogMaximumSize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.13769.2.3 NAME ( 'mozillaUseHtmlMail' 'xmozillausehtmlmail' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( nsSerialNumber-oid NAME 'nsSerialNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.90 NAME 'cirBeginORC' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2240 NAME 'nsslapd-accesslog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2096 NAME 'entryusn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.694 NAME 'inetSubscriberAccountId' DESC 'A unique attribute linking the subscriber to a billing system' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape subscriber interoperability' )", + "( 1.3.18.0.2.4.1112 NAME 'printer-current-operator' DESC 'The identity of the current human operator responsible for operating this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.2306 NAME 'nsslapd-return-default-opattr' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 1.2.840.113556.1.4.478 NAME 'calCalURI' DESC 'RFC2739: URI of entire default calendar' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'rfc2739' )", + "( 2.16.840.1.113730.3.1.604 NAME 'parentid' DESC 'internal server defined attribute type' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113730.3.1.2154 NAME 'nsds5ReplicaBackoffMin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2266 NAME 'nsslapd-enquote-sup-oc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.524 NAME 'ntUserScriptPath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2133 NAME 'pwdUpdateTime' DESC 'Last password update time' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.22 NAME 'mgrpAllowedBroadcaster' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.236 NAME 'nsSNMPDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( nsPreference-oid NAME 'nsPreference' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.592 NAME 'nsDS5ReplicaAutoReferral' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2083 NAME ( 'passwordMinTokenLength' 'pwdMinTokenLength' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.689 NAME 'nsds5replicaUpdateInProgress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2204 NAME 'nsslapd-auditlog-logging-enabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1109 NAME 'printer-charset-configured' DESC 'The configured charset in which error and status messages will be generated (by default) by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.44 NAME 'ntGroupDomainId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.214 NAME 'passwordAllowChangeTime' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2141 NAME 'dsOnlyMemberUid' DESC 'Elements from a memberuid attribute created to reflect dynamic group membership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Red Hat Directory Server' )", + "( nsDirectoryFailoverList-oid NAME 'nsDirectoryFailoverList' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' )", + "( nsSSLSessionTimeout-oid NAME 'nsSSLSessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2253 NAME 'nsslapd-nagle' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2118 NAME 'dnaInterval' DESC 'DNA interval between values' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2188 NAME 'nsslapd-errorlog-logrotationtimeunit' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.66 NAME 'ntUserUniqueId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.1.2078 NAME ( 'passwordMinLowers' 'pwdMinLowers' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.587 NAME 'nsds50ruv' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2167 NAME 'schemaUpdateAttributeAccept' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2271 NAME 'nsslapd-rewrite-rfc1274' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.31 NAME 'mailEnhancedUniqueMember' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.209 NAME 'vlvFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )", + "( nsErrorLog-oid NAME 'nsErrorLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.88 NAME 'cirUpdateFailedat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.250 NAME 'nsValueDefault' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape servers - value item' )", + "( 2.5.4.37 NAME 'cACertificate' DESC 'X.509 CA certificate' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 4523' )", + "( 2.16.840.1.113730.3.1.2105 NAME 'autoMemberTargetGroup' DESC 'Auto Membership target group' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 1.3.6.1.4.1.6981.11.3.2 NAME 'FTPQuotaMBytes' DESC 'Quota (in megabytes) for an FTP user' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Pure-FTPd' )", + "( 2.16.840.1.113730.3.1.803 NAME 'nsBackendSuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2217 NAME 'nsslapd-allow-anonymous-access' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.53 NAME 'replicaBindMethod' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.4 NAME 'info' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.2065 NAME 'nsSaslMapBaseDNTemplate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsSSLSupportedCiphers-oid NAME 'nsSSLSupportedCiphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.2287 NAME 'nsslapd-force-sasl-external' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.197 NAME 'replicaHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.107 NAME 'passwordResetDuration' DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 0.9.2342.19200300.100.1.48 NAME 'buildingName' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2235 NAME 'nsslapd-ldapientrysearchbase' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( nsInstalledLocation-oid NAME 'nsInstalledLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.1.573 NAME 'nsIdleTimeout' DESC 'Binder-based connection idle timeout (seconds)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.75 NAME 'adminUrl' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.245 NAME 'nsValueTel' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 X-ORIGIN 'Netscape servers - value item' )", + "( 1.3.6.1.4.1.1466.101.120.42 NAME 'preferredLocale' DESC 'preferred locale for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape' )", + "( nsNYR-oid NAME 'nsNYR' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.1.2172 NAME 'nsslapd-accesslog-maxlogsize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1131 NAME 'printer-charset-supported' DESC 'Set of charsets supported for the attribute values of syntax DirectoryString for this directory entry.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'rfc3712' )", + "( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' DESC '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 X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.1.551 NAME 'cosspecifier' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.97 NAME ( 'passwordMaxAge' 'pwdMaxAge' ) DESC 'Netscape defined password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.4.22 NAME 'teletexTerminalIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2099 NAME 'autoMemberExclusiveRegex' DESC 'Auto Membership exclusive regex rule' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )", + "( 1.3.6.1.1.1.1.2 NAME 'gecos' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.1.2180 NAME 'nsslapd-auditlog-logrotationsynchour' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2222 NAME 'nsslapd-localuser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2309 NAME 'nsds5ReplicaPreciseTombstonePurging' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2292 NAME 'nsslapd-disk-monitoring-logging-critical' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2070 NAME 'pamIDMapMethod' DESC 'How to map BIND DN to PAM identity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.1.408 NAME 'replicaLastRelevantChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2269 NAME 'nsslapd-errorlog-list' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.18.0.2.4.1124 NAME 'printer-number-up-supported' DESC 'The possible numbers of print-stream pages to impose upon a single side of an instance of a selected medium.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'rfc3712' )", + "( 2.5.21.7 NAME 'nameForms' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 0.9.2342.19200300.100.1.55 NAME 'audio' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'RFC 1274' )", + "( 2.16.840.1.113730.3.1.29 NAME 'mgrpMsgRejectText' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.231 NAME 'nsslapd-pluginEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2136 NAME 'nsds5ReplicaCleanRUVNotified' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )", + "( nsWellKnownJarfiles-oid NAME 'nsWellKnownJarfiles' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE directoryOperation X-ORIGIN 'RFC 4512' )", + "( 2.16.840.1.113730.3.1.328 NAME 'nsMatchingRule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( nsAdminAccessHosts-oid NAME 'nsAdminAccessHosts' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' )", + "( 1.3.6.1.4.1.5923.1.1.1.6 NAME 'eduPersonPrincipalName' DESC 'Principal Name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 2.16.840.1.113730.3.1.80 NAME 'cirHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.42.2.27.4.1.11 NAME 'javaReferenceAddress' DESC 'Addresses associated with a JNDI Reference' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2713' )", + "( 2.16.840.1.113730.3.1.2086 NAME 'mepManagedBy' DESC 'Managed Entries backpointer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.1.684 NAME 'nsds5ReplicaChangeCount' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.1101 NAME 'nsRoleScopeDN' DESC 'Scope of a role' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 1.3.1.1.4.1.453.16.2.103 NAME 'numSubordinates' DESC 'count of immediate subordinates' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'numSubordinates Internet Draft' )", + "( 1.3.6.1.4.1.13769.3.6 NAME 'mozillaHomeCountryName' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Mozilla Address Book' )", + "( 2.16.840.1.113730.3.1.2144 NAME 'rootdn-open-time' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.9999999 NAME 'nsds5debugreplicatimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2256 NAME 'passwordLegacyPolicy' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 4512' )", + "( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.1.12 NAME 'mailAccessDomain' DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.1.226 NAME 'nsslapd-pluginType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.2123 NAME 'dnaSharedCfgDN' DESC 'DNA shared configuration entry DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN '389 Directory Server' )", + "( 2.5.4.44 NAME 'generationQualifier' SUP name EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113730.3.1.2193 NAME 'nsslapd-accesslog-logminfreediskspace' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.1.612 NAME 'generation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )" + ], + "cn": [ + "schema" + ], + "ldapSyntaxes": [ + "( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", + "( 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.26 DESC 'IA5String' )", + "( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", + "( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", + "( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", + "( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", + "( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )", + "( 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.23 DESC 'FAX' )", + "( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", + "( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", + "( 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' )", + "( 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.40 DESC 'OctetString' )", + "( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", + "( 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.50 DESC 'TelephoneNumber' )", + "( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", + "( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )" + ], + "matchingRules": [ + "( 2.5.13.17 NAME 'octetStringMatch' DESC 'The octetStringMatch rule compares an assertion value of the Octet String syntax to an attribute value of a syntax (e.g., the Octet String or JPEG syntax) whose corresponding ASN.1 type is the OCTET STRING ASN.1 type. The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same length and corresponding octets (by position) are the same.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + "( 2.5.13.18 NAME 'octetStringOrderingMatch' DESC 'The octetStringOrderingMatch rule compares an assertion value of the Octet String syntax to an attribute value of a syntax (e.g., the Octet String or JPEG syntax) whose corresponding ASN.1 type is the OCTET STRING ASN.1 type. The rule evaluates to TRUE if and only if the attribute value appears earlier in the collation order than the assertion value. The rule compares octet strings from the first octet to the last octet, and from the most significant bit to the least significant bit within the octet. The first occurrence of a different bit determines the ordering of the strings. A zero bit precedes a one bit. If the strings contain different numbers of octets but the longer string is identical to the shorter string up to the length of the shorter string, then the shorter string precedes the longer string.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + "( 2.5.13.16 NAME 'bitStringMatch' DESC 'The bitStringMatch rule compares an assertion value of the Bit String syntax to an attribute value of a syntax (e.g., the Bit String syntax) whose corresponding ASN.1 type is BIT STRING. If the corresponding ASN.1 type of the attribute syntax does not have a named bit list [ASN.1] (which is the case for the Bit String syntax), then the rule evaluates to TRUE if and only if the attribute value has the same number of bits as the assertion value and the bits match on a bitwise basis. If the corresponding ASN.1 type does have a named bit list, then bitStringMatch operates as above, except that trailing zero bits in the attribute and assertion values are treated as absent.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", + "( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' DESC 'The caseExactIA5Match rule compares an assertion value of the IA5 String syntax to an attribute value of a syntax (e.g., the IA5 String syntax) whose corresponding ASN.1 type is IA5String. The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point. In preparing the attribute value and assertion value for comparison, characters are not case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", + "( 2.5.13.5 NAME 'caseExactMatch' DESC 'The caseExactMatch rule compares an assertion value of the Directory String syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of the alternative string types of DirectoryString, such as PrintableString (the other alternatives do not correspond to any syntax defined in this document). The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point. In preparing the attribute value and assertion value for comparison, characters are not case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.6 NAME 'caseExactOrderingMatch' DESC 'The caseExactOrderingMatch rule compares an assertion value of the Directory String syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of its alternative string types. The rule evaluates to TRUE if and only if, in the code point collation order, the prepared attribute value character string appears earlier than the prepared assertion value character string; i.e., the attribute value is \\"less than\\" the assertion value. In preparing the attribute value and assertion value for comparison, characters are not case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.7 NAME 'caseExactSubstringsMatch' DESC 'The caseExactSubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of its alternative string types. The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value character string in the order of the substrings in the assertion value, (2) an substring, if present, matches the beginning of the prepared attribute value character string, and (3) a substring, if present, matches the end of the prepared attribute value character string. A prepared substring matches a portion of the prepared attribute value character string if corresponding characters have the same code point. In preparing the attribute value and assertion value substrings for comparison, characters are not case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.16.840.1.113730.3.3.1 NAME 'caseExactIA5SubstringsMatch' DESC 'The caseExactIA5SubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the IA5 syntax) whose corresponding ASN.1 type is IA5 String or one of its alternative string types. The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value character string in the order of the substrings in the assertion value, (2) an substring, if present, matches the beginning of the prepared attribute value character string, and (3) a substring, if present, matches the end of the prepared attribute value character string. A prepared substring matches a portion of the prepared attribute value character string if corresponding characters have the same code point. In preparing the attribute value and assertion value substrings for comparison, characters are not case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.5.13.27 NAME 'generalizedTimeMatch' DESC 'The rule evaluates to TRUE if and only if the attribute value represents the same universal coordinated time as the assertion value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", + "( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' DESC 'The rule evaluates to TRUE if and only if the attribute value represents a universal coordinated time that is earlier than the universal coordinated time represented by the assertion value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", + "( 2.5.13.13 NAME 'booleanMatch' DESC 'The booleanMatch rule compares an assertion value of the Boolean syntax to an attribute value of a syntax (e.g., the Boolean syntax) whose corresponding ASN.1 type is BOOLEAN. The rule evaluates to TRUE if and only if the attribute value and the assertion value are both TRUE or both FALSE.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", + "( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' DESC 'The caseIgnoreIA5Match rule compares an assertion value of the IA5 String syntax to an attribute value of a syntax (e.g., the IA5 String syntax) whose corresponding ASN.1 type is IA5String. The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point. In preparing the attribute value and assertion value for comparison, characters are case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", + "( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' DESC 'The caseIgnoreIA5SubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the IA5 String syntax) whose corresponding ASN.1 type is IA5String. The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value character string in the order of the substrings in the assertion value, (2) an substring, if present, matches the beginning of the prepared attribute value character string, and (3) a substring, if present, matches the end of the prepared attribute value character string. A prepared substring matches a portion of the prepared attribute value character string if corresponding characters have the same code point. In preparing the attribute value and assertion value substrings for comparison, characters are case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.5.13.2 NAME 'caseIgnoreMatch' DESC 'The caseIgnoreMatch rule compares an assertion value of the Directory String syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of its alternative string types. The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point. In preparing the attribute value and assertion value for comparison, characters are case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' DESC 'The caseIgnoreOrderingMatch rule compares an assertion value of the Directory String syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of its alternative string types. The rule evaluates to TRUE if and only if, in the code point collation order, the prepared attribute value character string appears earlier than the prepared assertion value character string; i.e., the attribute value is \\"less than\\" the assertion value. In preparing the attribute value and assertion value for comparison, characters are case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' DESC 'The caseIgnoreSubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the Directory String, Printable String, Country String, or Telephone Number syntax) whose corresponding ASN.1 type is DirectoryString or one of its alternative string types. The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value character string in the order of the substrings in the assertion value, (2) an substring, if present, matches the beginning of the prepared attribute value character string, and (3) a substring, if present, matches the end of the prepared attribute value character string. A prepared substring matches a portion of the prepared attribute value character string if corresponding characters have the same code point. In preparing the attribute value and assertion value substrings for comparison, characters are case folded in the Map preparation step, and only Insignificant Space Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.5.13.11 NAME 'caseIgnoreListMatch' DESC 'The caseIgnoreListMatch rule compares an assertion value that is a sequence of strings to an attribute value of a syntax (e.g., the Postal Address syntax) whose corresponding ASN.1 type is a SEQUENCE OF the DirectoryString ASN.1 type. The rule evaluates to TRUE if and only if the attribute value and the assertion value have the same number of strings and corresponding strings (by position) match according to the caseIgnoreMatch matching rule. In [X.520], the assertion syntax for this matching rule is defined to be: SEQUENCE OF DirectoryString {ub-match} That is, it is different from the corresponding type for the Postal Address syntax. The choice of the Postal Address syntax for the assertion syntax of the caseIgnoreListMatch in LDAP should not be seen as limiting the matching rule to apply only to attributes with the Postal Address syntax.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", + "( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' DESC 'The caseIgnoreListSubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the Postal Address syntax) whose corresponding ASN.1 type is a SEQUENCE OF the DirectoryString ASN.1 type. The rule evaluates to TRUE if and only if the assertion value matches, per the caseIgnoreSubstringsMatch rule, the character string formed by concatenating the strings of the attribute value, except that none of the , , or substrings of the assertion value are considered to match a substring of the concatenated string which spans more than one of the original strings of the attribute value. Note that, in terms of the LDAP-specific encoding of the Postal Address syntax, the concatenated string omits the line separator and the escaping of \\"\\\\\\" and \\"$\\" characters.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.5.13.0 NAME 'objectIdentifierMatch' DESC 'The objectIdentifierMatch rule compares an assertion value of the OID syntax to an attribute value of a syntax (e.g., the OID syntax) whose corresponding ASN.1 type is OBJECT IDENTIFIER. The rule evaluates to TRUE if and only if the assertion value and the attribute value represent the same object identifier; that is, the same sequence of integers, whether represented explicitly in the form of or implicitly in the form (see [RFC4512]). If an LDAP client supplies an assertion value in the form and the chosen descriptor is not recognized by the server, then the objectIdentifierMatch rule evaluates to Undefined.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + "( 2.5.13.31 NAME 'directoryStringFirstComponentMatch' DESC 'The directoryStringFirstComponentMatch rule compares an assertion value of the Directory String syntax to an attribute value of a syntax whose corresponding ASN.1 type is a SEQUENCE with a mandatory first component of the DirectoryString ASN.1 type. Note that the assertion syntax of this matching rule differs from the attribute syntax of attributes for which this is the equality matching rule. The rule evaluates to TRUE if and only if the assertion value matches the first component of the attribute value using the rules of caseIgnoreMatch.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' DESC 'The objectIdentifierFirstComponentMatch rule compares an assertion value of the OID syntax to an attribute value of a syntax (e.g., the Attribute Type Description, DIT Content Rule Description, LDAP Syntax Description, Matching Rule Description, Matching Rule Use Description, Name Form Description, or Object Class Description syntax) whose corresponding ASN.1 type is a SEQUENCE with a mandatory first component of the OBJECT IDENTIFIER ASN.1 type. Note that the assertion syntax of this matching rule differs from the attribute syntax of attributes for which this is the equality matching rule. The rule evaluates to TRUE if and only if the assertion value matches the first component of the attribute value using the rules of objectIdentifierMatch.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", + "( 2.5.13.1 NAME 'distinguishedNameMatch' DESC 'The distinguishedNameMatch rule compares an assertion value of the DN syntax to an attribute value of a syntax (e.g., the DN syntax) whose corresponding ASN.1 type is DistinguishedName. The rule evaluates to TRUE if and only if the attribute value and the assertion value have the same number of relative distinguished names and corresponding relative distinguished names (by position) are the same. A relative distinguished name (RDN) of the assertion value is the same as an RDN of the attribute value if and only if they have the same number of attribute value assertions and each attribute value assertion (AVA) of the first RDN is the same as the AVA of the second RDN with the same attribute type. The order of the AVAs is not significant. Also note that a particular attribute type may appear in at most one AVA in an RDN. Two AVAs with the same attribute type are the same if their values are equal according to the equality matching rule of the attribute type. If one or more of the AVA comparisons evaluate to Undefined and the remaining AVA comparisons return TRUE then the distinguishedNameMatch rule evaluates to Undefined.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.5.13.14 NAME 'integerMatch' DESC 'The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same integer value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", + "( 2.5.13.15 NAME 'integerOrderingMatch' DESC 'The rule evaluates to TRUE if and only if the integer value of the attribute value is less than the integer value of the assertion value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", + "( 2.5.13.29 NAME 'integerFirstComponentMatch' DESC 'The integerFirstComponentMatch rule compares an assertion value of the Integer syntax to an attribute value of a syntax (e.g., the DIT Structure Rule Description syntax) whose corresponding ASN.1 type is a SEQUENCE with a mandatory first component of the INTEGER ASN.1 type. Note that the assertion syntax of this matching rule differs from the attribute syntax of attributes for which this is the equality matching rule. The rule evaluates to TRUE if and only if the assertion value and the first component of the attribute value are the same integer value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", + "( 2.16.840.1.113730.3.3.2.0.1 NAME 'caseIgnoreOrderingMatch-default' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.0.1.6 NAME 'caseIgnoreSubstringMatch-default' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.1.1 NAME 'caseIgnoreOrderingMatch-ar' DESC 'ar' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.1.1.6 NAME 'caseIgnoreSubstringMatch-ar' DESC 'ar' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.2.1 NAME 'caseIgnoreOrderingMatch-be' DESC 'be' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.2.1.6 NAME 'caseIgnoreSubstringMatch-be' DESC 'be' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.3.1 NAME 'caseIgnoreOrderingMatch-bg' DESC 'bg' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.3.1.6 NAME 'caseIgnoreSubstringMatch-bg' DESC 'bg' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.4.1 NAME 'caseIgnoreOrderingMatch-ca' DESC 'ca' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.4.1.6 NAME 'caseIgnoreSubstringMatch-ca' DESC 'ca' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.5.1 NAME 'caseIgnoreOrderingMatch-cs' DESC 'cs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.5.1.6 NAME 'caseIgnoreSubstringMatch-cs' DESC 'cs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.6.1 NAME 'caseIgnoreOrderingMatch-da' DESC 'da' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.6.1.6 NAME 'caseIgnoreSubstringMatch-da' DESC 'da' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.7.1 NAME 'caseIgnoreOrderingMatch-de' DESC 'de' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.7.1.6 NAME 'caseIgnoreSubstringMatch-de' DESC 'de' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.8.1 NAME 'caseIgnoreOrderingMatch-de-AT' DESC 'de-AT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.8.1.6 NAME 'caseIgnoreSubstringMatch-de-AT' DESC 'de-AT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.9.1 NAME 'caseIgnoreOrderingMatch-de-CH' DESC 'de-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.9.1.6 NAME 'caseIgnoreSubstringMatch-de-CH' DESC 'de-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.10.1 NAME 'caseIgnoreOrderingMatch-el' DESC 'el' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.10.1.6 NAME 'caseIgnoreSubstringMatch-el' DESC 'el' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.11.1 NAME 'caseIgnoreOrderingMatch-en' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.11.1.6 NAME 'caseIgnoreSubstringMatch-en' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.12.1 NAME 'caseIgnoreOrderingMatch-en-CA' DESC 'en-CA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.12.1.6 NAME 'caseIgnoreSubstringMatch-en-CA' DESC 'en-CA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.13.1 NAME 'caseIgnoreOrderingMatch-en-GB' DESC 'en-GB' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.13.1.6 NAME 'caseIgnoreSubstringMatch-en-GB' DESC 'en-GB' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.14.1 NAME 'caseIgnoreOrderingMatch-en-IE' DESC 'en-IE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.14.1.6 NAME 'caseIgnoreSubstringMatch-en-IE' DESC 'en-IE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.15.1 NAME 'caseIgnoreOrderingMatch-es' DESC 'es' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.15.1.6 NAME 'caseIgnoreSubstringMatch-es' DESC 'es' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.16.1 NAME 'caseIgnoreOrderingMatch-et' DESC 'et' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.16.1.6 NAME 'caseIgnoreSubstringMatch-et' DESC 'et' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.17.1 NAME 'caseIgnoreOrderingMatch-fi' DESC 'fi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.17.1.6 NAME 'caseIgnoreSubstringMatch-fi' DESC 'fi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.18.1 NAME 'caseIgnoreOrderingMatch-fr' DESC 'fr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.18.1.6 NAME 'caseIgnoreSubstringMatch-fr' DESC 'fr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.19.1 NAME 'caseIgnoreOrderingMatch-fr-BE' DESC 'fr-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.19.1.6 NAME 'caseIgnoreSubstringMatch-fr-BE' DESC 'fr-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.20.1 NAME 'caseIgnoreOrderingMatch-fr-CA' DESC 'fr-CA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.20.1.6 NAME 'caseIgnoreSubstringMatch-fr-CA' DESC 'fr-CA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.21.1 NAME 'caseIgnoreOrderingMatch-fr-CH' DESC 'fr-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.21.1.6 NAME 'caseIgnoreSubstringMatch-fr-CH' DESC 'fr-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.22.1 NAME 'caseIgnoreOrderingMatch-hr' DESC 'hr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.22.1.6 NAME 'caseIgnoreSubstringMatch-hr' DESC 'hr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.23.1 NAME 'caseIgnoreOrderingMatch-hu' DESC 'hu' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.23.1.6 NAME 'caseIgnoreSubstringMatch-hu' DESC 'hu' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.24.1 NAME 'caseIgnoreOrderingMatch-is' DESC 'is' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.24.1.6 NAME 'caseIgnoreSubstringMatch-is' DESC 'is' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.25.1 NAME 'caseIgnoreOrderingMatch-it' DESC 'it' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.25.1.6 NAME 'caseIgnoreSubstringMatch-it' DESC 'it' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.26.1 NAME 'caseIgnoreOrderingMatch-it-CH' DESC 'it-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.26.1.6 NAME 'caseIgnoreSubstringMatch-it-CH' DESC 'it-CH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.27.1 NAME 'caseIgnoreOrderingMatch-iw' DESC 'iw' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.27.1.6 NAME 'caseIgnoreSubstringMatch-iw' DESC 'iw' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.28.1 NAME 'caseIgnoreOrderingMatch-ja' DESC 'ja' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.28.1.6 NAME 'caseIgnoreSubstringMatch-ja' DESC 'ja' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.29.1 NAME 'caseIgnoreOrderingMatch-ko' DESC 'ko' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.29.1.6 NAME 'caseIgnoreSubstringMatch-ko' DESC 'ko' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.30.1 NAME 'caseIgnoreOrderingMatch-lt' DESC 'lt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.30.1.6 NAME 'caseIgnoreSubstringMatch-lt' DESC 'lt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.31.1 NAME 'caseIgnoreOrderingMatch-lv' DESC 'lv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.31.1.6 NAME 'caseIgnoreSubstringMatch-lv' DESC 'lv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.32.1 NAME 'caseIgnoreOrderingMatch-mk' DESC 'mk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.32.1.6 NAME 'caseIgnoreSubstringMatch-mk' DESC 'mk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.33.1 NAME 'caseIgnoreOrderingMatch-nl' DESC 'nl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.33.1.6 NAME 'caseIgnoreSubstringMatch-nl' DESC 'nl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.34.1 NAME 'caseIgnoreOrderingMatch-nl-BE' DESC 'nl-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.34.1.6 NAME 'caseIgnoreSubstringMatch-nl-BE' DESC 'nl-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.35.1 NAME 'caseIgnoreOrderingMatch-no' DESC 'no' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.35.1.6 NAME 'caseIgnoreSubstringMatch-no' DESC 'no' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.36.1 NAME 'caseIgnoreOrderingMatch-no-NO-B' DESC 'no-NO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.36.1.6 NAME 'caseIgnoreSubstringMatch-no-NO-B' DESC 'no-NO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.37.1 NAME 'caseIgnoreOrderingMatch-no-NO-NY' DESC 'no-NO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.37.1.6 NAME 'caseIgnoreSubstringMatch-no-NO-NY' DESC 'no-NO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.38.1 NAME 'caseIgnoreOrderingMatch-pl' DESC 'pl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.38.1.6 NAME 'caseIgnoreSubstringMatch-pl' DESC 'pl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.39.1 NAME 'caseIgnoreOrderingMatch-ro' DESC 'ro' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.39.1.6 NAME 'caseIgnoreSubstringMatch-ro' DESC 'ro' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.40.1 NAME 'caseIgnoreOrderingMatch-ru' DESC 'ru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.40.1.6 NAME 'caseIgnoreSubstringMatch-ru' DESC 'ru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.41.1 NAME 'caseIgnoreOrderingMatch-sh' DESC 'sh' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.41.1.6 NAME 'caseIgnoreSubstringMatch-sh' DESC 'sh' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.42.1 NAME 'caseIgnoreOrderingMatch-sk' DESC 'sk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.42.1.6 NAME 'caseIgnoreSubstringMatch-sk' DESC 'sk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.43.1 NAME 'caseIgnoreOrderingMatch-sl' DESC 'sl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.43.1.6 NAME 'caseIgnoreSubstringMatch-sl' DESC 'sl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.44.1 NAME 'caseIgnoreOrderingMatch-sq' DESC 'sq' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.44.1.6 NAME 'caseIgnoreSubstringMatch-sq' DESC 'sq' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.45.1 NAME 'caseIgnoreOrderingMatch-sr' DESC 'sr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.45.1.6 NAME 'caseIgnoreSubstringMatch-sr' DESC 'sr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.46.1 NAME 'caseIgnoreOrderingMatch-sv' DESC 'sv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.46.1.6 NAME 'caseIgnoreSubstringMatch-sv' DESC 'sv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.47.1 NAME 'caseIgnoreOrderingMatch-tr' DESC 'tr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.47.1.6 NAME 'caseIgnoreSubstringMatch-tr' DESC 'tr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.48.1 NAME 'caseIgnoreOrderingMatch-uk' DESC 'uk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.48.1.6 NAME 'caseIgnoreSubstringMatch-uk' DESC 'uk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.49.1 NAME 'caseIgnoreOrderingMatch-zh' DESC 'zh' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.49.1.6 NAME 'caseIgnoreSubstringMatch-zh' DESC 'zh' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.50.1 NAME 'caseIgnoreOrderingMatch-zh-TW' DESC 'zh-TW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.50.1.6 NAME 'caseIgnoreSubstringMatch-zh-TW' DESC 'zh-TW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.51.1 NAME 'caseIgnoreOrderingMatch-af' DESC 'af' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.51.1.6 NAME 'caseIgnoreSubstringMatch-af' DESC 'af' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.52.1 NAME 'caseIgnoreOrderingMatch-af-NA' DESC 'af-NA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.52.1.6 NAME 'caseIgnoreSubstringMatch-af-NA' DESC 'af-NA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.53.1 NAME 'caseIgnoreOrderingMatch-af-ZA' DESC 'af-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.53.1.6 NAME 'caseIgnoreSubstringMatch-af-ZA' DESC 'af-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.54.1 NAME 'caseIgnoreOrderingMatch-ar-AE' DESC 'ar-AE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.54.1.6 NAME 'caseIgnoreSubstringMatch-ar-AE' DESC 'ar-AE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.55.1 NAME 'caseIgnoreOrderingMatch-ar-BH' DESC 'ar-BH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.55.1.6 NAME 'caseIgnoreSubstringMatch-ar-BH' DESC 'ar-BH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.56.1 NAME 'caseIgnoreOrderingMatch-ar-DZ' DESC 'ar-DZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.56.1.6 NAME 'caseIgnoreSubstringMatch-ar-DZ' DESC 'ar-DZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.57.1 NAME 'caseIgnoreOrderingMatch-ar-EG' DESC 'ar-EG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.57.1.6 NAME 'caseIgnoreSubstringMatch-ar-EG' DESC 'ar-EG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.58.1 NAME 'caseIgnoreOrderingMatch-ar-IQ' DESC 'ar-IQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.58.1.6 NAME 'caseIgnoreSubstringMatch-ar-IQ' DESC 'ar-IQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.59.1 NAME 'caseIgnoreOrderingMatch-ar-JO' DESC 'ar-JO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.59.1.6 NAME 'caseIgnoreSubstringMatch-ar-JO' DESC 'ar-JO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.60.1 NAME 'caseIgnoreOrderingMatch-ar-KW' DESC 'ar-KW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.60.1.6 NAME 'caseIgnoreSubstringMatch-ar-KW' DESC 'ar-KW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.61.1 NAME 'caseIgnoreOrderingMatch-ar-LB' DESC 'ar-LB' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.61.1.6 NAME 'caseIgnoreSubstringMatch-ar-LB' DESC 'ar-LB' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.62.1 NAME 'caseIgnoreOrderingMatch-ar-LY' DESC 'ar-LY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.62.1.6 NAME 'caseIgnoreSubstringMatch-ar-LY' DESC 'ar-LY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.63.1 NAME 'caseIgnoreOrderingMatch-ar-MA' DESC 'ar-MA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.63.1.6 NAME 'caseIgnoreSubstringMatch-ar-MA' DESC 'ar-MA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.64.1 NAME 'caseIgnoreOrderingMatch-ar-OM' DESC 'ar-OM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.64.1.6 NAME 'caseIgnoreSubstringMatch-ar-OM' DESC 'ar-OM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.65.1 NAME 'caseIgnoreOrderingMatch-ar-QA' DESC 'ar-QA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.65.1.6 NAME 'caseIgnoreSubstringMatch-ar-QA' DESC 'ar-QA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.66.1 NAME 'caseIgnoreOrderingMatch-ar-SA' DESC 'ar-SA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.66.1.6 NAME 'caseIgnoreSubstringMatch-ar-SA' DESC 'ar-SA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.67.1 NAME 'caseIgnoreOrderingMatch-ar-SD' DESC 'ar-SD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.67.1.6 NAME 'caseIgnoreSubstringMatch-ar-SD' DESC 'ar-SD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.68.1 NAME 'caseIgnoreOrderingMatch-ar-SY' DESC 'ar-SY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.68.1.6 NAME 'caseIgnoreSubstringMatch-ar-SY' DESC 'ar-SY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.69.1 NAME 'caseIgnoreOrderingMatch-ar-TN' DESC 'ar-TN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.69.1.6 NAME 'caseIgnoreSubstringMatch-ar-TN' DESC 'ar-TN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.70.1 NAME 'caseIgnoreOrderingMatch-ar-YE' DESC 'ar-YE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.70.1.6 NAME 'caseIgnoreSubstringMatch-ar-YE' DESC 'ar-YE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.71.1 NAME 'caseIgnoreOrderingMatch-as' DESC 'as' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.71.1.6 NAME 'caseIgnoreSubstringMatch-as' DESC 'as' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.72.1 NAME 'caseIgnoreOrderingMatch-as-IN' DESC 'as-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.72.1.6 NAME 'caseIgnoreSubstringMatch-as-IN' DESC 'as-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.73.1 NAME 'caseIgnoreOrderingMatch-az' DESC 'az' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.73.1.6 NAME 'caseIgnoreSubstringMatch-az' DESC 'az' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.74.1 NAME 'caseIgnoreOrderingMatch-az-Latn' DESC 'az-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.74.1.6 NAME 'caseIgnoreSubstringMatch-az-Latn' DESC 'az-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.75.1 NAME 'caseIgnoreOrderingMatch-az-Latn-AZ' DESC 'az-Latn_AZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.75.1.6 NAME 'caseIgnoreSubstringMatch-az-Latn-AZ' DESC 'az-Latn_AZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.76.1 NAME 'caseIgnoreOrderingMatch-bn' DESC 'bn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.76.1.6 NAME 'caseIgnoreSubstringMatch-bn' DESC 'bn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.77.1 NAME 'caseIgnoreOrderingMatch-bn-BD' DESC 'bn-BD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.77.1.6 NAME 'caseIgnoreSubstringMatch-bn-BD' DESC 'bn-BD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.78.1 NAME 'caseIgnoreOrderingMatch-bn-IN' DESC 'bn-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.78.1.6 NAME 'caseIgnoreSubstringMatch-bn-IN' DESC 'bn-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.79.1 NAME 'caseIgnoreOrderingMatch-bs' DESC 'bs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.79.1.6 NAME 'caseIgnoreSubstringMatch-bs' DESC 'bs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.80.1 NAME 'caseIgnoreOrderingMatch-chr' DESC 'chr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.80.1.6 NAME 'caseIgnoreSubstringMatch-chr' DESC 'chr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.81.1 NAME 'caseIgnoreOrderingMatch-chr-US' DESC 'chr-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.81.1.6 NAME 'caseIgnoreSubstringMatch-chr-US' DESC 'chr-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.82.1 NAME 'caseIgnoreOrderingMatch-cy' DESC 'cy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.82.1.6 NAME 'caseIgnoreSubstringMatch-cy' DESC 'cy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.83.1 NAME 'caseIgnoreOrderingMatch-de-BE' DESC 'de-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.83.1.6 NAME 'caseIgnoreSubstringMatch-de-BE' DESC 'de-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.84.1 NAME 'caseIgnoreOrderingMatch-de-LI' DESC 'de-LI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.84.1.6 NAME 'caseIgnoreSubstringMatch-de-LI' DESC 'de-LI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.85.1 NAME 'caseIgnoreOrderingMatch-de-LU' DESC 'de-LU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.85.1.6 NAME 'caseIgnoreSubstringMatch-de-LU' DESC 'de-LU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.86.1 NAME 'caseIgnoreOrderingMatch-el-CY' DESC 'el-CY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.86.1.6 NAME 'caseIgnoreSubstringMatch-el-CY' DESC 'el-CY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.87.1 NAME 'caseIgnoreOrderingMatch-el-GR' DESC 'el-GR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.87.1.6 NAME 'caseIgnoreSubstringMatch-el-GR' DESC 'el-GR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.88.1 NAME 'caseIgnoreOrderingMatch-en-AS' DESC 'en-AS' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.88.1.6 NAME 'caseIgnoreSubstringMatch-en-AS' DESC 'en-AS' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.89.1 NAME 'caseIgnoreOrderingMatch-en-AU' DESC 'en-AU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.89.1.6 NAME 'caseIgnoreSubstringMatch-en-AU' DESC 'en-AU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.90.1 NAME 'caseIgnoreOrderingMatch-en-BE' DESC 'en-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.90.1.6 NAME 'caseIgnoreSubstringMatch-en-BE' DESC 'en-BE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.91.1 NAME 'caseIgnoreOrderingMatch-en-BW' DESC 'en-BW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.91.1.6 NAME 'caseIgnoreSubstringMatch-en-BW' DESC 'en-BW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.92.1 NAME 'caseIgnoreOrderingMatch-en-BZ' DESC 'en-BZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.92.1.6 NAME 'caseIgnoreSubstringMatch-en-BZ' DESC 'en-BZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.93.1 NAME 'caseIgnoreOrderingMatch-en-GU' DESC 'en-GU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.93.1.6 NAME 'caseIgnoreSubstringMatch-en-GU' DESC 'en-GU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.94.1 NAME 'caseIgnoreOrderingMatch-en-GY' DESC 'en-GY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.94.1.6 NAME 'caseIgnoreSubstringMatch-en-GY' DESC 'en-GY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.95.1 NAME 'caseIgnoreOrderingMatch-en-HK' DESC 'en-HK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.95.1.6 NAME 'caseIgnoreSubstringMatch-en-HK' DESC 'en-HK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.96.1 NAME 'caseIgnoreOrderingMatch-en-IN' DESC 'en-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.96.1.6 NAME 'caseIgnoreSubstringMatch-en-IN' DESC 'en-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.97.1 NAME 'caseIgnoreOrderingMatch-en-JM' DESC 'en-JM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.97.1.6 NAME 'caseIgnoreSubstringMatch-en-JM' DESC 'en-JM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.98.1 NAME 'caseIgnoreOrderingMatch-en-MH' DESC 'en-MH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.98.1.6 NAME 'caseIgnoreSubstringMatch-en-MH' DESC 'en-MH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.99.1 NAME 'caseIgnoreOrderingMatch-en-MP' DESC 'en-MP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.99.1.6 NAME 'caseIgnoreSubstringMatch-en-MP' DESC 'en-MP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.100.1 NAME 'caseIgnoreOrderingMatch-en-MT' DESC 'en-MT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.100.1.6 NAME 'caseIgnoreSubstringMatch-en-MT' DESC 'en-MT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.101.1 NAME 'caseIgnoreOrderingMatch-en-MU' DESC 'en-MU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.101.1.6 NAME 'caseIgnoreSubstringMatch-en-MU' DESC 'en-MU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.102.1 NAME 'caseIgnoreOrderingMatch-en-NA' DESC 'en-NA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.102.1.6 NAME 'caseIgnoreSubstringMatch-en-NA' DESC 'en-NA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.103.1 NAME 'caseIgnoreOrderingMatch-en-NZ' DESC 'en-NZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.103.1.6 NAME 'caseIgnoreSubstringMatch-en-NZ' DESC 'en-NZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.104.1 NAME 'caseIgnoreOrderingMatch-en-PH' DESC 'en-PH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.104.1.6 NAME 'caseIgnoreSubstringMatch-en-PH' DESC 'en-PH' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.105.1 NAME 'caseIgnoreOrderingMatch-en-PK' DESC 'en-PK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.105.1.6 NAME 'caseIgnoreSubstringMatch-en-PK' DESC 'en-PK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.106.1 NAME 'caseIgnoreOrderingMatch-en-SG' DESC 'en-SG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.106.1.6 NAME 'caseIgnoreSubstringMatch-en-SG' DESC 'en-SG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.107.1 NAME 'caseIgnoreOrderingMatch-en-TT' DESC 'en-TT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.107.1.6 NAME 'caseIgnoreSubstringMatch-en-TT' DESC 'en-TT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.108.1 NAME 'caseIgnoreOrderingMatch-en-UM' DESC 'en-UM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.108.1.6 NAME 'caseIgnoreSubstringMatch-en-UM' DESC 'en-UM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.109.1 NAME 'caseIgnoreOrderingMatch-en-US' DESC 'en-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.109.1.6 NAME 'caseIgnoreSubstringMatch-en-US' DESC 'en-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.110.1 NAME 'caseIgnoreOrderingMatch-en-US-POSIX' DESC 'en-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.110.1.6 NAME 'caseIgnoreSubstringMatch-en-US-POSIX' DESC 'en-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.111.1 NAME 'caseIgnoreOrderingMatch-en-VI' DESC 'en-VI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.111.1.6 NAME 'caseIgnoreSubstringMatch-en-VI' DESC 'en-VI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.112.1 NAME 'caseIgnoreOrderingMatch-en-ZA' DESC 'en-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.112.1.6 NAME 'caseIgnoreSubstringMatch-en-ZA' DESC 'en-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.113.1 NAME 'caseIgnoreOrderingMatch-en-ZW' DESC 'en-ZW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.113.1.6 NAME 'caseIgnoreSubstringMatch-en-ZW' DESC 'en-ZW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.114.1 NAME 'caseIgnoreOrderingMatch-es-AR' DESC 'es-AR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.114.1.6 NAME 'caseIgnoreSubstringMatch-es-AR' DESC 'es-AR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.115.1 NAME 'caseIgnoreOrderingMatch-es-BO' DESC 'es-BO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.115.1.6 NAME 'caseIgnoreSubstringMatch-es-BO' DESC 'es-BO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.116.1 NAME 'caseIgnoreOrderingMatch-es-CL' DESC 'es-CL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.116.1.6 NAME 'caseIgnoreSubstringMatch-es-CL' DESC 'es-CL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.117.1 NAME 'caseIgnoreOrderingMatch-es-CO' DESC 'es-CO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.117.1.6 NAME 'caseIgnoreSubstringMatch-es-CO' DESC 'es-CO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.118.1 NAME 'caseIgnoreOrderingMatch-es-CR' DESC 'es-CR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.118.1.6 NAME 'caseIgnoreSubstringMatch-es-CR' DESC 'es-CR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.119.1 NAME 'caseIgnoreOrderingMatch-es-DO' DESC 'es-DO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.119.1.6 NAME 'caseIgnoreSubstringMatch-es-DO' DESC 'es-DO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.120.1 NAME 'caseIgnoreOrderingMatch-es-EC' DESC 'es-EC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.120.1.6 NAME 'caseIgnoreSubstringMatch-es-EC' DESC 'es-EC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.121.1 NAME 'caseIgnoreOrderingMatch-es-ES' DESC 'es-ES' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.121.1.6 NAME 'caseIgnoreSubstringMatch-es-ES' DESC 'es-ES' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.122.1 NAME 'caseIgnoreOrderingMatch-es-GQ' DESC 'es-GQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.122.1.6 NAME 'caseIgnoreSubstringMatch-es-GQ' DESC 'es-GQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.123.1 NAME 'caseIgnoreOrderingMatch-es-GT' DESC 'es-GT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.123.1.6 NAME 'caseIgnoreSubstringMatch-es-GT' DESC 'es-GT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.124.1 NAME 'caseIgnoreOrderingMatch-es-HN' DESC 'es-HN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.124.1.6 NAME 'caseIgnoreSubstringMatch-es-HN' DESC 'es-HN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.125.1 NAME 'caseIgnoreOrderingMatch-es-MX' DESC 'es-MX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.125.1.6 NAME 'caseIgnoreSubstringMatch-es-MX' DESC 'es-MX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.126.1 NAME 'caseIgnoreOrderingMatch-es-NI' DESC 'es-NI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.126.1.6 NAME 'caseIgnoreSubstringMatch-es-NI' DESC 'es-NI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.127.1 NAME 'caseIgnoreOrderingMatch-es-PA' DESC 'es-PA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.127.1.6 NAME 'caseIgnoreSubstringMatch-es-PA' DESC 'es-PA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.128.1 NAME 'caseIgnoreOrderingMatch-es-PE' DESC 'es-PE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.128.1.6 NAME 'caseIgnoreSubstringMatch-es-PE' DESC 'es-PE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.129.1 NAME 'caseIgnoreOrderingMatch-es-PR' DESC 'es-PR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.129.1.6 NAME 'caseIgnoreSubstringMatch-es-PR' DESC 'es-PR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.130.1 NAME 'caseIgnoreOrderingMatch-es-PY' DESC 'es-PY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.130.1.6 NAME 'caseIgnoreSubstringMatch-es-PY' DESC 'es-PY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.131.1 NAME 'caseIgnoreOrderingMatch-es-SV' DESC 'es-SV' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.131.1.6 NAME 'caseIgnoreSubstringMatch-es-SV' DESC 'es-SV' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.132.1 NAME 'caseIgnoreOrderingMatch-es-US' DESC 'es-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.132.1.6 NAME 'caseIgnoreSubstringMatch-es-US' DESC 'es-US' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.133.1 NAME 'caseIgnoreOrderingMatch-es-UY' DESC 'es-UY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.133.1.6 NAME 'caseIgnoreSubstringMatch-es-UY' DESC 'es-UY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.134.1 NAME 'caseIgnoreOrderingMatch-es-VE' DESC 'es-VE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.134.1.6 NAME 'caseIgnoreSubstringMatch-es-VE' DESC 'es-VE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.135.1 NAME 'caseIgnoreOrderingMatch-fa' DESC 'fa' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.135.1.6 NAME 'caseIgnoreSubstringMatch-fa' DESC 'fa' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.136.1 NAME 'caseIgnoreOrderingMatch-fil' DESC 'fil' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.136.1.6 NAME 'caseIgnoreSubstringMatch-fil' DESC 'fil' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.137.1 NAME 'caseIgnoreOrderingMatch-fo' DESC 'fo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.137.1.6 NAME 'caseIgnoreSubstringMatch-fo' DESC 'fo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.138.1 NAME 'caseIgnoreOrderingMatch-fr-BF' DESC 'fr-BF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.138.1.6 NAME 'caseIgnoreSubstringMatch-fr-BF' DESC 'fr-BF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.139.1 NAME 'caseIgnoreOrderingMatch-fr-BI' DESC 'fr-BI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.139.1.6 NAME 'caseIgnoreSubstringMatch-fr-BI' DESC 'fr-BI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.140.1 NAME 'caseIgnoreOrderingMatch-fr-BJ' DESC 'fr-BJ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.140.1.6 NAME 'caseIgnoreSubstringMatch-fr-BJ' DESC 'fr-BJ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.141.1 NAME 'caseIgnoreOrderingMatch-fr-BL' DESC 'fr-BL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.141.1.6 NAME 'caseIgnoreSubstringMatch-fr-BL' DESC 'fr-BL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.142.1 NAME 'caseIgnoreOrderingMatch-fr-CD' DESC 'fr-CD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.142.1.6 NAME 'caseIgnoreSubstringMatch-fr-CD' DESC 'fr-CD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.143.1 NAME 'caseIgnoreOrderingMatch-fr-CF' DESC 'fr-CF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.143.1.6 NAME 'caseIgnoreSubstringMatch-fr-CF' DESC 'fr-CF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.144.1 NAME 'caseIgnoreOrderingMatch-fr-CG' DESC 'fr-CG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.144.1.6 NAME 'caseIgnoreSubstringMatch-fr-CG' DESC 'fr-CG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.145.1 NAME 'caseIgnoreOrderingMatch-fr-CI' DESC 'fr-CI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.145.1.6 NAME 'caseIgnoreSubstringMatch-fr-CI' DESC 'fr-CI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.146.1 NAME 'caseIgnoreOrderingMatch-fr-CM' DESC 'fr-CM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.146.1.6 NAME 'caseIgnoreSubstringMatch-fr-CM' DESC 'fr-CM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.147.1 NAME 'caseIgnoreOrderingMatch-fr-DJ' DESC 'fr-DJ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.147.1.6 NAME 'caseIgnoreSubstringMatch-fr-DJ' DESC 'fr-DJ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.148.1 NAME 'caseIgnoreOrderingMatch-fr-GA' DESC 'fr-GA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.148.1.6 NAME 'caseIgnoreSubstringMatch-fr-GA' DESC 'fr-GA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.149.1 NAME 'caseIgnoreOrderingMatch-fr-GN' DESC 'fr-GN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.149.1.6 NAME 'caseIgnoreSubstringMatch-fr-GN' DESC 'fr-GN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.150.1 NAME 'caseIgnoreOrderingMatch-fr-GP' DESC 'fr-GP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.150.1.6 NAME 'caseIgnoreSubstringMatch-fr-GP' DESC 'fr-GP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.151.1 NAME 'caseIgnoreOrderingMatch-fr-GQ' DESC 'fr-GQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.151.1.6 NAME 'caseIgnoreSubstringMatch-fr-GQ' DESC 'fr-GQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.152.1 NAME 'caseIgnoreOrderingMatch-fr-KM' DESC 'fr-KM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.152.1.6 NAME 'caseIgnoreSubstringMatch-fr-KM' DESC 'fr-KM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.153.1 NAME 'caseIgnoreOrderingMatch-fr-LU' DESC 'fr-LU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.153.1.6 NAME 'caseIgnoreSubstringMatch-fr-LU' DESC 'fr-LU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.154.1 NAME 'caseIgnoreOrderingMatch-fr-MC' DESC 'fr-MC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.154.1.6 NAME 'caseIgnoreSubstringMatch-fr-MC' DESC 'fr-MC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.155.1 NAME 'caseIgnoreOrderingMatch-fr-MF' DESC 'fr-MF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.155.1.6 NAME 'caseIgnoreSubstringMatch-fr-MF' DESC 'fr-MF' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.156.1 NAME 'caseIgnoreOrderingMatch-fr-MG' DESC 'fr-MG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.156.1.6 NAME 'caseIgnoreSubstringMatch-fr-MG' DESC 'fr-MG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.157.1 NAME 'caseIgnoreOrderingMatch-fr-ML' DESC 'fr-ML' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.157.1.6 NAME 'caseIgnoreSubstringMatch-fr-ML' DESC 'fr-ML' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.158.1 NAME 'caseIgnoreOrderingMatch-fr-MQ' DESC 'fr-MQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.158.1.6 NAME 'caseIgnoreSubstringMatch-fr-MQ' DESC 'fr-MQ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.159.1 NAME 'caseIgnoreOrderingMatch-fr-NE' DESC 'fr-NE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.159.1.6 NAME 'caseIgnoreSubstringMatch-fr-NE' DESC 'fr-NE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.160.1 NAME 'caseIgnoreOrderingMatch-fr-RE' DESC 'fr-RE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.160.1.6 NAME 'caseIgnoreSubstringMatch-fr-RE' DESC 'fr-RE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.161.1 NAME 'caseIgnoreOrderingMatch-fr-RW' DESC 'fr-RW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.161.1.6 NAME 'caseIgnoreSubstringMatch-fr-RW' DESC 'fr-RW' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.162.1 NAME 'caseIgnoreOrderingMatch-fr-SN' DESC 'fr-SN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.162.1.6 NAME 'caseIgnoreSubstringMatch-fr-SN' DESC 'fr-SN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.163.1 NAME 'caseIgnoreOrderingMatch-fr-TD' DESC 'fr-TD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.163.1.6 NAME 'caseIgnoreSubstringMatch-fr-TD' DESC 'fr-TD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.164.1 NAME 'caseIgnoreOrderingMatch-fr-TG' DESC 'fr-TG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.164.1.6 NAME 'caseIgnoreSubstringMatch-fr-TG' DESC 'fr-TG' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.165.1 NAME 'caseIgnoreOrderingMatch-ga' DESC 'ga' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.165.1.6 NAME 'caseIgnoreSubstringMatch-ga' DESC 'ga' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.166.1 NAME 'caseIgnoreOrderingMatch-ga-IE' DESC 'ga-IE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.166.1.6 NAME 'caseIgnoreSubstringMatch-ga-IE' DESC 'ga-IE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.167.1 NAME 'caseIgnoreOrderingMatch-ga-IN' DESC 'ga-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.167.1.6 NAME 'caseIgnoreSubstringMatch-ga-IN' DESC 'ga-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.168.1 NAME 'caseIgnoreOrderingMatch-ha' DESC 'ha' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.168.1.6 NAME 'caseIgnoreSubstringMatch-ha' DESC 'ha' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.169.1 NAME 'caseIgnoreOrderingMatch-ha-Latn' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.169.1.6 NAME 'caseIgnoreSubstringMatch-ha-Latn' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.170.1 NAME 'caseIgnoreOrderingMatch-ha-Latn-GH' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.170.1.6 NAME 'caseIgnoreSubstringMatch-ha-Latn-GH' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.171.1 NAME 'caseIgnoreOrderingMatch-ha-Latn-NE' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.171.1.6 NAME 'caseIgnoreSubstringMatch-ha-Latn-NE' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.172.1 NAME 'caseIgnoreOrderingMatch-ha-Latn-NG' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.172.1.6 NAME 'caseIgnoreSubstringMatch-ha-Latn-NG' DESC 'ha-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.173.1 NAME 'caseIgnoreOrderingMatch-he' DESC 'he' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.173.1.6 NAME 'caseIgnoreSubstringMatch-he' DESC 'he' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.174.1 NAME 'caseIgnoreOrderingMatch-hi' DESC 'hi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.174.1.6 NAME 'caseIgnoreSubstringMatch-hi' DESC 'hi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.175.1 NAME 'caseIgnoreOrderingMatch-hy' DESC 'hy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.175.1.6 NAME 'caseIgnoreSubstringMatch-hy' DESC 'hy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.176.1 NAME 'caseIgnoreOrderingMatch-id-ID' DESC 'id' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.176.1.6 NAME 'caseIgnoreSubstringMatch-id-ID' DESC 'id' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.177.1 NAME 'caseIgnoreOrderingMatch-ig-NG' DESC 'id-ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.177.1.6 NAME 'caseIgnoreSubstringMatch-ig-NG' DESC 'id-ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.178.1 NAME 'caseIgnoreOrderingMatch-it-IT' DESC 'it-IT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.178.1.6 NAME 'caseIgnoreSubstringMatch-it-IT' DESC 'it-IT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.179.1 NAME 'caseIgnoreOrderingMatch-ka' DESC 'ka' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.179.1.6 NAME 'caseIgnoreSubstringMatch-ka' DESC 'ka' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.180.1 NAME 'caseIgnoreOrderingMatch-ka-GE' DESC 'ka-GE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.180.1.6 NAME 'caseIgnoreSubstringMatch-ka-GE' DESC 'ka-GE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.181.1 NAME 'caseIgnoreOrderingMatch-kk' DESC 'kk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.181.1.6 NAME 'caseIgnoreSubstringMatch-kk' DESC 'kk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.182.1 NAME 'caseIgnoreOrderingMatch-kl' DESC 'kl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.182.1.6 NAME 'caseIgnoreSubstringMatch-kl' DESC 'kl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.183.1 NAME 'caseIgnoreOrderingMatch-kn' DESC 'kn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.183.1.6 NAME 'caseIgnoreSubstringMatch-kn' DESC 'kn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.184.1 NAME 'caseIgnoreOrderingMatch-kok' DESC 'kok' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.184.1.6 NAME 'caseIgnoreSubstringMatch-kok' DESC 'kok' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.185.1 NAME 'caseIgnoreOrderingMatch-ml' DESC 'ml' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.185.1.6 NAME 'caseIgnoreSubstringMatch-ml' DESC 'ml' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.186.1 NAME 'caseIgnoreOrderingMatch-ms' DESC 'ms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.186.1.6 NAME 'caseIgnoreSubstringMatch-ms' DESC 'ms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.187.1 NAME 'caseIgnoreOrderingMatch-ms-BN' DESC 'ms-BN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.187.1.6 NAME 'caseIgnoreSubstringMatch-ms-BN' DESC 'ms-BN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.188.1 NAME 'caseIgnoreOrderingMatch-ms-MY' DESC 'ms-MY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.188.1.6 NAME 'caseIgnoreSubstringMatch-ms-MY' DESC 'ms-MY' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.189.1 NAME 'caseIgnoreOrderingMatch-mt' DESC 'mt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.189.1.6 NAME 'caseIgnoreSubstringMatch-mt' DESC 'mt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.190.1 NAME 'caseIgnoreOrderingMatch-nl-NL' DESC 'nl-NL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.190.1.6 NAME 'caseIgnoreSubstringMatch-nl-NL' DESC 'nl-NL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.191.1 NAME 'caseIgnoreOrderingMatch-nn' DESC 'nn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.191.1.6 NAME 'caseIgnoreSubstringMatch-nn' DESC 'nn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.192.1 NAME 'caseIgnoreOrderingMatch-om' DESC 'om' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.192.1.6 NAME 'caseIgnoreSubstringMatch-om' DESC 'om' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.193.1 NAME 'caseIgnoreOrderingMatch-om-ET' DESC 'om-ET' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.193.1.6 NAME 'caseIgnoreSubstringMatch-om-ET' DESC 'om-ET' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.194.1 NAME 'caseIgnoreOrderingMatch-om-KE' DESC 'om-KE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.194.1.6 NAME 'caseIgnoreSubstringMatch-om-KE' DESC 'om-KE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.195.1 NAME 'caseIgnoreOrderingMatch-or' DESC 'or' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.195.1.6 NAME 'caseIgnoreSubstringMatch-or' DESC 'or' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.196.1 NAME 'caseIgnoreOrderingMatch-pa' DESC 'pa' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.196.1.6 NAME 'caseIgnoreSubstringMatch-pa' DESC 'pa' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.197.1 NAME 'caseIgnoreOrderingMatch-pa-Arab' DESC 'pa-Arab' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.197.1.6 NAME 'caseIgnoreSubstringMatch-pa-Arab' DESC 'pa-Arab' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.198.1 NAME 'caseIgnoreOrderingMatch-pa-Arab-PK' DESC 'pa-Arab' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.198.1.6 NAME 'caseIgnoreSubstringMatch-pa-Arab-PK' DESC 'pa-Arab' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.199.1 NAME 'caseIgnoreOrderingMatch-pa-Guru' DESC 'pa-Guru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.199.1.6 NAME 'caseIgnoreSubstringMatch-pa-Guru' DESC 'pa-Guru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.200.1 NAME 'caseIgnoreOrderingMatch-pa-Guru-IN' DESC 'pa-Guru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.200.1.6 NAME 'caseIgnoreSubstringMatch-pa-Guru-IN' DESC 'pa-Guru' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.201.1 NAME 'caseIgnoreOrderingMatch-ps' DESC 'ps' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.201.1.6 NAME 'caseIgnoreSubstringMatch-ps' DESC 'ps' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.202.1 NAME 'caseIgnoreOrderingMatch-pt' DESC 'pt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.202.1.6 NAME 'caseIgnoreSubstringMatch-pt' DESC 'pt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.203.1 NAME 'caseIgnoreOrderingMatch-pt-BR' DESC 'pt-BR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.203.1.6 NAME 'caseIgnoreSubstringMatch-pt-BR' DESC 'pt-BR' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.204.1 NAME 'caseIgnoreOrderingMatch-pt-PT' DESC 'pt-PT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.204.1.6 NAME 'caseIgnoreSubstringMatch-pt-PT' DESC 'pt-PT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.205.1 NAME 'caseIgnoreOrderingMatch-ro-MD' DESC 'ro-MD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.205.1.6 NAME 'caseIgnoreSubstringMatch-ro-MD' DESC 'ro-MD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.206.1 NAME 'caseIgnoreOrderingMatch-ro-RO' DESC 'ro-RO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.206.1.6 NAME 'caseIgnoreSubstringMatch-ro-RO' DESC 'ro-RO' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.207.1 NAME 'caseIgnoreOrderingMatch-ru-MD' DESC 'ru-MD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.207.1.6 NAME 'caseIgnoreSubstringMatch-ru-MD' DESC 'ru-MD' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.208.1 NAME 'caseIgnoreOrderingMatch-ru-RU' DESC 'ru-RU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.208.1.6 NAME 'caseIgnoreSubstringMatch-ru-RU' DESC 'ru-RU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.209.1 NAME 'caseIgnoreOrderingMatch-ru-UA' DESC 'ru-UA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.209.1.6 NAME 'caseIgnoreSubstringMatch-ru-UA' DESC 'ru-UA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.210.1 NAME 'caseIgnoreOrderingMatch-si' DESC 'si' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.210.1.6 NAME 'caseIgnoreSubstringMatch-si' DESC 'si' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.211.1 NAME 'caseIgnoreOrderingMatch-sk' DESC 'sk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.211.1.6 NAME 'caseIgnoreSubstringMatch-sk' DESC 'sk' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.212.1 NAME 'caseIgnoreOrderingMatch-sl' DESC 'sl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.212.1.6 NAME 'caseIgnoreSubstringMatch-sl' DESC 'sl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.213.1 NAME 'caseIgnoreOrderingMatch-sq' DESC 'sq' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.213.1.6 NAME 'caseIgnoreSubstringMatch-sq' DESC 'sq' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.214.1 NAME 'caseIgnoreOrderingMatch-sr-Cyrl' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.214.1.6 NAME 'caseIgnoreSubstringMatch-sr-Cyrl' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.215.1 NAME 'caseIgnoreOrderingMatch-sr-Cyrl-BA' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.215.1.6 NAME 'caseIgnoreSubstringMatch-sr-Cyrl-BA' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.216.1 NAME 'caseIgnoreOrderingMatch-sr-Cyrl-ME' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.216.1.6 NAME 'caseIgnoreSubstringMatch-sr-Cyrl-ME' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.217.1 NAME 'caseIgnoreOrderingMatch-sr-Cyrl-RS' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.217.1.6 NAME 'caseIgnoreSubstringMatch-sr-Cyrl-RS' DESC 'sr-Cyrl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.218.1 NAME 'caseIgnoreOrderingMatch-sr-Latn' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.218.1.6 NAME 'caseIgnoreSubstringMatch-sr-Latn' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.219.1 NAME 'caseIgnoreOrderingMatch-sr-Latn-BA' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.219.1.6 NAME 'caseIgnoreSubstringMatch-sr-Latn-BA' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.220.1 NAME 'caseIgnoreOrderingMatch-sr-Latn-ME' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.220.1.6 NAME 'caseIgnoreSubstringMatch-sr-Latn-ME' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.221.1 NAME 'caseIgnoreOrderingMatch-sr-Latn-RS' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.221.1.6 NAME 'caseIgnoreSubstringMatch-sr-Latn-RS' DESC 'sr-Latn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.222.1 NAME 'caseIgnoreOrderingMatch-sv-FI' DESC 'sv-FI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.222.1.6 NAME 'caseIgnoreSubstringMatch-sv-FI' DESC 'sv-FI' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.223.1 NAME 'caseIgnoreOrderingMatch-sv-SE' DESC 'sv-SE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.223.1.6 NAME 'caseIgnoreSubstringMatch-sv-SE' DESC 'sv-SE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.224.1 NAME 'caseIgnoreOrderingMatch-sw' DESC 'sw' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.224.1.6 NAME 'caseIgnoreSubstringMatch-sw' DESC 'sw' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.225.1 NAME 'caseIgnoreOrderingMatch-sw-KE' DESC 'sw-KE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.225.1.6 NAME 'caseIgnoreSubstringMatch-sw-KE' DESC 'sw-KE' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.226.1 NAME 'caseIgnoreOrderingMatch-sw-TZ' DESC 'sw-TZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.226.1.6 NAME 'caseIgnoreSubstringMatch-sw-TZ' DESC 'sw-TZ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.227.1 NAME 'caseIgnoreOrderingMatch-ta' DESC 'ta' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.227.1.6 NAME 'caseIgnoreSubstringMatch-ta' DESC 'ta' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.228.1 NAME 'caseIgnoreOrderingMatch-ta-IN' DESC 'ta-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.228.1.6 NAME 'caseIgnoreSubstringMatch-ta-IN' DESC 'ta-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.229.1 NAME 'caseIgnoreOrderingMatch-ta-LK' DESC 'ta-LK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.229.1.6 NAME 'caseIgnoreSubstringMatch-ta-LK' DESC 'ta-LK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.230.1 NAME 'caseIgnoreOrderingMatch-te' DESC 'te' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.230.1.6 NAME 'caseIgnoreSubstringMatch-te' DESC 'te' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.231.1 NAME 'caseIgnoreOrderingMatch-th' DESC 'th' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.231.1.6 NAME 'caseIgnoreSubstringMatch-th' DESC 'th' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.232.1 NAME 'caseIgnoreOrderingMatch-ur' DESC 'ur' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.232.1.6 NAME 'caseIgnoreSubstringMatch-ur' DESC 'ur' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.233.1 NAME 'caseIgnoreOrderingMatch-ur-IN' DESC 'ur-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.233.1.6 NAME 'caseIgnoreSubstringMatch-ur-IN' DESC 'ur-IN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.234.1 NAME 'caseIgnoreOrderingMatch-ur-PK' DESC 'ur-PK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.234.1.6 NAME 'caseIgnoreSubstringMatch-ur-PK' DESC 'ur-PK' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.235.1 NAME 'caseIgnoreOrderingMatch-vi' DESC 'vi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.235.1.6 NAME 'caseIgnoreSubstringMatch-vi' DESC 'vi' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.236.1 NAME 'caseIgnoreOrderingMatch-yo' DESC 'yo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.236.1.6 NAME 'caseIgnoreSubstringMatch-yo' DESC 'yo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.237.1 NAME 'caseIgnoreOrderingMatch-zh-Hans' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.237.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hans' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.238.1 NAME 'caseIgnoreOrderingMatch-zh-Hans-CN' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.238.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hans-CN' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.239.1 NAME 'caseIgnoreOrderingMatch-zh-Hans-SG' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.239.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hans-SG' DESC 'zh-Hans' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.240.1 NAME 'caseIgnoreOrderingMatch-zh-Hant-HK' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.240.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hant-HK' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.241.1 NAME 'caseIgnoreOrderingMatch-zh-Hant-MO' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.241.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hant-MO' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.242.1 NAME 'caseIgnoreOrderingMatch-zh-Hant-TW' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.242.1.6 NAME 'caseIgnoreSubstringMatch-zh-Hant-TW' DESC 'zh-Hant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.243.1 NAME 'caseIgnoreOrderingMatch-zu' DESC 'zu' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.243.1.6 NAME 'caseIgnoreSubstringMatch-zu' DESC 'zu' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.244.1 NAME 'caseIgnoreOrderingMatch-zu-ZA' DESC 'zu-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.244.1.6 NAME 'caseIgnoreSubstringMatch-zu-ZA' DESC 'zu-ZA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.0.3 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.0.3.6 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.11.3 NAME 'caseExactOrderingMatch-en' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.16.840.1.113730.3.3.2.11.3.6 NAME 'caseExactSubstringMatch-en' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", + "( 2.5.13.23 NAME 'uniqueMemberMatch' DESC 'The uniqueMemberMatch rule compares an assertion value of the Name And Optional UID syntax to an attribute value of a syntax (e.g., the Name And Optional UID syntax) whose corresponding ASN.1 type is NameAndOptionalUID. The rule evaluates to TRUE if and only if the components of the assertion value and attribute value match according to the distinguishedNameMatch rule and either, (1) the component is absent from both the attribute value and assertion value, or (2) the component is present in both the attribute value and the assertion value and the component of the assertion value matches the component of the attribute value according to the bitStringMatch rule. Note that this matching rule has been altered from its description in X.520 [X.520] in order to make the matching rule commutative. Server implementors should consider using the original X.520 semantics (where the matching was less exact) for approximate matching of attributes with uniqueMemberMatch as the equality matching rule.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", + "( 2.5.13.8 NAME 'numericStringMatch' DESC 'The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", + "( 2.5.13.9 NAME 'numericStringOrderingMatch' DESC 'The rule evaluates to TRUE if and only if, in the code point collation order, the prepared attribute value character string appears earlier than the prepared assertion value character string; i.e., the attribute value is less than the assertion value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", + "( 2.5.13.10 NAME 'numericStringSubstringsMatch' DESC 'The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value, (2) an initial substring, if present, matches the beginning of the prepared attribute value character string, and (3) a final substring, if present, matches the end of the prepared attribute value character string.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", + "( 2.5.13.20 NAME 'telephoneNumberMatch' DESC 'The telephoneNumberMatch rule compares an assertion value of the Telephone Number syntax to an attribute value of a syntax (e.g., the Telephone Number syntax) whose corresponding ASN.1 type is a PrintableString representing a telephone number. The rule evaluates to TRUE if and only if the prepared attribute value character string and the prepared assertion value character string have the same number of characters and corresponding characters have the same code point. In preparing the attribute value and assertion value for comparison, characters are case folded in the Map preparation step, and only telephoneNumber Insignificant Character Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", + "( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' DESC 'The telephoneNumberSubstringsMatch rule compares an assertion value of the Substring Assertion syntax to an attribute value of a syntax (e.g., the Telephone Number syntax) whose corresponding ASN.1 type is a PrintableString representing a telephone number. The rule evaluates to TRUE if and only if (1) the prepared substrings of the assertion value match disjoint portions of the prepared attribute value character string in the order of the substrings in the assertion value, (2) an substring, if present, matches the beginning of the prepared attribute value character string, and (3) a substring, if present, matches the end of the prepared attribute value character string. A prepared substring matches a portion of the prepared attribute value character string if corresponding characters have the same code point. In preparing the attribute value and assertion value substrings for comparison, characters are case folded in the Map preparation step, and only telephoneNumber Insignificant Character Handling is applied in the Insignificant Character Handling step.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )" + ], + "objectClass": [ + "top", + "ldapSubentry", + "subschema" + ], + "objectClasses": [ + "( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass X-ORIGIN 'RFC 4512' )", + "( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName X-ORIGIN 'RFC 4512' )", + "( 2.5.20.1 NAME 'subschema' AUXILIARY MAY ( dITStructureRules $ nameForms $ dITContentRules $ objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) X-ORIGIN 'RFC 4512' )", + "( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' SUP top AUXILIARY X-ORIGIN 'RFC 4512' )", + "( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST cn MAY ( seeAlso $ ou $ l $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c MAY ( searchGuide $ description ) X-ORIGIN 'RFC 4519' )", + "( 1.3.6.1.4.1.1466.344 NAME 'dcObject' SUP top AUXILIARY MUST dc X-ORIGIN 'RFC 4519' )", + "( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST cn MAY ( member $ businessCategory $ seeAlso $ owner $ ou $ o $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.17 NAME 'groupOfUniqueNames' SUP top STRUCTURAL MUST cn MAY ( uniqueMember $ businessCategory $ seeAlso $ owner $ ou $ o $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.4 NAME '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 ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationalISDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn MAY ( x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationalISDNNumber $ facsimileTelephoneNumber $ seeAlso $ roleOccupant $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l $ description ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou MAY ( businessCategory $ description $ destinationIndicator $ facsimileTelephoneNumber $ internationalISDNNumber $ l $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ preferredDeliveryMethod $ registeredAddress $ searchGuide $ seeAlso $ st $ street $ telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ userPassword $ x121Address ) X-ORIGIN 'RFC 4519' )", + "( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l MAY ( businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationalISDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l ) X-ORIGIN 'RFC 4519' )", + "( 1.3.6.1.1.3.1 NAME 'uidObject' SUP top AUXILIARY MUST uid X-ORIGIN 'RFC 4519' )", + "( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry' DESC 'LDAP Subentry class, version 1' SUP top STRUCTURAL MAY cn X-ORIGIN 'LDAP Subentry Internet Draft' )", + "( 2.16.840.1.113730.3.2.40 NAME 'directoryServerFeature' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( oid $ cn $ multiLineDescription ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.41 NAME 'nsslapdPlugin' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsslapd-pluginPath $ nsslapd-pluginInitfunc $ nsslapd-pluginType $ nsslapd-pluginId $ nsslapd-pluginVersion $ nsslapd-pluginVendor $ nsslapd-pluginDescription $ nsslapd-pluginEnabled ) MAY ( nsslapd-pluginConfigArea $ nsslapd-plugin-depends-on-type ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.44 NAME 'nsIndex' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsSystemIndex ) MAY ( description $ nsIndexType $ nsMatchingRule $ nsIndexIDListScanLimit ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.109 NAME 'nsBackendInstance' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY ( cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( nstombstonecsn $ nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5replicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY nsSaslMapPriority X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' )", + "( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers ) X-ORIGIN 'Netscape' )", + "( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsSSLToken $ nsSSLPersonalitySSL $ nsSSLActivation ) X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.2.327 NAME 'rootDNPluginConfig' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( rootdn-open-time $ rootdn-close-time $ rootdn-days-allowed $ rootdn-allow-host $ rootdn-deny-host $ rootdn-allow-ip $ rootdn-deny-ip ) X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.2.328 NAME 'nsSchemaPolicy' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( cn $ schemaUpdateObjectclassAccept $ schemaUpdateObjectclassReject $ schemaUpdateAttributeAccept $ schemaUpdateAttributeReject ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.31 NAME 'groupOfCertificates' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( memberCertificateDescription $ businessCategory $ description $ o $ ou $ owner $ seeAlso ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.33 NAME 'groupOfURLs' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( memberURL $ businessCategory $ description $ o $ ou $ owner $ seeAlso ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.35 NAME 'LDAPServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( description $ l $ ou $ seeAlso $ generation $ changeLogMaximumAge $ changeLogMaximumSize ) X-ORIGIN 'Netscape Directory Server' )", + "( 1.3.6.1.4.1.250.3.18 NAME 'cacheObject' DESC 'object that contains the TTL (time to live) attribute type' SUP top STRUCTURAL MAY ttl X-ORIGIN 'LDAP Caching Internet Draft' )", + "( 2.16.840.1.113730.3.2.10 NAME 'netscapeServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( description $ serverRoot $ serverProductName $ serverVersionNumber $ installationTimeStamp $ administratorContactInfo $ userPassword $ adminUrl $ serverHostName ) X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.2.7 NAME 'nsLicenseUser' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( nsLicensedFor $ nsLicenseStartTime $ nsLicenseEndTime ) X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.2.1 NAME 'changeLogEntry' DESC 'LDAP changelog objectclass' SUP top STRUCTURAL MUST ( targetDn $ changeTime $ changeNumber $ changeType ) MAY ( changes $ newRdn $ deleteOldRdn $ newSuperior ) X-ORIGIN 'Changelog Internet Draft' )", + "( 2.16.840.1.113730.3.2.6 NAME 'referral' DESC 'LDAP referrals objectclass' SUP top STRUCTURAL MAY ref X-ORIGIN 'LDAPv3 referrals Internet Draft' )", + "( 2.16.840.1.113730.3.2.12 NAME 'passwordObject' DESC 'Netscape defined password policy objectclass' SUP top STRUCTURAL MAY ( pwdpolicysubentry $ passwordExpirationTime $ passwordExpWarned $ passwordRetryCount $ retryCountResetTime $ accountUnlockTime $ passwordHistory $ passwordAllowChangeTime $ passwordGraceUserTime ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.13 NAME 'passwordPolicy' DESC 'Netscape defined password policy objectclass' SUP top STRUCTURAL MAY ( passwordMaxAge $ passwordExp $ passwordMinLength $ passwordKeepHistory $ passwordInHistory $ passwordChange $ passwordWarning $ passwordLockout $ passwordMaxFailure $ passwordResetDuration $ passwordUnlock $ passwordLockoutDuration $ passwordCheckSyntax $ passwordMustChange $ passwordStorageScheme $ passwordMinAge $ passwordResetFailureCount $ passwordGraceLimit $ passwordMinDigits $ passwordMinAlphas $ passwordMinUppers $ passwordMinLowers $ passwordMinSpecials $ passwordMin8bit $ passwordMaxRepeats $ passwordMinCategories $ passwordMinTokenLength $ passwordTrackUpdateTime $ passwordAdminDN ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.30 NAME 'glue' DESC 'Netscape defined objectclass' SUP top STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.32 NAME 'netscapeMachineData' DESC 'Netscape defined objectclass' SUP top STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.38 NAME 'vlvSearch' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ vlvBase $ vlvScope $ vlvFilter ) MAY multiLineDescription X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.42 NAME 'vlvIndex' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ vlvSort ) MAY ( vlvEnabled $ vlvUses ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.84 NAME 'cosDefinition' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( costargettree $ costemplatedn $ cosspecifier $ cosAttribute $ aci $ cn $ uid ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.93 NAME 'nsRoleDefinition' DESC 'Netscape defined objectclass' SUP ldapSubEntry STRUCTURAL MAY ( description $ nsRoleScopeDN ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.94 NAME 'nsSimpleRoleDefinition' DESC 'Netscape defined objectclass' SUP nsRoleDefinition STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.95 NAME 'nsComplexRoleDefinition' DESC 'Netscape defined objectclass' SUP nsRoleDefinition STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.96 NAME 'nsManagedRoleDefinition' DESC 'Netscape defined objectclass' SUP nsSimpleRoleDefinition STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.97 NAME 'nsFilteredRoleDefinition' DESC 'Netscape defined objectclass' SUP nsComplexRoleDefinition STRUCTURAL MUST nsRoleFilter X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.98 NAME 'nsNestedRoleDefinition' DESC 'Netscape defined objectclass' SUP nsComplexRoleDefinition STRUCTURAL MUST nsRoleDN X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.99 NAME 'cosSuperDefinition' DESC 'Netscape defined objectclass' SUP ldapSubEntry STRUCTURAL MUST cosAttribute MAY description X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.100 NAME 'cosClassicDefinition' DESC 'Netscape defined objectclass' SUP cosSuperDefinition STRUCTURAL MAY ( costemplatedn $ cosspecifier ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.101 NAME 'cosPointerDefinition' DESC 'Netscape defined objectclass' SUP cosSuperDefinition STRUCTURAL MAY costemplatedn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.102 NAME 'cosIndirectDefinition' DESC 'Netscape defined objectclass' SUP cosSuperDefinition STRUCTURAL MAY cosIndirectSpecifier X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.503 NAME 'nsDSWindowsReplicationAgreement' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5replicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5replicaSessionPauseTime $ nsds7WindowsReplicaSubtree $ nsds7DirectoryReplicaSubtree $ nsds7NewWinUserSyncEnabled $ nsds7NewWinGroupSyncEnabled $ nsds7WindowsDomain $ nsds7DirsyncCookie $ winSyncInterval $ oneWaySync $ winSyncMoveAction $ nsds5ReplicaEnabled $ winSyncDirectoryFilter $ winSyncWindowsFilter $ winSyncSubtreePair ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.128 NAME 'costemplate' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY ( cn $ cosPriority ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.304 NAME 'nsView' DESC 'Netscape defined objectclass' SUP top AUXILIARY MAY ( nsViewFilter $ description ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.316 NAME 'nsAttributeEncryption' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsEncryptionAlgorithm ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.5.6.21 NAME 'pkiUser' DESC 'X.509 PKI User' SUP top AUXILIARY MAY userCertificate X-ORIGIN 'RFC 4523' )", + "( 2.5.6.22 NAME 'pkiCA' DESC 'X.509 PKI Certificate Authority' SUP top AUXILIARY MAY ( cACertificate $ certificateRevocationList $ authorityRevocationList $ crossCertificatePair ) X-ORIGIN 'RFC 4523' )", + "( 2.5.6.19 NAME 'cRLDistributionPoint' DESC 'X.509 CRL distribution point' SUP top STRUCTURAL MUST cn MAY ( certificateRevocationList $ authorityRevocationList $ deltaRevocationList ) X-ORIGIN 'RFC 4523' )", + "( 2.5.6.23 NAME 'deltaCRL' DESC 'X.509 delta CRL' SUP top AUXILIARY MAY deltaRevocationList X-ORIGIN 'RFC 4523' )", + "( 2.5.6.15 NAME 'strongAuthenticationUser' DESC 'X.521 strong authentication user' SUP top AUXILIARY MUST userCertificate X-ORIGIN 'RFC 4523' )", + "( 2.5.6.18 NAME 'userSecurityInformation' DESC 'X.521 user security information' SUP top AUXILIARY MAY supportedAlgorithms X-ORIGIN 'RFC 4523' )", + "( 2.5.6.16 NAME 'certificationAuthority' DESC 'X.509 certificate authority' SUP top AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY crossCertificatePair X-ORIGIN 'RFC 4523' )", + "( 2.5.6.16.2 NAME 'certificationAuthority-V2' DESC 'X.509 certificate authority, version 2' SUP certificationAuthority AUXILIARY MAY deltaRevocationList X-ORIGIN 'RFC 4523' )", + "( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL MUST uid MAY ( description $ seeAlso $ l $ o $ ou $ host ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.6 NAME 'document' SUP top STRUCTURAL MUST documentIdentifier MAY ( cn $ description $ seeAlso $ l $ o $ ou $ documentTitle $ documentVersion $ documentAuthor $ documentLocation $ documentPublisher ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top STRUCTURAL MUST cn MAY ( description $ l $ o $ ou $ seeAlso $ telephoneNumber ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL MUST dc MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationalISDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $ description $ o $ associatedName ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' SUP top AUXILIARY MUST associatedDomain X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP country STRUCTURAL MUST co X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.14 NAME 'rFC822localPart' SUP domain STRUCTURAL MAY ( cn $ sn ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURAL MUST cn MAY ( roomNumber $ description $ seeAlso $ telephoneNumber ) X-ORIGIN 'RFC 4524' )", + "( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' SUP top AUXILIARY MUST userPassword X-ORIGIN 'RFC 4524' )", + "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' 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 ) X-ORIGIN 'RFC 2798' )", + "( 2.16.840.1.113730.3.2.322 NAME 'autoMemberDefinition' DESC 'Auto Membership Config Definition Entry' SUP top STRUCTURAL MUST ( cn $ autoMemberScope $ autoMemberFilter $ autoMemberGroupingAttr ) MAY ( autoMemberDefaultGroup $ autoMemberDisabled ) X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.323 NAME 'autoMemberRegexRule' DESC 'Auto Membership Regex Rule Entry' SUP top STRUCTURAL MUST ( cn $ autoMemberTargetGroup ) MAY ( autoMemberExclusiveRegex $ autoMemberInclusiveRegex $ description ) X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.324 NAME 'dnaPluginConfig' DESC 'DNA plugin configuration' SUP top AUXILIARY MAY ( dnaType $ dnaPrefix $ dnaNextValue $ dnaMaxValue $ dnaInterval $ dnaMagicRegen $ dnaFilter $ dnaScope $ dnaSharedCfgDN $ dnaThreshold $ dnaNextRange $ dnaRangeRequestTimeout $ dnaRemoteBindDN $ dnaRemoteBindCred $ cn ) X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.325 NAME 'dnaSharedConfig' DESC 'DNA Shared Configuration' SUP top AUXILIARY MAY ( dnaHostname $ dnaPortNum $ dnaSecurePortNum $ dnaRemoteBindMethod $ dnaRemoteConnProtocol $ dnaRemainingValues ) X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.319 NAME 'mepManagedEntry' DESC 'Managed Entries Managed Entry' SUP top AUXILIARY MAY mepManagedBy X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.320 NAME 'mepOriginEntry' DESC 'Managed Entries Origin Entry' SUP top AUXILIARY MAY mepManagedEntry X-ORIGIN '389 Directory Server' )", + "( 2.16.840.1.113730.3.2.321 NAME 'mepTemplateEntry' DESC 'Managed Entries Template Entry' SUP top AUXILIARY MAY ( cn $ mepStaticAttr $ mepMappedAttr $ mepRDNAttr ) X-ORIGIN '389 Directory Server' )", + "( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Standard LDAP objectclass' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' DESC 'Standard LDAP objectclass' SUP top AUXILIARY MUST uid MAY ( userPassword $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $ description ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.3 NAME 'ipService' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtocol ) MAY description X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( cn $ ipProtocolNumber ) MAY description X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.5 NAME 'oncRpc' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( cn $ oncRpcNumber ) MAY description X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.6 NAME 'ipHost' DESC 'Standard LDAP objectclass' SUP top AUXILIARY MUST ( ipHostNumber $ cn ) MAY ( manager $ description $ l $ o $ ou $ owner $ seeAlso $ serialNumber ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( ipNetworkNumber $ cn ) MAY ( ipNetmaskNumber $ manager $ l $ description ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.10 NAME 'nisObject' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( cn $ nisMapEntry $ nisMapName ) MAY description X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' DESC 'Standard LDAP objectclass' SUP top AUXILIARY MUST cn MAY ( macAddress $ description $ l $ o $ ou $ owner $ seeAlso $ serialNumber ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' DESC 'Standard LDAP objectclass' SUP top AUXILIARY MUST cn MAY ( bootFile $ bootParameter $ description $ l $ o $ ou $ owner $ seeAlso $ serialNumber ) X-ORIGIN 'RFC 2307' )", + "( 1.3.6.1.1.1.2.13 NAME 'nisMap' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST nisMapName MAY description X-ORIGIN 'RFC 2307' )", + "( 2.16.840.1.113730.3.2.129 NAME 'inetDomain' DESC 'Auxiliary class for virtual domain nodes' SUP top AUXILIARY MAY ( inetDomainBaseDN $ inetDomainStatus ) X-ORIGIN 'Netscape subscriber interoperability' )", + "( 2.16.840.1.113730.3.2.130 NAME 'inetUser' DESC 'Auxiliary class which must be present in an entry for delivery of subscriber services' SUP top AUXILIARY MAY ( uid $ inetUserStatus $ inetUserHttpURL $ userPassword $ memberOf ) X-ORIGIN 'Netscape subscriber interoperability' )", + "( 1.3.6.1.4.1.1466.101.120.141 NAME 'NetscapeLinkedOrganization' AUXILIARY MAY parentOrganization X-ORIGIN 'Netscape' )", + "( 1.3.6.1.4.1.1466.101.120.142 NAME 'NetscapePreferences' AUXILIARY MAY ( preferredLanguage $ preferredLocale $ preferredTimeZone ) X-ORIGIN 'Netscape' )", + "( 2.16.840.1.113730.3.2.134 NAME 'inetSubscriber' SUP top AUXILIARY MAY ( inetSubscriberAccountId $ inetSubscriberChallenge $ inetSubscriberResponse ) X-ORIGIN 'Netscape subscriber interoperability' )", + "( 2.16.840.1.113730.3.2.112 NAME 'inetAdmin' DESC 'Marker for an administrative group or user' SUP top AUXILIARY MAY ( aci $ memberOf $ adminRole ) X-ORIGIN 'Netscape Delegated Administrator' )", + "( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Container for a Java object' SUP top STRUCTURAL MUST cn X-ORIGIN 'RFC 2713' )", + "( 1.3.6.1.4.1.42.2.27.4.2.4 NAME 'javaObject' DESC 'Java object representation' SUP top ABSTRACT MUST javaClassName MAY ( javaClassNames $ javaCodebase $ javaDoc $ description ) X-ORIGIN 'RFC 2713' )", + "( 1.3.6.1.4.1.42.2.27.4.2.5 NAME 'javaSerializedObject' DESC 'Java serialized object' SUP javaObject AUXILIARY MUST javaSerializedData X-ORIGIN 'RFC 2713' )", + "( 1.3.6.1.4.1.42.2.27.4.2.7 NAME 'javaNamingReference' DESC 'JNDI reference' SUP javaObject AUXILIARY MAY ( javaReferenceAddress $ javaFactory ) X-ORIGIN 'RFC 2713' )", + "( 1.3.6.1.4.1.42.2.27.4.2.8 NAME 'javaMarshalledObject' DESC 'Java marshalled object' SUP javaObject AUXILIARY MUST javaSerializedData X-ORIGIN 'RFC 2713' )", + "( 0.9.2342.19200300.100.4.3 NAME 'pilotObject' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MAY ( audio $ ditRedirect $ info $ jpegPhoto $ lastModifiedBy $ lastModifiedTime $ manager $ photo $ uniqueIdentifier ) X-ORIGIN 'RFC 1274' )", + "( nsAdminDomain-oid NAME 'nsAdminDomain' DESC 'Netscape defined objectclass' SUP organizationalUnit STRUCTURAL MAY nsAdminDomainName X-ORIGIN 'Netscape' )", + "( nsHost-oid NAME 'nsHost' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( serverHostName $ description $ l $ nsHostLocation $ nsHardwarePlatform $ nsOsVersion ) X-ORIGIN 'Netscape' )", + "( nsAdminGroup-oid NAME 'nsAdminGroup' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsAdminGroupName $ description $ nsConfigRoot $ nsAdminSIEDN ) X-ORIGIN 'Netscape' )", + "( nsApplication-oid NAME 'nsApplication' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsVendor $ description $ nsProductName $ nsNickName $ nsProductVersion $ nsBuildNumber $ nsRevisionNumber $ nsSerialNumber $ nsInstalledLocation $ installationTimeStamp $ nsExpirationDate $ nsBuildSecurity $ nsLdapSchemaVersion $ nsServerMigrationClassname $ nsServerCreationClassname ) X-ORIGIN 'Netscape' )", + "( nsResourceRef-oid NAME 'nsResourceRef' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY seeAlso X-ORIGIN 'Netscape' )", + "( nsTask-oid NAME 'nsTask' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsTaskLabel $ nsHelpRef $ nsExecRef $ nsLogSuppress ) X-ORIGIN 'Netscape' )", + "( nsTaskGroup-oid NAME 'nsTaskGroup' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY nsTaskLabel X-ORIGIN 'Netscape' )", + "( nsAdminObject-oid NAME 'nsAdminObject' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsJarfilename $ nsClassname ) X-ORIGIN 'Netscape' )", + "( nsConfig-oid NAME 'nsConfig' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( description $ nsServerPort $ nsServerAddress $ nsSuiteSpotUser $ nsErrorLog $ nsPidLog $ nsAccessLog $ nsDefaultAcceptLanguage $ nsServerSecurity ) X-ORIGIN 'Netscape' )", + "( nsDirectoryInfo-oid NAME 'nsDirectoryInfo' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsBindDN $ nsBindPassword $ nsDirectoryURL $ nsDirectoryFailoverList $ nsDirectoryInfoRef ) X-ORIGIN 'Netscape' )", + "( nsAdminServer-oid NAME 'nsAdminServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsServerID ) MAY description X-ORIGIN 'Netscape Administration Services' )", + "( nsAdminConfig-oid NAME 'nsAdminConfig' DESC 'Netscape defined objectclass' SUP nsConfig STRUCTURAL MAY ( nsAdminCgiWaitPid $ nsAdminUsers $ nsAdminAccessHosts $ nsAdminAccessAddresses $ nsAdminOneACLDir $ nsAdminEnableDSGW $ nsAdminEnableEnduser $ nsAdminCacheLifetime ) X-ORIGIN 'Netscape Administration Services' )", + "( nsAdminResourceEditorExtension-oid NAME 'nsAdminResourceEditorExtension' DESC 'Netscape defined objectclass' SUP nsAdminObject STRUCTURAL MAY ( nsAdminAccountInfo $ nsDeleteclassname ) X-ORIGIN 'Netscape Administration Services' )", + "( nsAdminGlobalParameters-oid NAME 'nsAdminGlobalParameters' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsAdminEndUserHTMLIndex $ nsNickName ) X-ORIGIN 'Netscape Administration Services' )", + "( nsGlobalParameters-oid NAME 'nsGlobalParameters' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsUniqueAttribute $ nsUserIDFormat $ nsUserRDNComponent $ nsGroupRDNComponent $ nsWellKnownJarfiles $ nsNYR ) X-ORIGIN 'Netscape Administration Services' )", + "( nsDefaultObjectClasses-oid NAME 'nsDefaultObjectClasses' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY nsDefaultObjectClass X-ORIGIN 'Netscape Administration Services' )", + "( nsAdminConsoleUser-oid NAME 'nsAdminConsoleUser' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY nsPreference X-ORIGIN 'Netscape Administration Services' )", + "( nsCustomView-oid NAME 'nsCustomView' DESC 'Netscape defined objectclass' SUP nsAdminObject STRUCTURAL MAY nsDisplayName X-ORIGIN 'Netscape Administration Services' )", + "( nsTopologyCustomView-oid NAME 'nsTopologyCustomView' DESC 'Netscape defined objectclass' SUP nsCustomView STRUCTURAL MAY nsViewConfiguration X-ORIGIN 'Netscape Administration Services' )", + "( nsTopologyPlugin-oid NAME 'nsTopologyPlugin' DESC 'Netscape defined objectclass' SUP nsAdminObject STRUCTURAL X-ORIGIN 'Netscape Administration Services' )", + "( 2.16.840.1.113730.3.2.18 NAME 'netscapeCertificateServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL X-ORIGIN 'Netscape Certificate Management System' )", + "( nsCertificateServer-oid NAME 'nsCertificateServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST nsServerID MAY ( serverHostName $ nsServerPort $ nsCertConfig ) X-ORIGIN 'Netscape Certificate Management System' )", + "( 2.16.840.1.113730.3.2.23 NAME 'netscapeDirectoryServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL X-ORIGIN 'Netscape Directory Server' )", + "( nsDirectoryServer-oid NAME 'nsDirectoryServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST nsServerID MAY ( serverHostName $ nsServerPort $ nsSecureServerPort $ nsBindPassword $ nsBindDN $ nsBaseDN ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.8 NAME 'ntUser' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ntUserDomainId MAY ( description $ l $ ou $ seeAlso $ ntUserPriv $ ntUserHomeDir $ ntUserComment $ ntUserFlags $ ntUserScriptPath $ ntUserAuthFlags $ ntUserUsrComment $ ntUserParms $ ntUserWorkstations $ ntUserLastLogon $ ntUserLastLogoff $ ntUserAcctExpires $ ntUserMaxStorage $ ntUserUnitsPerWeek $ ntUserLogonHours $ ntUserBadPwCount $ ntUserNumLogons $ ntUserLogonServer $ ntUserCountryCode $ ntUserCodePage $ ntUserUniqueId $ ntUserPrimaryGroupId $ ntUserProfile $ ntUserHomeDirDrive $ ntUserPasswordExpired $ ntUserCreateNewAccount $ ntUserDeleteAccount $ ntUniqueId ) X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.2.9 NAME 'ntGroup' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ntUserDomainId MAY ( description $ l $ ou $ seeAlso $ ntGroupId $ ntGroupAttributes $ ntGroupCreateNewGroup $ ntGroupDeleteGroup $ ntGroupType $ ntUniqueId $ mail ) X-ORIGIN 'Netscape NT Synchronization' )", + "( 2.16.840.1.113730.3.2.82 NAME 'nsChangelog4Config' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.114 NAME 'nsConsumer4Config' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MAY cn X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.36 NAME 'LDAPReplica' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( description $ l $ ou $ seeAlso $ replicaRoot $ replicaHost $ replicaPort $ replicaBindDn $ replicaCredentials $ replicaBindMethod $ replicaUseSSL $ replicaUpdateSchedule $ replicaUpdateReplayed $ replicaUpdateFailedAt $ replicaBeginOrc $ replicaNickName $ replicaEntryFilter $ replicatedattributelist $ replicaCFUpdated $ replicaAbandonedChanges $ replicaLastRelevantChange ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.11 NAME 'cirReplicaSource' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( cirReplicaRoot $ cirHost $ cirPort $ cirBindDn $ cirUsePersistentSearch $ cirUseSsl $ cirBindCredentials $ cirLastUpdateApplied $ cirUpdateSchedule $ cirSyncInterval $ cirUpdateFailedat $ cirBeginORC $ replicaNickName $ replicaEntryFilter $ replicatedattributelist ) X-ORIGIN 'Netscape Directory Server' )", + "( 2.16.840.1.113730.3.2.3 NAME 'mailRecipient' DESC 'Netscape Messaging Server 4.x defined objectclass' SUP top AUXILIARY MAY ( cn $ mail $ mailAlternateAddress $ mailHost $ mailRoutingAddress $ mailAccessDomain $ mailAutoReplyMode $ mailAutoReplyText $ mailDeliveryOption $ mailForwardingAddress $ mailMessageStore $ mailProgramDeliveryInfo $ mailQuota $ multiLineDescription $ uid $ userPassword ) X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.113730.3.2.37 NAME 'nsMessagingServerUser' DESC 'Netscape Messaging Server 4.x defined objectclass' SUP top AUXILIARY MAY ( cn $ mailAccessDomain $ mailAutoReplyMode $ mailAutoReplyText $ mailDeliveryOption $ mailForwardingAddress $ mailMessageStore $ mailProgramDeliveryInfo $ mailQuota $ nsmsgDisallowAccess $ nsmsgNumMsgQuota $ nswmExtendedUserPrefs $ vacationstartdate $ vacationenddate ) X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.2.4 NAME 'mailGroup' DESC 'Netscape Messaging Server 4.x defined objectclass' SUP top AUXILIARY MAY ( cn $ mail $ mailAlternateAddress $ mailHost $ mailRoutingAddress $ mgrpAddHeader $ mgrpAllowedBroadcaster $ mgrpAllowedDomain $ mgrpApprovePassword $ mgrpBroadcasterPolicy $ mgrpDeliverTo $ mgrpErrorsTo $ mgrpModerator $ mgrpMsgMaxSize $ mgrpMsgRejectAction $ mgrpMsgRejectText $ mgrpNoDuplicateChecks $ mgrpRemoveHeader $ mgrpRFC822MailMember $ owner ) X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.2.5 NAME 'groupOfMailEnhancedUniqueNames' DESC 'Netscape Messaging Server 4.x defined objectclass' SUP top AUXILIARY MUST cn MAY ( businessCategory $ description $ mailEnhancedUniqueMember $ o $ ou $ owner $ seeAlso ) X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.2.24 NAME 'netscapeMailServer' DESC 'Netscape Messaging Server 4.x defined objectclass' SUP top AUXILIARY X-ORIGIN 'Netscape Messaging Server 4.x' )", + "( 2.16.840.1.113730.3.2.45 NAME 'nsValueItem' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST cn MAY ( nsValueCIS $ nsValueCES $ nsValueTel $ nsValueInt $ nsValueBin $ nsValueDN $ nsValueType $ nsValueSyntax $ nsValueDescription $ nsValueHelpURL $ nsValueFlags $ nsValueDefault ) X-ORIGIN 'Netscape servers - value item' )", + "( 2.16.840.1.113730.3.2.29 NAME 'netscapeWebServer' DESC 'Netscape defined objectclass' SUP top STRUCTURAL MUST ( cn $ nsServerID ) MAY ( description $ nsServerPort ) X-ORIGIN 'Netscape Web Server' )", + "( 2.16.840.1.113730.3.2.154 NAME 'netscapeReversiblePasswordObject' DESC 'object that contains an netscapeReversiblePassword' AUXILIARY MAY netscapeReversiblePassword X-ORIGIN 'Netscape Web Server' )", + "( 1.3.6.1.4.1.11.1.3.2.2.1 NAME 'accountPolicy' DESC 'Account policy entry' SUP top AUXILIARY MAY accountInactivityLimit X-ORIGIN 'Account Policy Plugin' )", + "( 1.3.6.1.1.1.2.17 NAME 'automount' DESC 'An entry in an automounter map' SUP top STRUCTURAL MUST ( cn $ automountInformation ) MAY description X-ORIGIN 'draft-howard-rfc2307bis' )", + "( 1.3.6.1.1.1.2.16 NAME 'automountMap' DESC 'An group of related automount objects' SUP top STRUCTURAL MUST ou X-ORIGIN 'draft-howard-rfc2307bis' )", + "( 1.3.6.1.4.1.5923.1.1.2 NAME 'eduPerson' AUXILIARY MAY ( eduPersonAffiliation $ eduPersonNickName $ eduPersonOrgDN $ eduPersonOrgUnitDN $ eduPersonPrimaryAffiliation $ eduPersonPrincipalName $ eduPersonEntitlement $ eduPersonPrimaryOrgUnitDN $ eduPersonScopedAffiliation ) X-ORIGIN 'http://middleware.internet2.edu/eduperson/' )", + "( 1.3.6.1.4.1.13769.9.1 NAME 'mozillaAbPersonAlpha' SUP top AUXILIARY MUST cn MAY ( c $ description $ displayName $ facsimileTelephoneNumber $ givenName $ homePhone $ l $ mail $ mobile $ mozillaCustom1 $ mozillaCustom2 $ mozillaCustom3 $ mozillaCustom4 $ mozillaHomeCountryName $ mozillaHomeLocalityName $ mozillaHomePostalCode $ mozillaHomeState $ mozillaHomeStreet $ mozillaHomeStreet2 $ mozillaHomeUrl $ mozillaNickname $ mozillaSecondEmail $ mozillaUseHtmlMail $ mozillaWorkStreet2 $ mozillaWorkUrl $ nsAIMid $ o $ ou $ pager $ postalCode $ postOfficeBox $ sn $ st $ street $ telephoneNumber $ title ) X-ORIGIN 'Mozilla Address Book' )", + "( 1.3.6.1.4.1.5322.17.1.1 NAME 'authorizedServiceObject' DESC 'Auxiliary object class for adding authorizedService attribute' SUP top AUXILIARY MAY authorizedService X-ORIGIN 'NSS LDAP schema' )", + "( 1.3.6.1.4.1.5322.17.1.2 NAME 'hostObject' DESC 'Auxiliary object class for adding host attribute' SUP top AUXILIARY MAY host X-ORIGIN 'NSS LDAP schema' )", + "( 2.16.840.1.113730.3.2.318 NAME 'pamConfig' DESC 'PAM plugin configuration' SUP top AUXILIARY MAY ( cn $ pamMissingSuffix $ pamExcludeSuffix $ pamIncludeSuffix $ pamIDAttr $ pamIDMapMethod $ pamFallback $ pamSecure $ pamService $ pamFilter ) X-ORIGIN 'Red Hat Directory Server' )", + "( 2.16.840.1.113730.3.2.326 NAME 'dynamicGroup' DESC 'Group containing internal dynamically-generated members' SUP posixGroup AUXILIARY MAY dsOnlyMemberUid X-ORIGIN 'Red Hat Directory Server' )", + "( 1.3.6.1.4.1.6981.11.2.3 NAME 'PureFTPdUser' DESC 'PureFTPd user with optional quota, throttling and ratio' STRUCTURAL MAY ( FTPStatus $ FTPQuotaFiles $ FTPQuotaMBytes $ FTPUploadRatio $ FTPDownloadRatio $ FTPUploadBandwidth $ FTPDownloadBandwidth $ FTPuid $ FTPgid ) X-ORIGIN 'Pure-FTPd' )", + "( 1.2.840.113556.1.5.87 NAME 'calEntry' DESC 'RFC2739: Calendar Entry' SUP top AUXILIARY MAY ( calCalURI $ calFBURL $ calOtherCalURIs $ calOtherFBURLs $ calCAPURI $ calOtherCAPURIs ) X-ORIGIN 'rfc2739' )", + "( 1.3.18.0.2.6.258 NAME 'printerAbstract' DESC 'Printer related information.' SUP top ABSTRACT MAY ( printer-name $ printer-natural-language-configured $ printer-location $ printer-info $ printer-more-info $ printer-make-and-model $ printer-multiple-document-jobs-supported $ printer-charset-configured $ printer-charset-supported $ printer-generated-natural-language-supported $ printer-document-format-supported $ printer-color-supported $ printer-compression-supported $ printer-pages-per-minute $ printer-pages-per-minute-color $ printer-finishings-supported $ printer-number-up-supported $ printer-sides-supported $ printer-media-supported $ printer-media-local-supported $ printer-resolution-supported $ printer-print-quality-supported $ printer-job-priority-supported $ printer-copies-supported $ printer-job-k-octets-supported $ printer-current-operator $ printer-service-person $ printer-delivery-orientation-supported $ printer-stacking-order-supported $ printer-output-features-supported ) X-ORIGIN 'rfc3712' )", + "( 1.3.18.0.2.6.255 NAME 'printerService' DESC 'Printer information.' SUP printerAbstract STRUCTURAL MAY ( printer-uri $ printer-xri-supported ) X-ORIGIN 'rfc3712' )", + "( 1.3.18.0.2.6.257 NAME 'printerServiceAuxClass' DESC 'Printer information.' SUP printerAbstract AUXILIARY MAY ( printer-uri $ printer-xri-supported ) X-ORIGIN 'rfc3712' )", + "( 1.3.18.0.2.6.256 NAME 'printerIPP' DESC 'Internet Printing Protocol (IPP) information.' SUP top AUXILIARY MAY ( printer-ipp-versions-supported $ printer-multiple-document-jobs-supported ) X-ORIGIN 'rfc3712' )", + "( 1.3.18.0.2.6.253 NAME 'printerLPR' DESC 'LPR information.' SUP top AUXILIARY MUST printer-name MAY printer-aliases X-ORIGIN 'rfc3712' )", + "( 1.3.6.1.4.1.2312.4.3.4.1 NAME 'sabayonProfile' DESC 'sabayon profile' SUP top STRUCTURAL MUST cn MAY ( sabayonProfileURL $ description ) X-ORIGIN 'Sabayon' )", + "( 1.3.6.1.4.1.2312.4.3.4.2 NAME 'sabayonProfileNameObject' DESC 'contains sabayon profile name' SUP top AUXILIARY MUST sabayonProfileName X-ORIGIN 'Sabayon' )", + "( 1.3.6.1.4.1.2312.4.3.4.3 NAME 'sabayonProfileURLObject' DESC 'contains sabayon profile' SUP top AUXILIARY MUST cn MAY sabayonProfileURL X-ORIGIN 'Sabayon' )", + "( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $ sudoOrder $ description ) X-ORIGIN 'SUDO' )", + "( 5.3.6.1.1.1.2.0 NAME 'trustAccount' DESC 'Sets trust accounts information' SUP top AUXILIARY MUST trustModel MAY accessTo X-ORIGIN 'nss_ldap/pam_ldap' )" + ] + }, + "schema_entry": "cn=schema", + "type": "SchemaInfo" +} +""" + +ds389_1_3_3_dsa_info = """ +{ + "raw": { + "aci": [ + "(targetattr != \\"aci\\")(version 3.0; aci \\"rootdse anon read access\\"; allow(read,search,compare) userdn=\\"ldap:///anyone\\";)" + ], + "dataversion": [ + "020141110230816" + ], + "defaultnamingcontext": [ + "dc=labldap06,dc=a3,dc=internal,dc=cloudapp,dc=net" + ], + "namingContexts": [ + "dc=labldap06,dc=a3,dc=internal,dc=cloudapp,dc=net" + ], + "netscapemdsuffix": [ + "cn=ldap://dc=DS3891,dc=labldap06,dc=a3,dc=internal,dc=cloudapp,dc=net:389" + ], + "objectClass": [ + "top" + ], + "subschemaSubentry": [ + "cn=schema" + ], + "supportedControl": [ + "2.16.840.1.113730.3.4.2", + "2.16.840.1.113730.3.4.3", + "2.16.840.1.113730.3.4.4", + "2.16.840.1.113730.3.4.5", + "1.2.840.113556.1.4.473", + "2.16.840.1.113730.3.4.9", + "2.16.840.1.113730.3.4.16", + "2.16.840.1.113730.3.4.15", + "2.16.840.1.113730.3.4.17", + "2.16.840.1.113730.3.4.19", + "1.3.6.1.1.13.1", + "1.3.6.1.1.13.2", + "1.3.6.1.4.1.42.2.27.8.5.1", + "1.3.6.1.4.1.42.2.27.9.5.2", + "1.2.840.113556.1.4.319", + "1.3.6.1.4.1.42.2.27.9.5.8", + "1.3.6.1.4.1.4203.666.5.16", + "2.16.840.1.113730.3.4.14", + "2.16.840.1.113730.3.4.20", + "1.3.6.1.4.1.1466.29539.12", + "2.16.840.1.113730.3.4.12", + "2.16.840.1.113730.3.4.18", + "2.16.840.1.113730.3.4.13" + ], + "supportedExtension": [ + "2.16.840.1.113730.3.5.7", + "2.16.840.1.113730.3.5.8", + "2.16.840.1.113730.3.5.3", + "2.16.840.1.113730.3.5.12", + "2.16.840.1.113730.3.5.5", + "2.16.840.1.113730.3.5.6", + "2.16.840.1.113730.3.5.9", + "2.16.840.1.113730.3.5.4", + "2.16.840.1.113730.3.6.5", + "2.16.840.1.113730.3.6.6", + "2.16.840.1.113730.3.6.7", + "2.16.840.1.113730.3.6.8", + "1.3.6.1.4.1.4203.1.11.3", + "1.3.6.1.4.1.4203.1.11.1" + ], + "supportedLdapVersion": [ + "2", + "3" + ], + "supportedSASLMechanisms": [ + "EXTERNAL", + "PLAIN", + "DIGEST-MD5", + "ANONYMOUS", + "GSSAPI", + "LOGIN" + ], + "vendorName": [ + "389 Project" + ], + "vendorVersion": [ + "389-Directory/1.3.3.0 B2014.289.2022" + ] + }, + "type": "DsaInfo" +} +""" diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir888.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir888.py new file mode 100644 index 00000000..fdc93717 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir888.py @@ -0,0 +1,1127 @@ +""" +""" + +# 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 . + +edir_8_8_8_schema = """ +{ + "raw": { + "attributeTypes": [ + "( 2.5.4.35 NAME 'userPassword' DESC 'Internal NDS policy forces this to be single-valued' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} USAGE directoryOperation )", + "( 2.5.18.1 NAME 'createTimestamp' DESC 'Operational Attribute' 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 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.5.18.10 NAME 'subschemaSubentry' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation )", + "( 2.5.21.9 NAME 'structuralObjectClass' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.49 NAME 'subordinateCount' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.48 NAME 'entryFlags' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.51 NAME 'federationBoundary' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.5.21.5 NAME 'attributeTypes' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )", + "( 2.5.21.6 NAME 'objectClasses' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )", + "( 1.3.6.1.1.20 NAME 'entryDN' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.1.4.1.2 NAME 'ACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.4.1 NAME 'aliasedObjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Aliased Object Name' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.6 NAME 'backLink' SYNTAX 2.16.840.1.113719.1.1.5.1.23 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Back Link' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.8 NAME 'binderyProperty' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Property' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.7 NAME 'binderyObjectRestriction' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Object Restriction' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.9 NAME 'binderyType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Type' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.11 NAME 'cAPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'CA Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.12 NAME 'cAPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'CA Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.10 NAME 'Cartridge' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.3 NAME ( 'cn' 'commonName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'CN' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.78 NAME 'printerConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} SINGLE-VALUE X-NDS_NAME 'Printer Configuration' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.15 NAME 'Convergence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{1} SINGLE-VALUE X-NDS_UPPER_BOUND '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.6 NAME ( 'c' 'countryName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2} SINGLE-VALUE X-NDS_NAME 'C' X-NDS_LOWER_BOUND '2' X-NDS_UPPER_BOUND '2' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.18 NAME 'defaultQueue' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Default Queue' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.13 NAME ( 'description' 'multiLineDescription' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} X-NDS_NAME 'Description' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '1024' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.64 NAME 'partitionCreationTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Creation Time' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.23 NAME 'facsimileTelephoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22{64512} X-NDS_NAME 'Facsimile Telephone Number' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.117 NAME 'highConvergenceSyncInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'High Convergence Sync Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.25 NAME 'groupMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Group Membership' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.26 NAME 'ndsHomeDirectory' SYNTAX 2.16.840.1.113719.1.1.5.1.15{255} SINGLE-VALUE X-NDS_NAME 'Home Directory' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.27 NAME 'hostDevice' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Device' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.28 NAME 'hostResourceName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Host Resource Name' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.29 NAME 'hostServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.30 NAME 'inheritedACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Inherited ACL' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.7 NAME ( 'l' 'localityname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'L' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.39 NAME 'loginAllowedTimeMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{42} SINGLE-VALUE X-NDS_NAME 'Login Allowed Time Map' X-NDS_LOWER_BOUND '42' X-NDS_UPPER_BOUND '42' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.40 NAME 'loginDisabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Login Disabled' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.41 NAME 'loginExpirationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Expiration Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.42 NAME 'loginGraceLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Grace Limit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.43 NAME 'loginGraceRemaining' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Grace Remaining' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.44 NAME 'loginIntruderAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.12 SINGLE-VALUE X-NDS_NAME 'Login Intruder Address' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.45 NAME 'loginIntruderAttempts' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Intruder Attempts' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.46 NAME 'loginIntruderLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Intruder Limit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.31 NAME 'intruderAttemptResetInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder Attempt Reset Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.47 NAME 'loginIntruderResetTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Intruder Reset Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.48 NAME 'loginMaximumSimultaneous' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Maximum Simultaneous' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.49 NAME 'loginScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Login Script' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.50 NAME 'loginTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Time' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.31 NAME ( 'member' 'uniqueMember' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Member' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.52 NAME 'Memory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.22 NAME 'eMailAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.14{64512} X-NDS_NAME 'EMail Address' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.55 NAME 'networkAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.56 NAME 'networkAddressRestriction' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address Restriction' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.57 NAME 'notify' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Notify' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.114 NAME 'Obituary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.0 NAME 'objectClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-NDS_NAME 'Object Class' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.59 NAME 'operator' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Operator' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'OU' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.10 NAME ( 'o' 'organizationname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'O' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.32 NAME 'owner' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Owner' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.63 NAME 'pageDescriptionLanguage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} X-NDS_NAME 'Page Description Language' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.65 NAME 'passwordsUsed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'Passwords Used' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.66 NAME 'passwordAllowChange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Allow Change' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.67 NAME 'passwordExpirationInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Password Expiration Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.68 NAME 'passwordExpirationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Password Expiration Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.69 NAME 'passwordMinimumLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Password Minimum Length' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.70 NAME 'passwordRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Required' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.71 NAME 'passwordUniqueRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Unique Required' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.72 NAME 'path' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'Path' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.19 NAME 'physicalDeliveryOfficeName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'Physical Delivery Office Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.16 NAME 'postalAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} X-NDS_NAME 'Postal Address' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.17 NAME 'postalCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} X-NDS_NAME 'Postal Code' X-NDS_UPPER_BOUND '40' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.18 NAME 'postOfficeBox' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} X-NDS_NAME 'Postal Office Box' X-NDS_UPPER_BOUND '40' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.80 NAME 'printJobConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Print Job Configuration' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.79 NAME 'printerControl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Printer Control' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.82 NAME 'privateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.83 NAME 'Profile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.84 NAME 'publicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.85 NAME 'queue' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Queue' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.86 NAME 'queueDirectory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-NDS_NAME 'Queue Directory' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.115 NAME 'Reference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.88 NAME 'Replica' SYNTAX 2.16.840.1.113719.1.1.5.1.16{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.89 NAME 'Resource' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.33 NAME 'roleOccupant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Role Occupant' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.116 NAME 'higherPrivileges' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Higher Privileges' X-NDS_SERVER_READ '1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.92 NAME 'securityEquals' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Security Equals' X-NDS_SERVER_READ '1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.4.34 NAME 'seeAlso' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'See Also' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.5 NAME 'serialNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} X-NDS_NAME 'Serial Number' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.95 NAME 'server' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Server' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'S' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.98 NAME 'status' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Status' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' )", + "( 2.5.4.9 NAME 'street' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'SA' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.102 NAME 'supportedTypefaces' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Typefaces' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.101 NAME 'supportedServices' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Services' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.4 NAME ( 'sn' 'surname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Surname' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} X-NDS_NAME 'Telephone Number' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.12 NAME 'title' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Title' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.111 NAME 'User' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.112 NAME 'Version' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.1 NAME 'accountBalance' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Account Balance' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.4 NAME 'allowUnlimitedCredit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Allow Unlimited Credit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.118 NAME 'lowConvergenceResetTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Low Convergence Reset Time' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.54 NAME 'minimumAccountBalance' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Minimum Account Balance' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.104 NAME 'lowConvergenceSyncInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Low Convergence Sync Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.21 NAME 'Device' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.53 NAME 'messageServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Message Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.34 NAME 'Language' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.100 NAME 'supportedConnections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Supported Connections' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.107 NAME 'typeCreatorMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Type Creator Map' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.108 NAME 'ndsUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'UID' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.24 NAME 'groupID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'GID' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.110 NAME 'unknownBaseClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Unknown Base Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.87 NAME 'receivedUpTo' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.33 NAME 'synchronizedUpTo' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Synchronized Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.5 NAME 'authorityRevocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Authority Revocation' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.13 NAME 'certificateRevocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Certificate Revocation' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.17 NAME 'ndsCrossCertificatePair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} X-NDS_NAME 'Cross Certificate Pair' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.37 NAME 'lockedByIntruder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Locked By Intruder' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.77 NAME 'printer' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Printer' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.20 NAME 'detectIntruder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Detect Intruder' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.38 NAME 'lockoutAfterDetection' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Lockout After Detection' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.32 NAME 'intruderLockoutResetInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder Lockout Reset Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.96 NAME 'serverHolds' SYNTAX 2.16.840.1.113719.1.1.5.1.23 X-NDS_NAME 'Server Holds' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.91 NAME 'sAPName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{47} SINGLE-VALUE X-NDS_NAME 'SAP Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '47' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.113 NAME 'Volume' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.35 NAME 'lastLoginTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Last Login Time' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.81 NAME 'printServer' SYNTAX 2.16.840.1.113719.1.1.5.1.25 SINGLE-VALUE X-NDS_NAME 'Print Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.119 NAME 'nNSDomain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'NNS Domain' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.120 NAME 'fullName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-NDS_NAME 'Full Name' X-NDS_UPPER_BOUND '127' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.121 NAME 'partitionControl' SYNTAX 2.16.840.1.113719.1.1.5.1.25 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Control' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.122 NAME 'revision' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Revision' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.123 NAME 'certificateValidityInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'Certificate Validity Interval' X-NDS_LOWER_BOUND '60' X-NDS_UPPER_BOUND '-1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.124 NAME 'externalSynchronizer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'External Synchronizer' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.125 NAME 'messagingDatabaseLocation' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Messaging Database Location' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.126 NAME 'messageRoutingGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Message Routing Group' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.127 NAME 'messagingServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Messaging Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.128 NAME 'Postmaster' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.162 NAME 'mailboxLocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Mailbox Location' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.163 NAME 'mailboxID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Mailbox ID' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.164 NAME 'externalName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'External Name' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.165 NAME 'securityFlags' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Security Flags' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.166 NAME 'messagingServerType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE X-NDS_NAME 'Messaging Server Type' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.167 NAME 'lastReferencedTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Last Referenced Time' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.42 NAME 'givenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} X-NDS_NAME 'Given Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.43 NAME 'initials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} X-NDS_NAME 'Initials' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.44 NAME 'generationQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Generational Qualifier' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.171 NAME 'profileMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Profile Membership' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.172 NAME 'dsRevision' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'DS Revision' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' )", + "( 2.16.840.1.113719.1.1.4.1.173 NAME 'supportedGateway' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} X-NDS_NAME 'Supported Gateway' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '4096' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.174 NAME 'equivalentToMe' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Equivalent To Me' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.175 NAME 'replicaUpTo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Replica Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.176 NAME 'partitionStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Status' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.177 NAME 'permanentConfigParms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'Permanent Config Parms' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.178 NAME 'Timezone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.179 NAME 'binderyRestrictionLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Bindery Restriction Level' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.180 NAME 'transitiveVector' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Transitive Vector' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.181 NAME 'T' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.183 NAME 'purgeVector' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Purge Vector' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.184 NAME 'synchronizationTolerance' SYNTAX 2.16.840.1.113719.1.1.5.1.19 USAGE directoryOperation X-NDS_NAME 'Synchronization Tolerance' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.185 NAME 'passwordManagement' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Password Management' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.186 NAME 'usedBy' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Used By' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.187 NAME 'Uses' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.500 NAME 'obituaryNotify' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Obituary Notify' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.501 NAME 'GUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{16} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.502 NAME 'otherGUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{16} USAGE directoryOperation X-NDS_NAME 'Other GUID' X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.503 NAME 'auxiliaryClassFlag' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Auxiliary Class Flag' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.504 NAME 'unknownAuxiliaryClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} USAGE directoryOperation X-NDS_NAME 'Unknown Auxiliary Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userId' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'uniqueID' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 0.9.2342.19200300.100.1.25 NAME 'dc' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} X-NDS_NAME 'dc' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.507 NAME 'auxClassObjectClassBackup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'AuxClass Object Class Backup' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.508 NAME 'localReceivedUpTo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Local Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.4 NAME 'federationControl' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.2 NAME 'federationSearchPath' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.3 NAME 'federationDNSName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.1 NAME 'federationBoundaryType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.14.4.1.4 NAME 'DirXML-Associations' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.18.3 NAME 'creatorsName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.18.4 NAME 'modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.300 NAME 'languageId' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.35 NAME 'ndsPredicate' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.36 NAME 'ndsPredicateState' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.37 NAME 'ndsPredicateFlush' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.38 NAME 'ndsPredicateTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.40 NAME 'ndsPredicateStatsDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.39 NAME 'ndsPredicateUseValues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.601 NAME 'syncPanePoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.600 NAME 'syncWindowVector' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.602 NAME 'objectVersion' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.27.4.52 NAME 'memberQueryURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'memberQuery' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.302 NAME 'excludedMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.525 NAME 'auxClassCompatibility' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.518 NAME 'ndsAgentPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.519 NAME 'ndsOperationCheckpoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.520 NAME 'localReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.521 NAME 'treeReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.522 NAME 'schemaResetLock' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.523 NAME 'modifiedACLEntry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.524 NAME 'monitoredConnection' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.526 NAME 'localFederationBoundary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.527 NAME 'replicationFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.296 NAME 'loginActivationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.687 NAME 'UpdateInProgress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.400.1 NAME 'edirSchemaFlagVersion' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.512 NAME 'indexDefinition' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.513 NAME 'ndsStatusRepair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.514 NAME 'ndsStatusExternalReference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.515 NAME 'ndsStatusObituary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.516 NAME 'ndsStatusSchema' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.517 NAME 'ndsStatusLimber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.511 NAME 'authoritative' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113730.3.1.34 NAME 'ref' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.546 NAME 'CachedAttrsOnExtRefs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.547 NAME 'ExtRefLastUpdatedTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.688 NAME 'NCPKeyMaterialName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.1.4.713 NAME 'UTF8LoginScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.714 NAME 'loginScriptCharset' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.1.192 NAME 'lDAPLogLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Log Level' X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.27.4.12 NAME 'lDAPUDPPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP UDP Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.1.4.1.204 NAME 'lDAPLogFilename' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Log Filename' )", + "( 2.16.840.1.113719.1.1.4.1.205 NAME 'lDAPBackupLogFilename' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Backup Log Filename' )", + "( 2.16.840.1.113719.1.1.4.1.206 NAME 'lDAPLogSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Log Size Limit' X-NDS_LOWER_BOUND '2048' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.1.4.1.194 NAME 'lDAPSearchSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP Search Size Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.1.4.1.195 NAME 'lDAPSearchTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP Search Time Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.1.4.1.207 NAME 'lDAPSuffix' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Suffix' )", + "( 2.16.840.1.113719.1.27.4.70 NAME 'ldapConfigVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.14 NAME 'ldapReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Referral' )", + "( 2.16.840.1.113719.1.27.4.73 NAME 'ldapDefaultReferralBehavior' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.23 NAME 'ldapSearchReferralUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:searchReferralUsage' )", + "( 2.16.840.1.113719.1.27.4.24 NAME 'lDAPOtherReferralUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:otherReferralUsage' )", + "( 2.16.840.1.113719.1.27.4.1 NAME 'ldapHostServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Host Server' )", + "( 2.16.840.1.113719.1.27.4.2 NAME 'ldapGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Group' )", + "( 2.16.840.1.113719.1.27.4.3 NAME 'ldapTraceLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Screen Level' X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.27.4.4 NAME 'searchSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.27.4.5 NAME 'searchTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.27.4.6 NAME 'ldapServerBindLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Server Bind Limit' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.27.4.7 NAME 'ldapServerIdleTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Server Idle Timeout' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.27.4.8 NAME 'ldapEnableTCP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable TCP' )", + "( 2.16.840.1.113719.1.27.4.10 NAME 'ldapEnableSSL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable SSL' )", + "( 2.16.840.1.113719.1.27.4.11 NAME 'ldapTCPPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP TCP Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.27.4.13 NAME 'ldapSSLPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP SSL Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.27.4.21 NAME 'filteredReplicaUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.22 NAME 'ldapKeyMaterialName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP:keyMaterialName' )", + "( 2.16.840.1.113719.1.27.4.42 NAME 'extensionInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.27.4.45 NAME 'nonStdClientSchemaCompatMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.46 NAME 'sslEnableMutualAuthentication' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.62 NAME 'ldapEnablePSearch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.63 NAME 'ldapMaximumPSearchOperations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.64 NAME 'ldapIgnorePSearchLimitsForEvents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.65 NAME 'ldapTLSTrustedRootContainer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.27.4.66 NAME 'ldapEnableMonitorEvents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.67 NAME 'ldapMaximumMonitorEventsLoad' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.68 NAME 'ldapTLSRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.69 NAME 'ldapTLSVerifyClientCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.71 NAME 'ldapDerefAlias' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.72 NAME 'ldapNonStdAllUserAttrsMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.75 NAME 'ldapBindRestrictions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.79 NAME 'ldapInterfaces' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.27.4.80 NAME 'ldapChainSecureRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.82 NAME 'ldapStdCompliance' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.83 NAME 'ldapDerefAliasOnAuth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.84 NAME 'ldapGeneralizedTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.85 NAME 'ldapPermissiveModify' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.15 NAME 'ldapServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server List' )", + "( 2.16.840.1.113719.1.27.4.16 NAME 'ldapAttributeMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Attribute Map v11' )", + "( 2.16.840.1.113719.1.27.4.17 NAME 'ldapClassMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Class Map v11' )", + "( 2.16.840.1.113719.1.27.4.18 NAME 'ldapAllowClearTextPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Allow Clear Text Password' )", + "( 2.16.840.1.113719.1.27.4.19 NAME 'ldapAnonymousIdentity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Anonymous Identity' )", + "( 2.16.840.1.113719.1.27.4.52 NAME 'ldapAttributeList' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} )", + "( 2.16.840.1.113719.1.27.4.53 NAME 'ldapClassList' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} )", + "( 2.16.840.1.113719.1.27.4.56 NAME 'transitionGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.74 NAME 'ldapTransitionBackLink' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.78 NAME 'ldapLBURPNumWriterThreads' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.20 NAME 'ldapServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server' )", + "( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'Internet EMail Address' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'NSCP:employeeNumber' )", + "( 2.16.840.1.113719.1.27.4.76 NAME 'referralExcludeFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.27.4.77 NAME 'referralIncludeFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.5.4.36 NAME 'userCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} X-NDS_NAME 'userCertificate' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.37 NAME 'cACertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} X-NDS_NAME 'cACertificate' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.40 NAME 'crossCertificatePair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5{64512} X-NDS_NAME 'crossCertificatePair' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.58 NAME 'attributeCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.2 NAME 'knowledgeInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 2.5.4.14 NAME 'searchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.25{64512} X-NDS_NAME 'searchGuide' )", + "( 2.5.4.15 NAME 'businessCategory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' )", + "( 2.5.4.21 NAME 'telexNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.52{64512} X-NDS_NAME 'telexNumber' )", + "( 2.5.4.22 NAME 'teletexTerminalIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51{64512} X-NDS_NAME 'teletexTerminalIdentifier' )", + "( 2.5.4.24 NAME 'x121Address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '15' )", + "( 2.5.4.25 NAME 'internationaliSDNNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '16' )", + "( 2.5.4.26 NAME 'registeredAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} X-NDS_NAME 'registeredAddress' )", + "( 2.5.4.27 NAME 'destinationIndicator' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' )", + "( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.14{64512} SINGLE-VALUE X-NDS_NAME 'preferredDeliveryMethod' )", + "( 2.5.4.29 NAME 'presentationAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.43{64512} SINGLE-VALUE X-NDS_NAME 'presentationAddress' )", + "( 2.5.4.30 NAME 'supportedApplicationContext' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38{64512} X-NDS_NAME 'supportedApplicationContext' )", + "( 2.5.4.45 NAME 'x500UniqueIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6{64512} X-NDS_NAME 'x500UniqueIdentifier' )", + "( 2.5.4.46 NAME 'dnQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64512} )", + "( 2.5.4.47 NAME 'enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21{64512} X-NDS_NAME 'enhancedSearchGuide' )", + "( 2.5.4.48 NAME 'protocolInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.42{64512} X-NDS_NAME 'protocolInformation' )", + "( 2.5.4.51 NAME 'houseIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 2.5.4.52 NAME 'supportedAlgorithms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.49{64512} X-NDS_NAME 'supportedAlgorithms' )", + "( 2.5.4.54 NAME 'dmdName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.38 NAME 'associatedName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.5.4.49 NAME 'dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.1 NAME 'httpServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.3.4.2 NAME 'httpHostServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.3 NAME 'httpThreadsPerCPU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.4 NAME 'httpIOBufferSize' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.5 NAME 'httpRequestTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.6 NAME 'httpKeepAliveRequestTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.7 NAME 'httpSessionTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.8 NAME 'httpKeyMaterialObject' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.9 NAME 'httpTraceLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.10 NAME 'httpAuthRequiresTLS' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.11 NAME 'httpDefaultClearPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.12 NAME 'httpDefaultTLSPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.13 NAME 'httpBindRestrictions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.295 NAME 'emboxConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.54.4.1.1 NAME 'trusteesOfNewObject' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'Trustees Of New Object' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.55.4.1.1 NAME 'newObjectSDSRights' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object's DS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.56.4.1.1 NAME 'newObjectSFSRights' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'New Object's FS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.57.4.1.1 NAME 'setupScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Setup Script' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.58.4.1.1 NAME 'runSetupScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Run Setup Script' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.59.4.1.1 NAME 'membersOfTemplate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Members Of Template' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.60.4.1.1 NAME 'volumeSpaceRestrictions' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'Volume Space Restrictions' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.61.4.1.1 NAME 'setPasswordAfterCreate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Set Password After Create' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.62.4.1.1 NAME 'homeDirectoryRights' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_NAME 'Home Directory Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.63.4.1.1 NAME 'newObjectSSelfRights' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object's Self Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.8.4.1 NAME 'digitalMeID' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.8.4.2 NAME 'assistant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.8.4.3 NAME 'assistantPhone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.4 NAME 'city' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.5 NAME 'company' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.43 NAME 'co' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.6 NAME 'directReports' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 0.9.2342.19200300.100.1.10 NAME 'manager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.8.4.7 NAME 'mailstop' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.41 NAME 'mobile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.42 NAME 'pager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.8 NAME 'workforceID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.9 NAME 'instantMessagingID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.10 NAME 'preferredName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.8.4.11 NAME 'jobCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.12 NAME 'siteLocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.13 NAME 'employeeStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.4 NAME 'employeeType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.14 NAME 'costCenter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.15 NAME 'costCenterDescription' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.16 NAME 'tollFreePhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.17 NAME 'otherPhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.18 NAME 'managerWorkforceID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.19 NAME 'jackNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.20 NAME 'vehicleInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.21 NAME 'accessCardNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.32 NAME 'isManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.8.4.22 NAME 'homeCity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.23 NAME 'homeEmailAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 1.3.6.1.4.1.1466.101.120.31 NAME 'homeFax' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 0.9.2342.19200300.100.1.20 NAME 'homePhone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.24 NAME 'homeState' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} )", + "( 2.16.840.1.113719.1.8.4.25 NAME 'homeZipCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.26 NAME 'personalMobile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.27 NAME 'children' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.28 NAME 'spouse' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.29 NAME 'vendorName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.30 NAME 'vendorAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.31 NAME 'vendorPhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.1.4.1.303 NAME 'dgIdentity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME_VALUE_ACCESS '1' )", + "( 2.16.840.1.113719.1.1.4.1.304 NAME 'dgTimeOut' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.305 NAME 'dgAllowUnknown' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.306 NAME 'dgAllowDuplicates' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.546 NAME 'allowAliasToAncestor' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.39.4.1.1 NAME 'sASSecurityDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Security DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.4.1.2 NAME 'sASServiceDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Service DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.4.1.3 NAME 'sASSecretStore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:SecretStore' )", + "( 2.16.840.1.113719.1.39.4.1.4 NAME 'sASSecretStoreKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'SAS:SecretStore:Key' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.5 NAME 'sASSecretStoreData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'SAS:SecretStore:Data' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.6 NAME 'sASPKIStoreKeys' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'SAS:PKIStore:Keys' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.48.4.1.1 NAME 'nDSPKIPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.2 NAME 'nDSPKIPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Private Key' )", + "( 2.16.840.1.113719.1.48.4.1.3 NAME 'nDSPKIPublicKeyCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key Certificate' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.4 NAME 'nDSPKICertificateChain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:Certificate Chain' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.5 NAME 'nDSPKIParentCA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA' )", + "( 2.16.840.1.113719.1.48.4.1.6 NAME 'nDSPKIParentCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA DN' )", + "( 2.16.840.1.113719.1.48.4.1.7 NAME 'nDSPKIKeyFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Key File' )", + "( 2.16.840.1.113719.1.48.4.1.8 NAME 'nDSPKISubjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Subject Name' )", + "( 2.16.840.1.113719.1.48.4.1.11 NAME 'nDSPKIGivenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Given Name' )", + "( 2.16.840.1.113719.1.48.4.1.9 NAME 'nDSPKIKeyMaterialDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Key Material DN' )", + "( 2.16.840.1.113719.1.48.4.1.10 NAME 'nDSPKITreeCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Tree CA DN' )", + "( 2.16.840.1.113719.1.48.4.1.12 NAME 'nDSPKIUserCertificateInfo' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'NDSPKI:userCertificateInfo' )", + "( 2.16.840.1.113719.1.48.4.1.13 NAME 'nDSPKITrustedRootCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Trusted Root Certificate' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.14 NAME 'nDSPKINotBefore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not Before' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.15 NAME 'nDSPKINotAfter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not After' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.101 NAME 'nDSPKISDKeyServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:SD Key Server DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.102 NAME 'nDSPKISDKeyStruct' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:SD Key Struct' )", + "( 2.16.840.1.113719.1.48.4.1.103 NAME 'nDSPKISDKeyCert' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key Cert' )", + "( 2.16.840.1.113719.1.48.4.1.104 NAME 'nDSPKISDKeyID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key ID' )", + "( 2.16.840.1.113719.1.39.4.1.105 NAME 'nDSPKIKeystore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'NDSPKI:Keystore' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.106 NAME 'ndspkiAdditionalRoots' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.3 NAME 'masvLabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.4 NAME 'masvProposedLabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.5 NAME 'masvDefaultRange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.6 NAME 'masvAuthorizedRange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.7 NAME 'masvDomainPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.8 NAME 'masvClearanceNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.9 NAME 'masvLabelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.10 NAME 'masvLabelSecrecyLevelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.11 NAME 'masvLabelSecrecyCategoryNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.12 NAME 'masvLabelIntegrityLevelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.13 NAME 'masvLabelIntegrityCategoryNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.14 NAME 'masvPolicyUpdate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.31.4.1.16 NAME 'masvNDSAttributeLabels' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.15 NAME 'masvPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.2 NAME 'sASLoginSequence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'SAS:Login Sequence' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.8 NAME 'sASLoginPolicyUpdate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Login Policy Update' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'sasNMASProductOptions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.74 NAME 'sasAuditConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.14 NAME 'sASNDSPasswordWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:NDS Password Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.15 NAME 'sASPolicyCredentials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Policy Credentials' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.16 NAME 'sASPolicyMethods' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Methods' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.17 NAME 'sASPolicyObjectVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Policy Object Version' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.18 NAME 'sASPolicyServiceSubtypes' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Service Subtypes' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.19 NAME 'sASPolicyServices' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Services' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.20 NAME 'sASPolicyUsers' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Users' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.21 NAME 'sASAllowNDSPasswordWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:Allow NDS Password Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.9 NAME 'sASMethodIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Method Identifier' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.10 NAME 'sASMethodVendor' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Method Vendor' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.11 NAME 'sASAdvisoryMethodGrade' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Advisory Method Grade' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.12 NAME 'sASVendorSupport' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Vendor Support' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.13 NAME 'sasCertificateSearchContainers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.70 NAME 'sasNMASMethodConfigData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.22 NAME 'sASLoginClientMethodNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Client Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.23 NAME 'sASLoginServerMethodNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Server Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.24 NAME 'sASLoginClientMethodWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Client Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.25 NAME 'sASLoginServerMethodWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Server Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.26 NAME 'sasLoginClientMethodSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.27 NAME 'sasLoginServerMethodSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.28 NAME 'sasLoginClientMethodLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.29 NAME 'sasLoginServerMethodLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.30 NAME 'sasLoginClientMethodTru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.31 NAME 'sasLoginServerMethodTru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.32 NAME 'sasLoginClientMethodAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.33 NAME 'sasLoginServerMethodAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.34 NAME 'sasLoginClientMethodHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.35 NAME 'sasLoginServerMethodHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1000 NAME 'sasLoginClientMethods390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1001 NAME 'sasLoginServerMethods390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1002 NAME 'sasLoginClientMethodLinuxX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1003 NAME 'sasLoginServerMethodLinuxX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1004 NAME 'sasLoginClientMethodWinX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1005 NAME 'sasLoginServerMethodWinX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1006 NAME 'sasLoginClientMethodSolaris64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1007 NAME 'sasLoginServerMethodSolaris64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1008 NAME 'sasLoginClientMethodAIX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1009 NAME 'sasLoginServerMethodAIX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1011 NAME 'sasLoginServerMethodSolarisi386' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1012 NAME 'sasLoginClientMethodSolarisi386' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.78 NAME 'sasUnsignedMethodModules' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.79 NAME 'sasServerModuleName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.80 NAME 'sasServerModuleEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.81 NAME 'sasSASLMechanismName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.82 NAME 'sasSASLMechanismEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.83 NAME 'sasClientModuleName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.84 NAME 'sasClientModuleEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.36 NAME 'sASLoginMethodContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Login Method Container DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.37 NAME 'sASLoginPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Login Policy DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.63 NAME 'sasPostLoginMethodContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'rADIUSActiveConnections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Active Connections' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.39 NAME 'rADIUSAgedInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Aged Interval' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.40 NAME 'rADIUSAttributeList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Attribute List' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.41 NAME 'rADIUSAttributeLists' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Attribute Lists' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.42 NAME 'rADIUSClient' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Client' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.43 NAME 'rADIUSCommonNameResolution' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Common Name Resolution' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.44 NAME 'rADIUSConcurrentLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Concurrent Limit' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.45 NAME 'rADIUSConnectionHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Connection History' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.46 NAME 'rADIUSDASVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:DAS Version' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.47 NAME 'rADIUSDefaultProfile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Default Profile' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.48 NAME 'rADIUSDialAccessGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'RADIUS:Dial Access Group' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.49 NAME 'rADIUSEnableCommonNameLogin' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS:Enable Common Name Login' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.50 NAME 'rADIUSEnableDialAccess' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS:Enable Dial Access' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.51 NAME 'rADIUSInterimAcctingTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Interim Accting Timeout' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.52 NAME 'rADIUSLookupContexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'RADIUS:Lookup Contexts' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.53 NAME 'rADIUSMaxDASHistoryRecord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Max DAS History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.54 NAME 'rADIUSMaximumHistoryRecord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Maximum History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.55 NAME 'rADIUSPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Password' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.56 NAME 'rADIUSPasswordPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Password Policy' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.57 NAME 'rADIUSPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Private Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.58 NAME 'rADIUSProxyContext' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Proxy Context' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.59 NAME 'rADIUSProxyDomain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Domain' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.60 NAME 'rADIUSProxyTarget' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Target' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.61 NAME 'rADIUSPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Public Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.62 NAME 'rADIUSServiceList' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Service List' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.3 NAME 'sASLoginSecret' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.4 NAME 'sASLoginSecretKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret Key' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.5 NAME 'sASEncryptionType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Encryption Type' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.6 NAME 'sASLoginConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Configuration' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.7 NAME 'sASLoginConfigurationKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Configuration Key' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.73 NAME 'sasDefaultLoginSequence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.64 NAME 'sasAuthorizedLoginSequences' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.69 NAME 'sasAllowableSubjectNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.71 NAME 'sasLoginFailureDelay' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.72 NAME 'sasMethodVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1010 NAME 'sasUpdateLoginInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1011 NAME 'sasOTPEnabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1012 NAME 'sasOTPCounter' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1013 NAME 'sasOTPLookAheadWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1014 NAME 'sasOTPDigits' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1015 NAME 'sasOTPReSync' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1016 NAME 'sasUpdateLoginTimeInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.6.4.1 NAME 'snmpGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.2 NAME 'snmpServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.6.4.3 NAME 'snmpTrapConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.4 NAME 'snmpTrapDescription' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.5 NAME 'snmpTrapInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.6 NAME 'snmpTrapDisable' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.528 NAME 'ndapPartitionPasswordMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.529 NAME 'ndapClassPasswordMgmt' SYNTAX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.530 NAME 'ndapPasswordMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.537 NAME 'ndapPartitionLoginMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.538 NAME 'ndapClassLoginMgmt' SYNTAX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.539 NAME 'ndapLoginMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.1 NAME 'nspmPasswordKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.2 NAME 'nspmPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.3 NAME 'nspmDistributionPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.4 NAME 'nspmPasswordHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.5 NAME 'nspmAdministratorChangeCount' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.6 NAME 'nspmPasswordPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.7 NAME 'nspmPreviousDistributionPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.8 NAME 'nspmDoNotExpirePassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 1.3.6.1.4.1.42.2.27.8.1.16 NAME 'pwdChangedTime' 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' 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.19 NAME 'pwdFailureTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.39.43.4.100 NAME 'nspmConfigurationOptions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.102 NAME 'nspmChangePasswordMessage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.103 NAME 'nspmPasswordHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.104 NAME 'nspmPasswordHistoryExpiration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 1.3.6.1.4.1.42.2.27.8.1.4 NAME 'pwdInHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.105 NAME 'nspmMinPasswordLifetime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.106 NAME 'nspmAdminsDoNotExpirePassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.107 NAME 'nspmPasswordACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 )", + "( 2.16.840.1.113719.1.39.43.4.200 NAME 'nspmMaximumLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.201 NAME 'nspmMinUpperCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.202 NAME 'nspmMaxUpperCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.203 NAME 'nspmMinLowerCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.204 NAME 'nspmMaxLowerCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.205 NAME 'nspmNumericCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.206 NAME 'nspmNumericAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.207 NAME 'nspmNumericAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.208 NAME 'nspmMinNumericCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.209 NAME 'nspmMaxNumericCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.210 NAME 'nspmSpecialCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.211 NAME 'nspmSpecialAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.212 NAME 'nspmSpecialAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.213 NAME 'nspmMinSpecialCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.214 NAME 'nspmMaxSpecialCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.215 NAME 'nspmMaxRepeatedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.216 NAME 'nspmMaxConsecutiveCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.217 NAME 'nspmMinUniqueCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.218 NAME 'nspmDisallowedAttributeValues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.219 NAME 'nspmExcludeList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.220 NAME 'nspmCaseSensitive' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.221 NAME 'nspmPolicyPrecedence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.222 NAME 'nspmExtendedCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.223 NAME 'nspmExtendedAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.224 NAME 'nspmExtendedAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.225 NAME 'nspmMinExtendedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.226 NAME 'nspmMaxExtendedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.227 NAME 'nspmUpperAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.228 NAME 'nspmUpperAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.229 NAME 'nspmLowerAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.230 NAME 'nspmLowerAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.231 NAME 'nspmComplexityRules' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.233 NAME 'nspmAD2K8Syntax' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.234 NAME 'nspmAD2K8maxViolation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.235 NAME 'nspmXCharLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.236 NAME 'nspmXCharHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.237 NAME 'nspmUnicodeAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.238 NAME 'nspmNonAlphaCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.239 NAME 'nspmMinNonAlphaCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.240 NAME 'nspmMaxNonAlphaCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.241 NAME 'nspmGraceLoginHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.300 NAME 'nspmPolicyAgentContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.301 NAME 'nspmPolicyAgentNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.302 NAME 'nspmPolicyAgentWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.303 NAME 'nspmPolicyAgentSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.304 NAME 'nspmPolicyAgentLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.305 NAME 'nspmPolicyAgentAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.306 NAME 'nspmPolicyAgentHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 0.9.2342.19200300.100.1.55 NAME 'audio' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.1 NAME 'carLicense' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.241 NAME 'displayName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 1.3.6.1.4.1.250.1.57 NAME 'labeledUri' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.7 NAME 'ldapPhoto' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.21 NAME 'secretary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.12.4.1.0 NAME 'auditAEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:A Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.2.0 NAME 'auditBEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:B Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.3.0 NAME 'auditContents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Contents' )", + "( 2.16.840.1.113719.1.12.4.4.0 NAME 'auditType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Type' )", + "( 2.16.840.1.113719.1.12.4.5.0 NAME 'auditCurrentEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Current Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.6.0 NAME 'auditFileLink' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Audit:File Link' )", + "( 2.16.840.1.113719.1.12.4.7.0 NAME 'auditLinkList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Audit:Link List' )", + "( 2.16.840.1.113719.1.12.4.8.0 NAME 'auditPath' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Path' )", + "( 2.16.840.1.113719.1.12.4.9.0 NAME 'auditPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Policy' )", + "( 2.16.840.1.113719.1.38.4.1.1 NAME 'wANMANWANPolicy' SYNTAX 2.16.840.1.113719.1.1.5.1.13{64512} X-NDS_NAME 'WANMAN:WAN Policy' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.2 NAME 'wANMANLANAreaMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'WANMAN:LAN Area Membership' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.3 NAME 'wANMANCost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'WANMAN:Cost' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.4 NAME 'wANMANDefaultCost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'WANMAN:Default Cost' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.135.4.30 NAME 'rbsAssignedRoles' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.31 NAME 'rbsContent' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.32 NAME 'rbsContentMembership' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.33 NAME 'rbsEntryPoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.34 NAME 'rbsMember' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.35 NAME 'rbsOwnedCollections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.135.4.36 NAME 'rbsPath' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.37 NAME 'rbsParameters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} )", + "( 2.16.840.1.113719.1.135.4.38 NAME 'rbsTaskRights' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.135.4.39 NAME 'rbsTrusteeOf' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.40 NAME 'rbsType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '256' )", + "( 2.16.840.1.113719.1.135.4.41 NAME 'rbsURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.42 NAME 'rbsTaskTemplates' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.135.4.43 NAME 'rbsTaskTemplatesURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.44 NAME 'rbsGALabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.45 NAME 'rbsPageMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} )", + "( 2.16.840.1.113719.1.135.4.46 NAME 'rbsTargetObjectType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.135.4.47 NAME 'rbsContext' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.48 NAME 'rbsXMLInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.51 NAME 'rbsAssignedRoles2' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.52 NAME 'rbsOwnedCollections2' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.1.4.1.540 NAME 'prSyncPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.541 NAME 'prSyncAttributes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.542 NAME 'dsEncryptedReplicationConfig' SYNTAX 2.16.840.1.113719.1.1.5.1.19 )", + "( 2.16.840.1.113719.1.1.4.1.543 NAME 'encryptionPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.544 NAME 'attrEncryptionRequiresSecure' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.545 NAME 'attrEncryptionDefinition' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.48.4.1.16 NAME 'ndspkiCRLFileName' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.17 NAME 'ndspkiStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.18 NAME 'ndspkiIssueTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.19 NAME 'ndspkiNextIssueTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.20 NAME 'ndspkiAttemptTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.21 NAME 'ndspkiTimeInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.22 NAME 'ndspkiCRLMaxProcessingInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.23 NAME 'ndspkiCRLNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.24 NAME 'ndspkiDistributionPoints' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.25 NAME 'ndspkiCRLProcessData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.26 NAME 'ndspkiCRLConfigurationDNList' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.27 NAME 'ndspkiCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.28 NAME 'ndspkiCRLContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.29 NAME 'ndspkiIssuedCertContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.30 NAME 'ndspkiDistributionPointDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.31 NAME 'ndspkiCRLConfigurationDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.32 NAME 'ndspkiDirectory' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} )", + "( 2.5.4.38 NAME 'authorityRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiAuthorityRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.39 NAME 'certificateRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiCertificateRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.53 NAME 'deltaRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'ndspkiDeltaRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.36 NAME 'ndspkiTrustedRootList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.37 NAME 'ndspkiSecurityRightsLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.48.4.1.38 NAME 'ndspkiKMOExport' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.7.4.1 NAME 'notfSMTPEmailHost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.2 NAME 'notfSMTPEmailFrom' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.3 NAME 'notfSMTPEmailUserName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.5 NAME 'notfMergeTemplateData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.6 NAME 'notfMergeTemplateSubject' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.1 NAME 'nsimRequiredQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.2 NAME 'nsimRandomQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.3 NAME 'nsimNumberRandomQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.4 NAME 'nsimMinResponseLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.5 NAME 'nsimMaxResponseLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.6 NAME 'nsimForgottenLoginConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.7 NAME 'nsimForgottenAction' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.8 NAME 'nsimAssignments' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.9 NAME 'nsimChallengeSetDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.10 NAME 'nsimChallengeSetGUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.11 NAME 'nsimPwdRuleEnforcement' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.12 NAME 'nsimHint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.44.4.13 NAME 'nsimPasswordReminder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.4 NAME 'sssProxyStoreKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.266.4.5 NAME 'sssProxyStoreSecrets' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.266.4.6 NAME 'sssActiveServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.266.4.7 NAME 'sssCacheRefreshInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.8 NAME 'sssAdminList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.266.4.9 NAME 'sssAdminGALabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.10 NAME 'sssEnableReadTimestamps' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.11 NAME 'sssDisableMasterPasswords' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.12 NAME 'sssEnableAdminAccess' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.13 NAME 'sssReadSecretPolicies' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.266.4.14 NAME 'sssServerPolicyOverrideDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.531 NAME 'eDirCloneSource' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.532 NAME 'eDirCloneKeys' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.1.4.1.533 NAME 'eDirCloneLock' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.711 NAME 'groupMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.1.4.712 NAME 'nestedConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.717 NAME 'xdasDSConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.1.4.718 NAME 'xdasConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.1.4.719 NAME 'xdasVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.347.4.79 NAME 'NAuditInstrumentation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.347.4.2 NAME 'NAuditLoggingServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.135.4.53 NAME 'rbsRoleMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.135.4.54 NAME 'rbsCategoryMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )" + ], + "ldapSyntaxes": [ + "( 1.3.6.1.4.1.1466.115.121.1.1 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.2 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.3 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.4 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.5 X-NDS_SYNTAX '21' )", + "( 1.3.6.1.4.1.1466.115.121.1.6 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.7 X-NDS_SYNTAX '7' )", + "( 2.16.840.1.113719.1.1.5.1.6 X-NDS_SYNTAX '6' )", + "( 1.3.6.1.4.1.1466.115.121.1.8 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.9 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.10 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.22 X-NDS_SYNTAX '22' )", + "( 1.3.6.1.4.1.1466.115.121.1.11 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_SYNTAX '1' )", + "( 1.3.6.1.4.1.1466.115.121.1.13 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.14 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.15 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.16 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.17 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.18 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.19 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.20 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.21 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.22 X-NDS_SYNTAX '11' )", + "( 1.3.6.1.4.1.1466.115.121.1.23 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.24 X-NDS_SYNTAX '24' )", + "( 1.3.6.1.4.1.1466.115.121.1.25 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.26 X-NDS_SYNTAX '2' )", + "( 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_SYNTAX '8' )", + "( 1.3.6.1.4.1.1466.115.121.1.28 X-NDS_SYNTAX '9' )", + "( 1.2.840.113556.1.4.906 X-NDS_SYNTAX '29' )", + "( 1.3.6.1.4.1.1466.115.121.1.54 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.56 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.57 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.29 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.30 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.31 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.32 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.33 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.55 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.34 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.35 X-NDS_SYNTAX '3' )", + "( 2.16.840.1.113719.1.1.5.1.19 X-NDS_SYNTAX '19' )", + "( 1.3.6.1.4.1.1466.115.121.1.36 X-NDS_SYNTAX '5' )", + "( 2.16.840.1.113719.1.1.5.1.17 X-NDS_SYNTAX '17' )", + "( 1.3.6.1.4.1.1466.115.121.1.37 X-NDS_SYNTAX '3' )", + "( 2.16.840.1.113719.1.1.5.1.13 X-NDS_SYNTAX '13' )", + "( 1.3.6.1.4.1.1466.115.121.1.40 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.38 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.39 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.41 X-NDS_SYNTAX '18' )", + "( 1.3.6.1.4.1.1466.115.121.1.43 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.44 X-NDS_SYNTAX '4' )", + "( 1.3.6.1.4.1.1466.115.121.1.42 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.16 X-NDS_SYNTAX '16' )", + "( 1.3.6.1.4.1.1466.115.121.1.58 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.45 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.46 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.47 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.48 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.49 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.12 X-NDS_SYNTAX '12' )", + "( 2.16.840.1.113719.1.1.5.1.23 X-NDS_SYNTAX '23' )", + "( 2.16.840.1.113719.1.1.5.1.15 X-NDS_SYNTAX '15' )", + "( 2.16.840.1.113719.1.1.5.1.14 X-NDS_SYNTAX '14' )", + "( 1.3.6.1.4.1.1466.115.121.1.50 X-NDS_SYNTAX '10' )", + "( 1.3.6.1.4.1.1466.115.121.1.51 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.52 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.25 X-NDS_SYNTAX '25' )", + "( 1.3.6.1.4.1.1466.115.121.1.53 X-NDS_SYNTAX '9' )" + ], + "modifyTimestamp": [ + "20141014222353Z" + ], + "objectClass": [ + "top", + "subschema" + ], + "objectClasses": [ + "( 2.5.6.0 NAME 'Top' STRUCTURAL MUST objectClass MAY ( cAPublicKey $ cAPrivateKey $ certificateValidityInterval $ authorityRevocation $ lastReferencedTime $ equivalentToMe $ ACL $ backLink $ binderyProperty $ Obituary $ Reference $ revision $ ndsCrossCertificatePair $ certificateRevocation $ usedBy $ GUID $ otherGUID $ DirXML-Associations $ creatorsName $ modifiersName $ objectVersion $ auxClassCompatibility $ unknownBaseClass $ unknownAuxiliaryClass $ masvProposedLabel $ masvDefaultRange $ masvAuthorizedRange $ auditFileLink $ rbsAssignedRoles $ rbsOwnedCollections $ rbsAssignedRoles2 $ rbsOwnedCollections2 ) X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '16#subtree#[Creator]#[Entry Rights]' )", + "( 1.3.6.1.4.1.42.2.27.1.2.1 NAME 'aliasObject' SUP Top STRUCTURAL MUST aliasedObjectName X-NDS_NAME 'Alias' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.2 NAME 'Country' SUP Top STRUCTURAL MUST c MAY ( description $ searchGuide $ sssActiveServerList $ sssServerPolicyOverrideDN ) X-NDS_NAMING 'c' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.3 NAME 'Locality' SUP Top STRUCTURAL MAY ( description $ l $ seeAlso $ st $ street $ searchGuide $ sssActiveServerList $ sssServerPolicyOverrideDN ) X-NDS_NAMING ( 'l' 'st' ) X-NDS_CONTAINMENT ( 'Country' 'organizationalUnit' 'Locality' 'Organization' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.4 NAME 'Organization' SUP ( ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST o MAY ( description $ facsimileTelephoneNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ printerControl $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ businessCategory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'o' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Locality' 'domain' ) X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Self]#loginScript' '2#entry#[Self]#printJobConfiguration') )", + "( 2.5.6.5 NAME 'organizationalUnit' SUP ( ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST ou MAY ( description $ facsimileTelephoneNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ printerControl $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ businessCategory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'ou' X-NDS_CONTAINMENT ( 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Unit' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Self]#loginScript' '2#entry#[Self]#printJobConfiguration') )", + "( 2.5.6.8 NAME 'organizationalRole' SUP Top STRUCTURAL MUST cn MAY ( description $ facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ roleOccupant $ seeAlso $ st $ street $ telephoneNumber $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Role' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.9 NAME ( 'groupOfNames' 'group' 'groupOfUniqueNames' ) SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ ou $ o $ owner $ seeAlso $ groupID $ fullName $ eMailAddress $ mailboxLocation $ mailboxID $ Profile $ profileMembership $ loginScript $ businessCategory $ nspmPasswordPolicyDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Group' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.6 NAME 'Person' SUP ndsLoginProperties STRUCTURAL MUST ( cn $ sn ) MAY ( description $ seeAlso $ telephoneNumber $ fullName $ givenName $ initials $ generationQualifier $ uid $ assistant $ assistantPhone $ city $ st $ company $ co $ directReports $ manager $ mailstop $ mobile $ personalTitle $ pager $ workforceID $ instantMessagingID $ preferredName $ photo $ jobCode $ siteLocation $ employeeStatus $ employeeType $ costCenter $ costCenterDescription $ tollFreePhoneNumber $ otherPhoneNumber $ managerWorkforceID $ roomNumber $ jackNumber $ departmentNumber $ vehicleInformation $ accessCardNumber $ isManager $ userPassword ) X-NDS_NAMING ( 'cn' 'uid' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.7 NAME 'organizationalPerson' SUP Person STRUCTURAL MAY ( facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ st $ street $ title $ mailboxLocation $ mailboxID $ uid $ mail $ employeeNumber $ destinationIndicator $ internationaliSDNNumber $ preferredDeliveryMethod $ registeredAddress $ teletexTerminalIdentifier $ telexNumber $ x121Address $ businessCategory $ roomNumber $ x500UniqueIdentifier ) X-NDS_NAMING ( 'cn' 'ou' 'uid' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Person' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organizationalPerson STRUCTURAL MAY ( groupMembership $ ndsHomeDirectory $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRemaining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestriction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ printJobConfiguration $ privateKey $ Profile $ publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ messageServer $ Language $ ndsUID $ lockedByIntruder $ serverHolds $ lastLoginTime $ typeCreatorMap $ higherPrivileges $ printerControl $ securityFlags $ profileMembership $ Timezone $ sASServiceDN $ sASSecretStore $ sASSecretStoreKey $ sASSecretStoreData $ sASPKIStoreKeys $ userCertificate $ nDSPKIUserCertificateInfo $ nDSPKIKeystore $ rADIUSActiveConnections $ rADIUSAttributeLists $ rADIUSConcurrentLimit $ rADIUSConnectionHistory $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSPassword $ rADIUSServiceList $ audio $ businessCategory $ carLicense $ departmentNumber $ employeeNumber $ employeeType $ displayName $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledUri $ mail $ manager $ mobile $ o $ pager $ ldapPhoto $ preferredLanguage $ roomNumber $ secretary $ uid $ userSMIMECertificate $ x500UniqueIdentifier $ userPKCS12 $ sssProxyStoreKey $ sssProxyStoreSecrets $ sssServerPolicyOverrideDN ) X-NDS_NAME 'User' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#subtree#[Self]#[All Attributes Rights]' '6#entry#[Self]#loginScript' '1#subtree#[Root Template]#[Entry Rights]' '2#entry#[Public]#messageServer' '2#entry#[Root Template]#groupMembership' '6#entry#[Self]#printJobConfiguration' '2#entry#[Root Template]#networkAddress') )", + "( 2.5.6.14 NAME 'Device' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ networkAddress $ ou $ o $ owner $ seeAlso $ serialNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.4 NAME 'Computer' SUP Device STRUCTURAL MAY ( operator $ server $ status ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.17 NAME 'Printer' SUP Device STRUCTURAL MAY ( Cartridge $ printerConfiguration $ defaultQueue $ hostDevice $ printServer $ Memory $ networkAddressRestriction $ notify $ operator $ pageDescriptionLanguage $ queue $ status $ supportedTypefaces ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.21 NAME 'Resource' SUP Top ABSTRACT MUST cn MAY ( description $ hostResourceName $ l $ ou $ o $ seeAlso $ Uses ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.20 NAME 'Queue' SUP Resource STRUCTURAL MUST queueDirectory MAY ( Device $ operator $ server $ User $ networkAddress $ Volume $ hostServer ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.3 NAME 'binderyQueue' SUP Queue STRUCTURAL MUST binderyType X-NDS_NAMING ( 'cn' 'binderyType' ) X-NDS_NAME 'Bindery Queue' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.26 NAME 'Volume' SUP Resource STRUCTURAL MUST hostServer MAY status X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Root Template]#hostResourceName' '2#entry#[Root Template]#hostServer') )", + "( 2.16.840.1.113719.1.1.6.1.7 NAME 'directoryMap' SUP Resource STRUCTURAL MUST hostServer MAY path X-NDS_NAME 'Directory Map' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.19 NAME 'Profile' SUP Top STRUCTURAL MUST ( cn $ loginScript ) MAY ( description $ l $ ou $ o $ seeAlso $ fullName ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.22 NAME 'Server' SUP Top ABSTRACT MUST cn MAY ( description $ hostDevice $ l $ ou $ o $ privateKey $ publicKey $ Resource $ seeAlso $ status $ User $ Version $ networkAddress $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ fullName $ securityEquals $ securityFlags $ Timezone $ ndapClassPasswordMgmt $ ndapClassLoginMgmt ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Public]#networkAddress' '16#subtree#[Self]#[Entry Rights]') )", + "( 2.16.840.1.113719.1.1.6.1.10 NAME 'ncpServer' SUP Server STRUCTURAL MAY ( operator $ supportedServices $ messagingServer $ dsRevision $ permanentConfigParms $ ndsPredicateStatsDN $ languageId $ indexDefinition $ CachedAttrsOnExtRefs $ NCPKeyMaterialName $ ldapServerDN $ httpServerDN $ emboxConfig $ sASServiceDN $ cACertificate $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKICertificateChain $ nDSPKIParentCADN $ nDSPKISDKeyID $ nDSPKISDKeyStruct $ snmpGroupDN $ wANMANWANPolicy $ wANMANLANAreaMembership $ wANMANCost $ wANMANDefaultCost $ encryptionPolicyDN $ eDirCloneSource $ eDirCloneLock $ xdasDSConfiguration $ xdasConfiguration $ xdasVersion $ NAuditLoggingServer $ NAuditInstrumentation ) X-NDS_NAME 'NCP Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Public]#messagingServer' )", + "( 2.16.840.1.113719.1.1.6.1.18 NAME 'printServer' SUP Server STRUCTURAL MAY ( operator $ printer $ sAPName ) X-NDS_NAME 'Print Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.31 NAME 'CommExec' SUP Server STRUCTURAL MAY networkAddressRestriction X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.2 NAME 'binderyObject' SUP Top STRUCTURAL MUST ( binderyObjectRestriction $ binderyType $ cn ) X-NDS_NAMING ( 'cn' 'binderyType' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Bindery Object' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.15 NAME 'Partition' AUXILIARY MAY ( Convergence $ partitionCreationTime $ Replica $ inheritedACL $ lowConvergenceSyncInterval $ receivedUpTo $ synchronizedUpTo $ authorityRevocation $ certificateRevocation $ cAPrivateKey $ cAPublicKey $ ndsCrossCertificatePair $ lowConvergenceResetTime $ highConvergenceSyncInterval $ partitionControl $ replicaUpTo $ partitionStatus $ transitiveVector $ purgeVector $ synchronizationTolerance $ obituaryNotify $ localReceivedUpTo $ federationControl $ syncPanePoint $ syncWindowVector $ authoritative $ allowAliasToAncestor $ sASSecurityDN $ masvLabel $ ndapPartitionPasswordMgmt $ ndapPartitionLoginMgmt $ prSyncPolicyDN $ dsEncryptedReplicationConfig ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.0 NAME 'aFPServer' SUP Server STRUCTURAL MAY ( serialNumber $ supportedConnections ) X-NDS_NAME 'AFP Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.27 NAME 'messagingServer' SUP Server STRUCTURAL MAY ( messagingDatabaseLocation $ messageRoutingGroup $ Postmaster $ supportedServices $ messagingServerType $ supportedGateway ) X-NDS_NAME 'Messaging Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '1#subtree#[Self]#[Entry Rights]' '2#subtree#[Self]#[All Attributes Rights]' '6#entry#[Self]#status' '2#entry#[Public]#messagingServerType' '2#entry#[Public]#messagingDatabaseLocation') )", + "( 2.16.840.1.113719.1.1.6.1.28 NAME 'messageRoutingGroup' SUP groupOfNames STRUCTURAL X-NDS_NAME 'Message Routing Group' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '1#subtree#[Self]#[Entry Rights]' '2#subtree#[Self]#[All Attributes Rights]') )", + "( 2.16.840.1.113719.1.1.6.1.29 NAME 'externalEntity' SUP Top STRUCTURAL MUST cn MAY ( description $ seeAlso $ facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ st $ street $ title $ externalName $ mailboxLocation $ mailboxID ) X-NDS_NAMING ( 'cn' 'ou' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'External Entity' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Public]#externalName' )", + "( 2.16.840.1.113719.1.1.6.1.30 NAME 'List' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ ou $ o $ eMailAddress $ mailboxLocation $ mailboxID $ owner $ seeAlso $ fullName ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Root Template]#member' )", + "( 2.16.840.1.113719.1.1.6.1.32 NAME 'treeRoot' SUP Top STRUCTURAL MUST T MAY sssActiveServerList X-NDS_NAMING 'T' X-NDS_NAME 'Tree Root' X-NDS_NONREMOVABLE '1' )", + "( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP ( Top $ ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST dc MAY ( searchGuide $ o $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ l $ associatedName $ description $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'dc' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 1.3.6.1.4.1.1466.344 NAME 'dcObject' AUXILIARY MUST dc X-NDS_NAMING 'dc' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.33 NAME 'ndsLoginProperties' SUP Top ABSTRACT MAY ( groupMembership $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRemaining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestriction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ privateKey $ Profile $ publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ Language $ lockedByIntruder $ serverHolds $ lastLoginTime $ higherPrivileges $ securityFlags $ profileMembership $ Timezone $ loginActivationTime $ UTF8LoginScript $ loginScriptCharset $ sASNDSPasswordWindow $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasAllowableSubjectNames $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPCounter $ sasOTPDigits $ sasOTPReSync $ sasUpdateLoginTimeInterval $ ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordKey $ nspmPassword $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotExpirePassword $ nspmDistributionPassword $ nspmPreviousDistributionPassword $ nspmPasswordHistory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN $ nsimHint $ nsimPasswordReminder $ userPassword ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.141.6.1 NAME 'federationBoundary' AUXILIARY MUST federationBoundaryType MAY ( federationControl $ federationDNSName $ federationSearchPath ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.34 NAME 'ndsContainerLoginProperties' SUP Top ABSTRACT MAY ( loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPDigits $ sasUpdateLoginTimeInterval $ ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordPolicyDN ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.6.3 NAME 'ndsPredicateStats' SUP Top STRUCTURAL MUST ( cn $ ndsPredicateState $ ndsPredicateFlush ) MAY ( ndsPredicate $ ndsPredicateTimeout $ ndsPredicateUseValues ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.400.1 NAME 'edirSchemaVersion' SUP Top ABSTRACT MAY edirSchemaFlagVersion X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.47 NAME 'immediateSuperiorReference' AUXILIARY MAY ref X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.27.6.1 NAME 'ldapServer' SUP Top STRUCTURAL MUST cn MAY ( ldapHostServer $ ldapGroupDN $ ldapTraceLevel $ ldapServerBindLimit $ ldapServerIdleTimeout $ lDAPUDPPort $ lDAPSearchSizeLimit $ lDAPSearchTimeLimit $ lDAPLogLevel $ lDAPLogFilename $ lDAPBackupLogFilename $ lDAPLogSizeLimit $ Version $ searchSizeLimit $ searchTimeLimit $ ldapEnableTCP $ ldapTCPPort $ ldapEnableSSL $ ldapSSLPort $ ldapKeyMaterialName $ filteredReplicaUsage $ extensionInfo $ nonStdClientSchemaCompatMode $ sslEnableMutualAuthentication $ ldapEnablePSearch $ ldapMaximumPSearchOperations $ ldapIgnorePSearchLimitsForEvents $ ldapTLSTrustedRootContainer $ ldapEnableMonitorEvents $ ldapMaximumMonitorEventsLoad $ ldapTLSRequired $ ldapTLSVerifyClientCertificate $ ldapConfigVersion $ ldapDerefAlias $ ldapNonStdAllUserAttrsMode $ ldapBindRestrictions $ ldapDefaultReferralBehavior $ ldapReferral $ ldapSearchReferralUsage $ lDAPOtherReferralUsage $ ldapLBURPNumWriterThreads $ ldapInterfaces $ ldapChainSecureRequired $ ldapStdCompliance $ ldapDerefAliasOnAuth $ ldapGeneralizedTime $ ldapPermissiveModify ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) X-NDS_NAME 'LDAP Server' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.27.6.2 NAME 'ldapGroup' SUP Top STRUCTURAL MUST cn MAY ( ldapReferral $ ldapServerList $ ldapAllowClearTextPassword $ ldapAnonymousIdentity $ lDAPSuffix $ ldapAttributeMap $ ldapClassMap $ ldapSearchReferralUsage $ lDAPOtherReferralUsage $ transitionGroupDN $ ldapAttributeList $ ldapClassList $ ldapConfigVersion $ Version $ ldapDefaultReferralBehavior $ ldapTransitionBackLink $ referralIncludeFilter $ referralExcludeFilter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) X-NDS_NAME 'LDAP Group' X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.22 NAME 'pkiCA' AUXILIARY MAY ( cACertificate $ certificateRevocationList $ authorityRevocationList $ crossCertificatePair $ attributeCertificate $ publicKey $ privateKey $ networkAddress $ loginTime $ lastLoginTime ) X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.21 NAME 'pkiUser' AUXILIARY MAY userCertificate X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.15 NAME 'strongAuthenticationUser' AUXILIARY MAY userCertificate X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.11 NAME 'applicationProcess' SUP Top STRUCTURAL MUST cn MAY ( seeAlso $ ou $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.12 NAME 'applicationEntity' SUP Top STRUCTURAL MUST ( presentationAddress $ cn ) MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL MAY knowledgeInformation X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.16 NAME 'certificationAuthority' AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY crossCertificatePair X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.18 NAME 'userSecurityInformation' AUXILIARY MAY supportedAlgorithms X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.20 NAME 'dmd' SUP ndsLoginProperties AUXILIARY MUST dmdName MAY ( searchGuide $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ l $ description $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.16.2 NAME 'certificationAuthority-V2' AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY ( crossCertificatePair $ deltaRevocationList ) X-NDS_NAME 'certificationAuthorityVer2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.3.6.1 NAME 'httpServer' SUP Top STRUCTURAL MUST cn MAY ( httpHostServerDN $ httpThreadsPerCPU $ httpIOBufferSize $ httpRequestTimeout $ httpKeepAliveRequestTimeout $ httpSessionTimeout $ httpKeyMaterialObject $ httpTraceLevel $ httpAuthRequiresTLS $ httpDefaultClearPort $ httpDefaultTLSPort $ httpBindRestrictions ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'domain' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.64.6.1.1 NAME 'Template' SUP Top STRUCTURAL MUST cn MAY ( trusteesOfNewObject $ newObjectSDSRights $ newObjectSFSRights $ setupScript $ runSetupScript $ membersOfTemplate $ volumeSpaceRestrictions $ setPasswordAfterCreate $ homeDirectoryRights $ accountBalance $ allowUnlimitedCredit $ description $ eMailAddress $ facsimileTelephoneNumber $ groupMembership $ higherPrivileges $ ndsHomeDirectory $ l $ Language $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginMaximumSimultaneous $ loginScript $ mailboxID $ mailboxLocation $ member $ messageServer $ minimumAccountBalance $ networkAddressRestriction $ newObjectSSelfRights $ ou $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ Profile $ st $ street $ securityEquals $ securityFlags $ seeAlso $ telephoneNumber $ title $ assistant $ assistantPhone $ city $ company $ co $ manager $ managerWorkforceID $ mailstop $ siteLocation $ employeeType $ costCenter $ costCenterDescription $ tollFreePhoneNumber $ departmentNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.8.6.1 NAME 'homeInfo' AUXILIARY MAY ( homeCity $ homeEmailAddress $ homeFax $ homePhone $ homeState $ homePostalAddress $ homeZipCode $ personalMobile $ spouse $ children ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.8.6.2 NAME 'contingentWorker' AUXILIARY MAY ( vendorName $ vendorAddress $ vendorPhoneNumber ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.45 NAME 'dynamicGroup' SUP ( groupOfNames $ ndsLoginProperties ) STRUCTURAL MAY ( memberQueryURL $ excludedMember $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.46 NAME 'dynamicGroupAux' SUP ( groupOfNames $ ndsLoginProperties ) AUXILIARY MAY ( memberQueryURL $ excludedMember $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.6.1.1 NAME 'sASSecurity' SUP Top STRUCTURAL MUST cn MAY ( nDSPKITreeCADN $ masvPolicyDN $ sASLoginPolicyDN $ sASLoginMethodContainerDN $ sasPostLoginMethodContainerDN $ nspmPolicyAgentContainerDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Organization' 'domain' ) X-NDS_NAME 'SAS:Security' )", + "( 2.16.840.1.113719.1.39.6.1.2 NAME 'sASService' SUP Resource STRUCTURAL MAY ( hostServer $ privateKey $ publicKey $ allowUnlimitedCredit $ fullName $ lastLoginTime $ lockedByIntruder $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginTime $ networkAddress $ networkAddressRestriction $ notify $ operator $ owner $ path $ securityEquals $ securityFlags $ status $ Version $ nDSPKIKeyMaterialDN $ ndspkiKMOExport ) X-NDS_NAMING 'cn' X-NDS_NAME 'SAS:Service' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.1 NAME 'nDSPKICertificateAuthority' SUP Top STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKIParentCA $ nDSPKIParentCADN $ nDSPKISubjectName $ cACertificate $ ndspkiCRLContainerDN $ ndspkiIssuedCertContainerDN $ ndspkiCRLConfigurationDNList $ ndspkiSecurityRightsLevel ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'NDSPKI:Certificate Authority' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.2 NAME 'nDSPKIKeyMaterial' SUP Top STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIKeyFile $ nDSPKIPrivateKey $ nDSPKIPublicKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKISubjectName $ nDSPKIGivenName $ ndspkiAdditionalRoots $ nDSPKINotBefore $ nDSPKINotAfter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'NDSPKI:Key Material' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.3 NAME 'nDSPKITrustedRoot' SUP Top STRUCTURAL MUST cn MAY ndspkiTrustedRootList X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'domain' ) X-NDS_NAME 'NDSPKI:Trusted Root' )", + "( 2.16.840.1.113719.1.48.6.1.4 NAME 'nDSPKITrustedRootObject' SUP Top STRUCTURAL MUST ( cn $ nDSPKITrustedRootCertificate ) MAY ( nDSPKISubjectName $ nDSPKINotBefore $ nDSPKINotAfter $ externalName $ givenName $ sn ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKITrustedRoot' X-NDS_NAME 'NDSPKI:Trusted Root Object' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.101 NAME 'nDSPKISDKeyAccessPartition' SUP Top STRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'NDSPKI:SD Key Access Partition' )", + "( 2.16.840.1.113719.1.48.6.1.102 NAME 'nDSPKISDKeyList' SUP Top STRUCTURAL MUST cn MAY ( nDSPKISDKeyServerDN $ nDSPKISDKeyStruct $ nDSPKISDKeyCert ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKISDKeyAccessPartition' X-NDS_NAME 'NDSPKI:SD Key List' )", + "( 2.16.840.1.113719.1.31.6.2.1 NAME 'mASVSecurityPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ masvDomainPolicy $ masvPolicyUpdate $ masvClearanceNames $ masvLabelNames $ masvLabelSecrecyLevelNames $ masvLabelSecrecyCategoryNames $ masvLabelIntegrityLevelNames $ masvLabelIntegrityCategoryNames $ masvNDSAttributeLabels ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'MASV:Security Policy' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.1 NAME 'sASLoginMethodContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'SAS:Login Method Container' )", + "( 2.16.840.1.113719.1.39.42.2.0.4 NAME 'sASLoginPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ privateKey $ publicKey $ sASAllowNDSPasswordWindow $ sASPolicyCredentials $ sASPolicyMethods $ sASPolicyObjectVersion $ sASPolicyServiceSubtypes $ sASPolicyServices $ sASPolicyUsers $ sASLoginSequence $ sASLoginPolicyUpdate $ sasNMASProductOptions $ sasPolicyMethods $ sasPolicyServices $ sasPolicyUsers $ sasAllowNDSPasswordWindow $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasAuditConfiguration $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPLookAheadWindow $ sasOTPDigits $ sasUpdateLoginTimeInterval $ nspmPasswordPolicyDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'SAS:Login Policy' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.7 NAME 'sASNMASBaseLoginMethod' SUP Top ABSTRACT MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMethodGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLoginClientMethodWINNT $ sASLoginServerMethodWINNT $ sasCertificateSearchContainers $ sasNMASMethodConfigData $ sasMethodVersion $ sASLoginPolicyUpdate $ sasUnsignedMethodModules $ sasServerModuleName $ sasServerModuleEntryPointName $ sasSASLMechanismName $ sasSASLMechanismEntryPointName $ sasClientModuleName $ sasClientModuleEntryPointName $ sasLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ sasLoginClientMethodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodTru64 $ sasLoginServerMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerMethodAIX $ sasLoginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginClientMethods390 $ sasLoginServerMethods390 $ sasLoginClientMethodLinuxX64 $ sasLoginServerMethodLinuxX64 $ sasLoginClientMethodWinX64 $ sasLoginServerMethodWinX64 $ sasLoginClientMethodSolaris64 $ sasLoginServerMethodSolaris64 $ sasLoginClientMethodSolarisi386 $ sasLoginServerMethodSolarisi386 $ sasLoginClientMethodAIX64 $ sasLoginServerMethodAIX64 ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASLoginMethodContainer' X-NDS_NAME 'SAS:NMAS Base Login Method' )", + "( 2.16.840.1.113719.1.39.42.2.0.8 NAME 'sASNMASLoginMethod' SUP sASNMASBaseLoginMethod STRUCTURAL X-NDS_NAME 'SAS:NMAS Login Method' )", + "( 2.16.840.1.113719.1.39.42.2.0.9 NAME 'rADIUSDialAccessSystem' SUP Top STRUCTURAL MUST cn MAY ( publicKey $ privateKey $ rADIUSAgedInterval $ rADIUSClient $ rADIUSCommonNameResolution $ rADIUSConcurrentLimit $ rADIUSDASVersion $ rADIUSEnableCommonNameLogin $ rADIUSEnableDialAccess $ rADIUSInterimAcctingTimeout $ rADIUSLookupContexts $ rADIUSMaxDASHistoryRecord $ rADIUSMaximumHistoryRecord $ rADIUSPasswordPolicy $ rADIUSPrivateKey $ rADIUSProxyContext $ rADIUSProxyDomain $ rADIUSProxyTarget $ rADIUSPublicKey $ sASLoginConfiguration $ sASLoginConfigurationKey ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'RADIUS:Dial Access System' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.10 NAME 'rADIUSProfile' SUP Top STRUCTURAL MUST cn MAY rADIUSAttributeList X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'RADIUS:Profile' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.11 NAME 'sasPostLoginMethodContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.39.42.2.0.12 NAME 'sasPostLoginMethod' SUP Top STRUCTURAL MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMethodGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLoginClientMethodWINNT $ sASLoginServerMethodWINNT $ sasMethodVersion $ sASLoginPolicyUpdate $ sasUnsignedMethodModules $ sasServerModuleName $ sasServerModuleEntryPointName $ sasSASLMechanismName $ sasSASLMechanismEntryPointName $ sasClientModuleName $ sasClientModuleEntryPointName $ sasLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ sasLoginClientMethodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodTru64 $ sasLoginServerMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerMethodAIX $ sasLoginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginClientMethods390 $ sasLoginServerMethods390 $ sasLoginClientMethodLinuxX64 $ sasLoginServerMethodLinuxX64 $ sasLoginClientMethodWinX64 $ sasLoginServerMethodWinX64 $ sasLoginClientMethodSolaris64 $ sasLoginServerMethodSolaris64 $ sasLoginClientMethodSolarisi386 $ sasLoginServerMethodSolarisi386 $ sasLoginClientMethodAIX64 $ sasLoginServerMethodAIX64 ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sasPostLoginMethodContainer' )", + "( 2.16.840.1.113719.1.6.6.1 NAME 'snmpGroup' SUP Top STRUCTURAL MUST cn MAY ( Version $ snmpServerList $ snmpTrapDisable $ snmpTrapInterval $ snmpTrapDescription $ snmpTrapConfig ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'domain' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.2 NAME 'nspmPasswordPolicyContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Country' 'domain' 'Locality' 'Organization' 'organizationalUnit' ) )", + "( 2.16.840.1.113719.1.39.43.6.3 NAME 'nspmPolicyAgent' SUP Top STRUCTURAL MUST cn MAY ( description $ nspmPolicyAgentNetWare $ nspmPolicyAgentWINNT $ nspmPolicyAgentSolaris $ nspmPolicyAgentLinux $ nspmPolicyAgentAIX $ nspmPolicyAgentHPUX ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nspmPasswordPolicyContainer' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.1 NAME 'nspmPasswordPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ nspmPolicyPrecedence $ nspmConfigurationOptions $ nspmChangePasswordMessage $ passwordExpirationInterval $ loginGraceLimit $ nspmMinPasswordLifetime $ passwordUniqueRequired $ nspmPasswordHistoryLimit $ nspmPasswordHistoryExpiration $ passwordAllowChange $ passwordRequired $ passwordMinimumLength $ nspmMaximumLength $ nspmCaseSensitive $ nspmMinUpperCaseCharacters $ nspmMaxUpperCaseCharacters $ nspmMinLowerCaseCharacters $ nspmMaxLowerCaseCharacters $ nspmNumericCharactersAllowed $ nspmNumericAsFirstCharacter $ nspmNumericAsLastCharacter $ nspmMinNumericCharacters $ nspmMaxNumericCharacters $ nspmSpecialCharactersAllowed $ nspmSpecialAsFirstCharacter $ nspmSpecialAsLastCharacter $ nspmMinSpecialCharacters $ nspmMaxSpecialCharacters $ nspmMaxRepeatedCharacters $ nspmMaxConsecutiveCharacters $ nspmMinUniqueCharacters $ nspmDisallowedAttributeValues $ nspmExcludeList $ nspmExtendedCharactersAllowed $ nspmExtendedAsFirstCharacter $ nspmExtendedAsLastCharacter $ nspmMinExtendedCharacters $ nspmMaxExtendedCharacters $ nspmUpperAsFirstCharacter $ nspmUpperAsLastCharacter $ nspmLowerAsFirstCharacter $ nspmLowerAsLastCharacter $ nspmComplexityRules $ nspmAD2K8Syntax $ nspmAD2K8maxViolation $ nspmXCharLimit $ nspmXCharHistoryLimit $ nspmUnicodeAllowed $ nspmNonAlphaCharactersAllowed $ nspmMinNonAlphaCharacters $ nspmMaxNonAlphaCharacters $ pwdInHistory $ nspmAdminsDoNotExpirePassword $ nspmPasswordACL $ nsimChallengeSetDN $ nsimForgottenAction $ nsimForgottenLoginConfig $ nsimAssignments $ nsimChallengeSetGUID $ nsimPwdRuleEnforcement ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'nspmPasswordPolicyContainer' 'domain' 'Locality' 'Organization' 'organizationalUnit' 'Country' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.4 NAME 'nspmPasswordAux' AUXILIARY MAY ( publicKey $ privateKey $ loginGraceLimit $ loginGraceRemaining $ passwordExpirationTime $ passwordRequired $ nspmPasswordKey $ nspmPassword $ nspmDistributionPassword $ nspmPreviousDistributionPassword $ nspmPasswordHistory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotExpirePassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.12.6.1.0 NAME 'auditFileObject' SUP Top STRUCTURAL MUST ( cn $ auditPolicy $ auditContents ) MAY ( description $ auditPath $ auditLinkList $ auditType $ auditCurrentEncryptionKey $ auditAEncryptionKey $ auditBEncryptionKey ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' 'Country' 'Locality' 'Organization' 'organizationalUnit' 'treeRoot' 'domain' ) X-NDS_NAME 'Audit:File Object' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.38.6.1.4 NAME 'wANMANLANArea' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ o $ ou $ owner $ seeAlso $ wANMANWANPolicy $ wANMANCost $ wANMANDefaultCost ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' ) X-NDS_NAME 'WANMAN:LAN Area' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.37.1 NAME 'rbsCollection' SUP Top STRUCTURAL MUST cn MAY ( owner $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.16.840.1.113719.1.135.6.30.1 NAME 'rbsExternalScope' SUP Top ABSTRACT MUST cn MAY ( rbsURL $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.31.1 NAME 'rbsModule' SUP Top STRUCTURAL MUST cn MAY ( rbsURL $ rbsPath $ rbsType $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' )", + "( 2.16.840.1.113719.1.135.6.32.1 NAME 'rbsRole' SUP Top STRUCTURAL MUST cn MAY ( rbsContent $ rbsMember $ rbsTrusteeOf $ rbsGALabel $ rbsParameters $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' )", + "( 2.16.840.1.113719.1.135.6.33.1 NAME 'rbsTask' SUP Top STRUCTURAL MUST cn MAY ( rbsContentMembership $ rbsType $ rbsTaskRights $ rbsEntryPoint $ rbsParameters $ rbsTaskTemplates $ rbsTaskTemplatesURL $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsModule' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.34.1 NAME 'rbsBook' SUP rbsTask STRUCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.35.1 NAME 'rbsScope' SUP groupOfNames STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.45.1 NAME 'rbsCollection2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsParameters $ owner $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.16.840.1.113719.1.135.6.38.1 NAME 'rbsExternalScope2' SUP Top ABSTRACT MUST cn MAY ( rbsXMLInfo $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.39.1 NAME 'rbsModule2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsPath $ rbsType $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' )", + "( 2.16.840.1.113719.1.135.6.40.1 NAME 'rbsRole2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsContent $ rbsMember $ rbsTrusteeOf $ rbsParameters $ description $ rbsCategoryMembership ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' )", + "( 2.16.840.1.113719.1.135.6.41.1 NAME 'rbsTask2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsContentMembership $ rbsType $ rbsTaskRights $ rbsEntryPoint $ rbsParameters $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsModule2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.42.1 NAME 'rbsBook2' SUP rbsTask2 STRUCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.43.1 NAME 'rbsScope2' SUP groupOfNames STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.49 NAME 'prSyncPolicy' SUP Top STRUCTURAL MUST cn MAY prSyncAttributes X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'domain' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.50 NAME 'encryptionPolicy' SUP Top STRUCTURAL MUST cn MAY ( attrEncryptionDefinition $ attrEncryptionRequiresSecure ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'domain' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.5 NAME 'ndspkiContainer' SUP Top STRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'ndspkiContainer' 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'nDSPKITrustedRoot' ) )", + "( 2.16.840.1.113719.1.48.6.1.6 NAME 'ndspkiCertificate' SUP Top STRUCTURAL MUST ( cn $ userCertificate ) MAY ( nDSPKISubjectName $ nDSPKINotBefore $ nDSPKINotAfter $ externalName $ givenName $ sn ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'ndspkiContainer' 'nDSPKITrustedRoot' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.7 NAME 'ndspkiCRLConfiguration' SUP Top STRUCTURAL MUST cn MAY ( ndspkiCRLFileName $ ndspkiDirectory $ ndspkiStatus $ ndspkiIssueTime $ ndspkiNextIssueTime $ ndspkiAttemptTime $ ndspkiTimeInterval $ ndspkiCRLMaxProcessingInterval $ ndspkiCRLNumber $ ndspkiDistributionPoints $ ndspkiDistributionPointDN $ ndspkiCADN $ ndspkiCRLProcessData $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKIParentCA $ nDSPKIParentCADN $ nDSPKISubjectName $ cACertificate $ hostServer ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'ndspkiContainer' )", + "( 2.5.6.19 NAME 'cRLDistributionPoint' SUP Top STRUCTURAL MUST cn MAY ( authorityRevocationList $ authorityRevocationList $ cACertificate $ certificateRevocationList $ certificateRevocationList $ crossCertificatePair $ deltaRevocationList $ deltaRevocationList $ ndspkiCRLConfigurationDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'sASSecurity' 'domain' 'ndspkiCRLConfiguration' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.7.6.1 NAME 'notfTemplateCollection' SUP Top STRUCTURAL MUST cn MAY ( notfSMTPEmailHost $ notfSMTPEmailFrom $ notfSMTPEmailUserName $ sASSecretStore ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.7.6.2 NAME 'notfMergeTemplate' SUP Top STRUCTURAL MUST cn MAY ( notfMergeTemplateData $ notfMergeTemplateSubject ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'notfTemplateCollection' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.44.6.1 NAME 'nsimChallengeSet' SUP Top STRUCTURAL MUST cn MAY ( description $ nsimRequiredQuestions $ nsimRandomQuestions $ nsimNumberRandomQuestions $ nsimMinResponseLength $ nsimMaxResponseLength ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'nspmPasswordPolicyContainer' 'Country' 'domain' 'Locality' 'Organization' 'organizationalUnit' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.266.6.1 NAME 'sssServerPolicies' SUP Top STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimestamps $ sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sssAdminGALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.266.6.2 NAME 'sssServerPolicyOverride' SUP Top STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimestamps $ sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sssAdminGALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sssServerPolicies' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'domain' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.91 NAME 'nestedGroupAux' AUXILIARY MAY ( groupMember $ excludedMember $ nestedConfig $ groupMembership ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.46.1 NAME 'rbsCategory2' SUP Top STRUCTURAL MUST cn MAY ( rbsRoleMember $ rbsXMLInfo $ rbsParameters $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' X-NDS_NOT_CONTAINER '1' )" + ] + }, + "schema_entry": "cn=schema", + "type": "SchemaInfo" +} +""" + +edir_8_8_8_dsa_info = """ +{ + "raw": { + "abandonOps": [ + "0" + ], + "addEntryOps": [ + "947" + ], + "altServer": [], + "bindSecurityErrors": [ + "3" + ], + "chainings": [ + "0" + ], + "compareOps": [ + "61" + ], + "directoryTreeName": [ + "EDIR-TEST" + ], + "dsaName": [ + "cn=edir1,o=services" + ], + "errors": [ + "984" + ], + "extendedOps": [ + "213" + ], + "inBytes": [ + "1253717" + ], + "inOps": [ + "14342" + ], + "listOps": [ + "0" + ], + "modifyEntryOps": [ + "121" + ], + "modifyRDNOps": [ + "63" + ], + "namingContexts": [ + "" + ], + "oneLevelSearchOps": [ + "129" + ], + "outBytes": [ + "547685251" + ], + "readOps": [ + "7427" + ], + "referralsReturned": [ + "0" + ], + "removeEntryOps": [ + "146" + ], + "repUpdatesIn": [ + "0" + ], + "repUpdatesOut": [ + "0" + ], + "searchOps": [ + "8316" + ], + "securityErrors": [ + "3" + ], + "simpleAuthBinds": [ + "1654" + ], + "strongAuthBinds": [ + "57" + ], + "subschemaSubentry": [ + "cn=schema" + ], + "supportedControl": [ + "2.16.840.1.113719.1.27.101.6", + "2.16.840.1.113719.1.27.101.5", + "1.2.840.113556.1.4.319", + "2.16.840.1.113730.3.4.3", + "2.16.840.1.113730.3.4.2", + "2.16.840.1.113719.1.27.103.7", + "2.16.840.1.113719.1.27.101.40", + "2.16.840.1.113719.1.27.101.41", + "1.2.840.113556.1.4.1413", + "1.2.840.113556.1.4.805" + ], + "supportedExtension": [ + "2.16.840.1.113719.1.148.100.1", + "2.16.840.1.113719.1.148.100.3", + "2.16.840.1.113719.1.148.100.5", + "2.16.840.1.113719.1.148.100.7", + "2.16.840.1.113719.1.148.100.9", + "2.16.840.1.113719.1.148.100.11", + "2.16.840.1.113719.1.148.100.13", + "2.16.840.1.113719.1.148.100.15", + "2.16.840.1.113719.1.148.100.17", + "2.16.840.1.113719.1.39.42.100.1", + "2.16.840.1.113719.1.39.42.100.3", + "2.16.840.1.113719.1.39.42.100.5", + "2.16.840.1.113719.1.39.42.100.7", + "2.16.840.1.113719.1.39.42.100.9", + "2.16.840.1.113719.1.39.42.100.11", + "2.16.840.1.113719.1.39.42.100.13", + "2.16.840.1.113719.1.39.42.100.15", + "2.16.840.1.113719.1.39.42.100.17", + "2.16.840.1.113719.1.39.42.100.19", + "2.16.840.1.113719.1.39.42.100.21", + "2.16.840.1.113719.1.39.42.100.23", + "2.16.840.1.113719.1.39.42.100.25", + "2.16.840.1.113719.1.39.42.100.27", + "2.16.840.1.113719.1.27.100.1", + "2.16.840.1.113719.1.27.100.3", + "2.16.840.1.113719.1.27.100.5", + "2.16.840.1.113719.1.27.100.7", + "2.16.840.1.113719.1.27.100.11", + "2.16.840.1.113719.1.27.100.13", + "2.16.840.1.113719.1.27.100.15", + "2.16.840.1.113719.1.27.100.17", + "2.16.840.1.113719.1.27.100.19", + "2.16.840.1.113719.1.27.100.21", + "2.16.840.1.113719.1.27.100.23", + "2.16.840.1.113719.1.27.100.25", + "2.16.840.1.113719.1.27.100.27", + "2.16.840.1.113719.1.27.100.29", + "2.16.840.1.113719.1.27.100.31", + "2.16.840.1.113719.1.27.100.33", + "2.16.840.1.113719.1.27.100.35", + "2.16.840.1.113719.1.27.100.37", + "2.16.840.1.113719.1.27.100.39", + "2.16.840.1.113719.1.27.100.41", + "2.16.840.1.113719.1.27.100.96", + "2.16.840.1.113719.1.27.100.98", + "2.16.840.1.113719.1.27.100.101", + "2.16.840.1.113719.1.27.100.103", + "2.16.840.1.113719.1.142.100.1", + "2.16.840.1.113719.1.142.100.4", + "2.16.840.1.113719.1.142.100.6", + "2.16.840.1.113719.1.27.100.9", + "2.16.840.1.113719.1.27.100.43", + "2.16.840.1.113719.1.27.100.45", + "2.16.840.1.113719.1.27.100.47", + "2.16.840.1.113719.1.27.100.49", + "2.16.840.1.113719.1.27.100.51", + "2.16.840.1.113719.1.27.100.53", + "2.16.840.1.113719.1.27.100.55", + "1.3.6.1.4.1.1466.20037", + "2.16.840.1.113719.1.27.100.79", + "2.16.840.1.113719.1.27.100.84", + "2.16.840.1.113719.1.27.103.1", + "2.16.840.1.113719.1.27.103.2" + ], + "supportedFeatures": [ + "1.3.6.1.4.1.4203.1.5.1", + "2.16.840.1.113719.1.27.99.1" + ], + "supportedGroupingTypes": [ + "2.16.840.1.113719.1.27.103.8" + ], + "supportedLDAPVersion": [ + "2", + "3" + ], + "supportedSASLMechanisms": [ + "NMAS_LOGIN", + "EXTERNAL", + "DIGEST-MD5", + "GSSAPI" + ], + "unAuthBinds": [ + "1897" + ], + "vendorName": [ + "NetIQ Corporation" + ], + "vendorVersion": [ + "LDAP Agent for NetIQ eDirectory 8.8 SP8 (20804.04)" + ], + "wholeSubtreeSearchOps": [ + "760" + ] + }, + "type": "DsaInfo" +} +""" diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir914.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir914.py new file mode 100644 index 00000000..1ef20615 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/edir914.py @@ -0,0 +1,1157 @@ +""" +""" + +# Created on 2019.08.31 +# +# 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 . + +edir_9_1_4_schema = """ +{ + "raw": { + "attributeTypes": [ + "( 2.5.4.35 NAME 'userPassword' DESC 'Internal NDS policy forces this to be single-valued' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} USAGE directoryOperation )", + "( 2.5.18.1 NAME 'createTimestamp' DESC 'Operational Attribute' 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 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.5.18.10 NAME 'subschemaSubentry' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation )", + "( 2.5.21.9 NAME 'structuralObjectClass' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.49 NAME 'subordinateCount' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.48 NAME 'entryFlags' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.27.4.51 NAME 'federationBoundary' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.5.21.5 NAME 'attributeTypes' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )", + "( 2.5.21.6 NAME 'objectClasses' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )", + "( 1.3.6.1.1.20 NAME 'entryDN' DESC 'Operational Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.1.4.1.2 NAME 'ACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.4.1 NAME 'aliasedObjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Aliased Object Name' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.6 NAME 'backLink' SYNTAX 2.16.840.1.113719.1.1.5.1.23 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Back Link' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.8 NAME 'binderyProperty' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Property' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.7 NAME 'binderyObjectRestriction' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Object Restriction' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.9 NAME 'binderyType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Bindery Type' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.11 NAME 'cAPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'CA Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.12 NAME 'cAPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'CA Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.10 NAME 'Cartridge' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.3 NAME ( 'cn' 'commonName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'CN' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.78 NAME 'printerConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Printer Configuration' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.15 NAME 'Convergence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{1} SINGLE-VALUE X-NDS_UPPER_BOUND '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.6 NAME ( 'c' 'countryName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2} SINGLE-VALUE X-NDS_NAME 'C' X-NDS_LOWER_BOUND '2' X-NDS_UPPER_BOUND '2' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.18 NAME 'defaultQueue' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Default Queue' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.13 NAME ( 'description' 'multiLineDescription' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} X-NDS_NAME 'Description' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '1024' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.64 NAME 'partitionCreationTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Creation Time' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.23 NAME 'facsimileTelephoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22{64512} X-NDS_NAME 'Facsimile Telephone Number' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.117 NAME 'highConvergenceSyncInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_NAME 'High Convergence Sync Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.25 NAME 'groupMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Group Membership' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.26 NAME 'ndsHomeDirectory' SYNTAX 2.16.840.1.113719.1.1.5.1.15{255} SINGLE-VALUE X-NDS_NAME 'Home Directory' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.27 NAME 'hostDevice' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Device' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.28 NAME 'hostResourceName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Host Resource Name' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.29 NAME 'hostServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Host Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.30 NAME 'inheritedACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Inherited ACL' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.7 NAME ( 'l' 'localityname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'L' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.39 NAME 'loginAllowedTimeMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{42} SINGLE-VALUE X-NDS_NAME 'Login Allowed Time Map' X-NDS_LOWER_BOUND '42' X-NDS_UPPER_BOUND '42' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.40 NAME 'loginDisabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Login Disabled' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.41 NAME 'loginExpirationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Expiration Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.42 NAME 'loginGraceLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Grace Limit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.43 NAME 'loginGraceRemaining' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Grace Remaining' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.44 NAME 'loginIntruderAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.12 SINGLE-VALUE X-NDS_NAME 'Login Intruder Address' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.45 NAME 'loginIntruderAttempts' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Login Intruder Attempts' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.46 NAME 'loginIntruderLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Intruder Limit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.31 NAME 'intruderAttemptResetInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder Attempt Reset Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.47 NAME 'loginIntruderResetTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Intruder Reset Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.48 NAME 'loginMaximumSimultaneous' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Login Maximum Simultaneous' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.49 NAME 'loginScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Login Script' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.50 NAME 'loginTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Login Time' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.31 NAME ( 'member' 'uniqueMember' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Member' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.52 NAME 'Memory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.22 NAME 'eMailAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.14{64512} X-NDS_NAME 'EMail Address' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.55 NAME 'networkAddress' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.56 NAME 'networkAddressRestriction' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NAME 'Network Address Restriction' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.57 NAME 'notify' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Notify' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.114 NAME 'Obituary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.0 NAME 'objectClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-NDS_NAME 'Object Class' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.59 NAME 'operator' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Operator' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'OU' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.10 NAME ( 'o' 'organizationname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'O' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.32 NAME 'owner' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Owner' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.63 NAME 'pageDescriptionLanguage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} X-NDS_NAME 'Page Description Language' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.65 NAME 'passwordsUsed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'Passwords Used' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.66 NAME 'passwordAllowChange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Allow Change' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.67 NAME 'passwordExpirationInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_NAME 'Password Expiration Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.68 NAME 'passwordExpirationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NAME 'Password Expiration Time' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.69 NAME 'passwordMinimumLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Password Minimum Length' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.70 NAME 'passwordRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Required' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.71 NAME 'passwordUniqueRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Password Unique Required' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.72 NAME 'path' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'Path' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.19 NAME 'physicalDeliveryOfficeName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'Physical Delivery Office Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.16 NAME 'postalAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} X-NDS_NAME 'Postal Address' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.17 NAME 'postalCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} X-NDS_NAME 'Postal Code' X-NDS_UPPER_BOUND '40' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.18 NAME 'postOfficeBox' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} X-NDS_NAME 'Postal Office Box' X-NDS_UPPER_BOUND '40' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.80 NAME 'printJobConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Print Job Configuration' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.79 NAME 'printerControl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Printer Control' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.82 NAME 'privateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Private Key' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.83 NAME 'Profile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.84 NAME 'publicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Public Key' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.85 NAME 'queue' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Queue' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.86 NAME 'queueDirectory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-NDS_NAME 'Queue Directory' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '255' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.115 NAME 'Reference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.88 NAME 'Replica' SYNTAX 2.16.840.1.113719.1.1.5.1.16{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.89 NAME 'Resource' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.33 NAME 'roleOccupant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Role Occupant' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.116 NAME 'higherPrivileges' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Higher Privileges' X-NDS_SERVER_READ '1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.92 NAME 'securityEquals' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Security Equals' X-NDS_SERVER_READ '1' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.4.34 NAME 'seeAlso' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'See Also' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.5 NAME 'serialNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} X-NDS_NAME 'Serial Number' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.95 NAME 'server' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Server' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'S' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.98 NAME 'status' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Status' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' )", + "( 2.5.4.9 NAME 'street' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'SA' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.102 NAME 'supportedTypefaces' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Typefaces' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.101 NAME 'supportedServices' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Supported Services' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.4 NAME ( 'sn' 'surname' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Surname' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} X-NDS_NAME 'Telephone Number' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.12 NAME 'title' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'Title' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.111 NAME 'User' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.112 NAME 'Version' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.1 NAME 'accountBalance' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_NAME 'Account Balance' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.4 NAME 'allowUnlimitedCredit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Allow Unlimited Credit' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.118 NAME 'lowConvergenceResetTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Low Convergence Reset Time' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.54 NAME 'minimumAccountBalance' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Minimum Account Balance' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.104 NAME 'lowConvergenceSyncInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_NAME 'Low Convergence Sync Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.21 NAME 'Device' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.53 NAME 'messageServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Message Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.34 NAME 'Language' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.100 NAME 'supportedConnections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Supported Connections' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.107 NAME 'typeCreatorMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Type Creator Map' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.108 NAME 'ndsUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'UID' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.24 NAME 'groupID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'GID' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.110 NAME 'unknownBaseClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Unknown Base Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.87 NAME 'receivedUpTo' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.33 NAME 'synchronizedUpTo' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Synchronized Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.5 NAME 'authorityRevocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Authority Revocation' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.13 NAME 'certificateRevocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Certificate Revocation' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.17 NAME 'ndsCrossCertificatePair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'Cross Certificate Pair' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.37 NAME 'lockedByIntruder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Locked By Intruder' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.77 NAME 'printer' SYNTAX 2.16.840.1.113719.1.1.5.1.25 X-NDS_NAME 'Printer' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.20 NAME 'detectIntruder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Detect Intruder' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.38 NAME 'lockoutAfterDetection' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Lockout After Detection' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.32 NAME 'intruderLockoutResetInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_NAME 'Intruder Lockout Reset Interval' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.96 NAME 'serverHolds' SYNTAX 2.16.840.1.113719.1.1.5.1.26 X-NDS_NAME 'Server Holds' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.91 NAME 'sAPName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{47} SINGLE-VALUE X-NDS_NAME 'SAP Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '47' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.113 NAME 'Volume' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.35 NAME 'lastLoginTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Last Login Time' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.81 NAME 'printServer' SYNTAX 2.16.840.1.113719.1.1.5.1.25 SINGLE-VALUE X-NDS_NAME 'Print Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.119 NAME 'nNSDomain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_NAME 'NNS Domain' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.120 NAME 'fullName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-NDS_NAME 'Full Name' X-NDS_UPPER_BOUND '127' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.121 NAME 'partitionControl' SYNTAX 2.16.840.1.113719.1.1.5.1.25 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Control' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.122 NAME 'revision' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Revision' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.123 NAME 'certificateValidityInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'Certificate Validity Interval' X-NDS_LOWER_BOUND '60' X-NDS_UPPER_BOUND '-1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.124 NAME 'externalSynchronizer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'External Synchronizer' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.125 NAME 'messagingDatabaseLocation' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Messaging Database Location' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.126 NAME 'messageRoutingGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Message Routing Group' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.127 NAME 'messagingServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Messaging Server' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.128 NAME 'Postmaster' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.162 NAME 'mailboxLocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Mailbox Location' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.163 NAME 'mailboxID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Mailbox ID' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.164 NAME 'externalName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'External Name' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.165 NAME 'securityFlags' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Security Flags' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.166 NAME 'messagingServerType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE X-NDS_NAME 'Messaging Server Type' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.167 NAME 'lastReferencedTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Last Referenced Time' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.4.42 NAME 'givenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} X-NDS_NAME 'Given Name' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.43 NAME 'initials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} X-NDS_NAME 'Initials' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.4.44 NAME 'generationQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Generational Qualifier' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '8' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.171 NAME 'profileMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Profile Membership' X-NDS_NAME_VALUE_ACCESS '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.172 NAME 'dsRevision' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'DS Revision' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_OPERATIONAL '1' )", + "( 2.16.840.1.113719.1.1.4.1.173 NAME 'supportedGateway' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} X-NDS_NAME 'Supported Gateway' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '4096' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.174 NAME 'equivalentToMe' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Equivalent To Me' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.16.840.1.113719.1.1.4.1.175 NAME 'replicaUpTo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Replica Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.176 NAME 'partitionStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Partition Status' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.177 NAME 'permanentConfigParms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'Permanent Config Parms' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.178 NAME 'Timezone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.179 NAME 'binderyRestrictionLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Bindery Restriction Level' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.180 NAME 'transitiveVector' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Transitive Vector' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.181 NAME 'T' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.183 NAME 'purgeVector' SYNTAX 2.16.840.1.113719.1.1.5.1.19 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Purge Vector' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_SCHED_SYNC_NEVER '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.184 NAME 'synchronizationTolerance' SYNTAX 2.16.840.1.113719.1.1.5.1.19 USAGE directoryOperation X-NDS_NAME 'Synchronization Tolerance' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.185 NAME 'passwordManagement' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'Password Management' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.186 NAME 'usedBy' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Used By' X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.187 NAME 'Uses' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_SERVER_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.500 NAME 'obituaryNotify' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Obituary Notify' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.501 NAME 'GUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{16} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.502 NAME 'otherGUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{16} USAGE directoryOperation X-NDS_NAME 'Other GUID' X-NDS_LOWER_BOUND '16' X-NDS_UPPER_BOUND '16' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.503 NAME 'auxiliaryClassFlag' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Auxiliary Class Flag' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.504 NAME 'unknownAuxiliaryClass' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} USAGE directoryOperation X-NDS_NAME 'Unknown Auxiliary Class' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userId' ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} X-NDS_NAME 'uniqueID' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 0.9.2342.19200300.100.1.25 NAME 'dc' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} X-NDS_NAME 'dc' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '64' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.507 NAME 'auxClassObjectClassBackup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'AuxClass Object Class Backup' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.508 NAME 'localReceivedUpTo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NAME 'Local Received Up To' X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.4 NAME 'federationControl' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.2 NAME 'federationSearchPath' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.3 NAME 'federationDNSName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.141.4.1 NAME 'federationBoundaryType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.14.4.1.4 NAME 'DirXML-Associations' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' )", + "( 2.5.18.3 NAME 'creatorsName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.5.18.4 NAME 'modifiersName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_FILTERED_REQUIRED '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.300 NAME 'languageId' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.35 NAME 'ndsPredicate' SYNTAX 2.16.840.1.113719.1.1.5.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.36 NAME 'ndsPredicateState' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.37 NAME 'ndsPredicateFlush' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.38 NAME 'ndsPredicateTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.40 NAME 'ndsPredicateStatsDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.4.39 NAME 'ndsPredicateUseValues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.601 NAME 'syncPanePoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.600 NAME 'syncWindowVector' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.602 NAME 'objectVersion' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.27.4.52 NAME 'memberQueryURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'memberQuery' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.302 NAME 'excludedMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.1.525 NAME 'auxClassCompatibility' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.518 NAME 'ndsAgentPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.519 NAME 'ndsOperationCheckpoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.520 NAME 'localReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.521 NAME 'treeReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.522 NAME 'schemaResetLock' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.523 NAME 'modifiedACLEntry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.524 NAME 'monitoredConnection' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.526 NAME 'localFederationBoundary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.527 NAME 'replicationFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.721 NAME 'ServerEBAEnabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.716 NAME 'EBATreeConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.722 NAME 'EBAPartitionConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.723 NAME 'EBAServerConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.1.4.1.296 NAME 'loginActivationTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.687 NAME 'UpdateInProgress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.720 NAME 'dsContainerReadyAttrs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.4.400.1 NAME 'edirSchemaFlagVersion' SYNTAX 2.16.840.1.113719.1.1.5.1.0 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NONREMOVABLE '1' X-NDS_HIDDEN '1' X-NDS_READ_FILTERED '1' )", + "( 2.16.840.1.113719.1.1.4.1.512 NAME 'indexDefinition' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.513 NAME 'ndsStatusRepair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.514 NAME 'ndsStatusExternalReference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.515 NAME 'ndsStatusObituary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.516 NAME 'ndsStatusSchema' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.517 NAME 'ndsStatusLimber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.511 NAME 'authoritative' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113730.3.1.34 NAME 'ref' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.546 NAME 'CachedAttrsOnExtRefs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.547 NAME 'ExtRefLastUpdatedTime' SYNTAX 2.16.840.1.113719.1.1.5.1.19 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-NDS_PUBLIC_READ '1' X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.688 NAME 'NCPKeyMaterialName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.1.4.713 NAME 'UTF8LoginScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.714 NAME 'loginScriptCharset' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.721 NAME 'NDSRightsToMonitor' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NEVER_SYNC '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.1.192 NAME 'lDAPLogLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Log Level' X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.27.4.12 NAME 'lDAPUDPPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP UDP Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.1.4.1.204 NAME 'lDAPLogFilename' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Log Filename' )", + "( 2.16.840.1.113719.1.1.4.1.205 NAME 'lDAPBackupLogFilename' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Backup Log Filename' )", + "( 2.16.840.1.113719.1.1.4.1.206 NAME 'lDAPLogSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Log Size Limit' X-NDS_LOWER_BOUND '2048' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.1.4.1.194 NAME 'lDAPSearchSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP Search Size Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.1.4.1.195 NAME 'lDAPSearchTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_NAME 'LDAP Search Time Limit' X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.1.4.1.207 NAME 'lDAPSuffix' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Suffix' )", + "( 2.16.840.1.113719.1.27.4.70 NAME 'ldapConfigVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.14 NAME 'ldapReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Referral' )", + "( 2.16.840.1.113719.1.27.4.73 NAME 'ldapDefaultReferralBehavior' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.23 NAME 'ldapSearchReferralUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:searchReferralUsage' )", + "( 2.16.840.1.113719.1.27.4.24 NAME 'lDAPOtherReferralUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'LDAP:otherReferralUsage' )", + "( 2.16.840.1.113719.1.27.4.1 NAME 'ldapHostServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Host Server' )", + "( 2.16.840.1.113719.1.27.4.2 NAME 'ldapGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Group' )", + "( 2.16.840.1.113719.1.27.4.3 NAME 'ldapTraceLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_NAME 'LDAP Screen Level' X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.27.4.4 NAME 'searchSizeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.27.4.5 NAME 'searchTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{2147483647} SINGLE-VALUE X-NDS_UPPER_BOUND '2147483647' )", + "( 2.16.840.1.113719.1.27.4.6 NAME 'ldapServerBindLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Server Bind Limit' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.27.4.7 NAME 'ldapServerIdleTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{4294967295} SINGLE-VALUE X-NDS_NAME 'LDAP Server Idle Timeout' X-NDS_UPPER_BOUND '-1' )", + "( 2.16.840.1.113719.1.27.4.8 NAME 'ldapEnableTCP' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable TCP' )", + "( 2.16.840.1.113719.1.27.4.10 NAME 'ldapEnableSSL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Enable SSL' )", + "( 2.16.840.1.113719.1.27.4.11 NAME 'ldapTCPPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP TCP Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.27.4.13 NAME 'ldapSSLPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{65535} SINGLE-VALUE X-NDS_NAME 'LDAP SSL Port' X-NDS_UPPER_BOUND '65535' )", + "( 2.16.840.1.113719.1.27.4.21 NAME 'filteredReplicaUsage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.22 NAME 'ldapKeyMaterialName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'LDAP:keyMaterialName' )", + "( 2.16.840.1.113719.1.27.4.42 NAME 'extensionInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.27.4.45 NAME 'nonStdClientSchemaCompatMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.46 NAME 'sslEnableMutualAuthentication' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.62 NAME 'ldapEnablePSearch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.63 NAME 'ldapMaximumPSearchOperations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.64 NAME 'ldapIgnorePSearchLimitsForEvents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.65 NAME 'ldapTLSTrustedRootContainer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.27.4.66 NAME 'ldapEnableMonitorEvents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.67 NAME 'ldapMaximumMonitorEventsLoad' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.68 NAME 'ldapTLSRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.69 NAME 'ldapTLSVerifyClientCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.71 NAME 'ldapDerefAlias' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.72 NAME 'ldapNonStdAllUserAttrsMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.75 NAME 'ldapBindRestrictions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.79 NAME 'ldapInterfaces' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.27.4.80 NAME 'ldapChainSecureRequired' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.82 NAME 'ldapStdCompliance' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.83 NAME 'ldapDerefAliasOnAuth' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.84 NAME 'ldapGeneralizedTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.85 NAME 'ldapPermissiveModify' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.86 NAME 'ldapSSLConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.27.4.15 NAME 'ldapServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server List' )", + "( 2.16.840.1.113719.1.27.4.16 NAME 'ldapAttributeMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Attribute Map v11' )", + "( 2.16.840.1.113719.1.27.4.17 NAME 'ldapClassMap' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'LDAP Class Map v11' )", + "( 2.16.840.1.113719.1.27.4.18 NAME 'ldapAllowClearTextPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'LDAP Allow Clear Text Password' )", + "( 2.16.840.1.113719.1.27.4.19 NAME 'ldapAnonymousIdentity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'LDAP Anonymous Identity' )", + "( 2.16.840.1.113719.1.27.4.52 NAME 'ldapAttributeList' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} )", + "( 2.16.840.1.113719.1.27.4.53 NAME 'ldapClassList' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} )", + "( 2.16.840.1.113719.1.27.4.56 NAME 'transitionGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.74 NAME 'ldapTransitionBackLink' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.78 NAME 'ldapLBURPNumWriterThreads' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.27.4.20 NAME 'ldapServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'LDAP Server' )", + "( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'Internet EMail Address' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'NSCP:employeeNumber' )", + "( 2.16.840.1.113719.1.27.4.76 NAME 'referralExcludeFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.27.4.77 NAME 'referralIncludeFilter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.5.4.36 NAME 'userCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'userCertificate' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.37 NAME 'cACertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'cACertificate' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.40 NAME 'crossCertificatePair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'crossCertificatePair' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.58 NAME 'attributeCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.2 NAME 'knowledgeInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 2.5.4.14 NAME 'searchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.25{64512} X-NDS_NAME 'searchGuide' )", + "( 2.5.4.15 NAME 'businessCategory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' )", + "( 2.5.4.21 NAME 'telexNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.52{64512} X-NDS_NAME 'telexNumber' )", + "( 2.5.4.22 NAME 'teletexTerminalIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51{64512} X-NDS_NAME 'teletexTerminalIdentifier' )", + "( 2.5.4.24 NAME 'x121Address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '15' )", + "( 2.5.4.25 NAME 'internationaliSDNNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '16' )", + "( 2.5.4.26 NAME 'registeredAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} X-NDS_NAME 'registeredAddress' )", + "( 2.5.4.27 NAME 'destinationIndicator' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '128' )", + "( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.14{64512} SINGLE-VALUE X-NDS_NAME 'preferredDeliveryMethod' )", + "( 2.5.4.29 NAME 'presentationAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.43{64512} SINGLE-VALUE X-NDS_NAME 'presentationAddress' )", + "( 2.5.4.30 NAME 'supportedApplicationContext' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38{64512} X-NDS_NAME 'supportedApplicationContext' )", + "( 2.5.4.45 NAME 'x500UniqueIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6{64512} X-NDS_NAME 'x500UniqueIdentifier' )", + "( 2.5.4.46 NAME 'dnQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64512} )", + "( 2.5.4.47 NAME 'enhancedSearchGuide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21{64512} X-NDS_NAME 'enhancedSearchGuide' )", + "( 2.5.4.48 NAME 'protocolInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.42{64512} X-NDS_NAME 'protocolInformation' )", + "( 2.5.4.51 NAME 'houseIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 2.5.4.52 NAME 'supportedAlgorithms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.49{64512} X-NDS_NAME 'supportedAlgorithms' )", + "( 2.5.4.54 NAME 'dmdName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '32768' )", + "( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.38 NAME 'associatedName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.5.4.49 NAME 'dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.1 NAME 'httpServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.3.4.2 NAME 'httpHostServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.3 NAME 'httpThreadsPerCPU' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.4 NAME 'httpIOBufferSize' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.5 NAME 'httpRequestTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.6 NAME 'httpKeepAliveRequestTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.7 NAME 'httpSessionTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.8 NAME 'httpKeyMaterialObject' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.9 NAME 'httpTraceLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.10 NAME 'httpAuthRequiresTLS' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.11 NAME 'httpDefaultClearPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.12 NAME 'httpDefaultTLSPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.3.4.13 NAME 'httpBindRestrictions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.295 NAME 'emboxConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.54.4.1.1 NAME 'trusteesOfNewObject' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'Trustees Of New Object' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.55.4.1.1 NAME 'newObjectSDSRights' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object's DS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.56.4.1.1 NAME 'newObjectSFSRights' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'New Object's FS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.57.4.1.1 NAME 'setupScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'Setup Script' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.58.4.1.1 NAME 'runSetupScript' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Run Setup Script' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.59.4.1.1 NAME 'membersOfTemplate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Members Of Template' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.60.4.1.1 NAME 'volumeSpaceRestrictions' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'Volume Space Restrictions' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.61.4.1.1 NAME 'setPasswordAfterCreate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'Set Password After Create' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.62.4.1.1 NAME 'homeDirectoryRights' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_NAME 'Home Directory Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.63.4.1.1 NAME 'newObjectSSelfRights' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object's Self Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.8.4.1 NAME 'digitalMeID' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.8.4.2 NAME 'assistant' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.8.4.3 NAME 'assistantPhone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.4 NAME 'city' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.5 NAME 'company' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.43 NAME 'co' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.6 NAME 'directReports' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 0.9.2342.19200300.100.1.10 NAME 'manager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.8.4.7 NAME 'mailstop' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.41 NAME 'mobile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.42 NAME 'pager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.8 NAME 'workforceID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.9 NAME 'instantMessagingID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.10 NAME 'preferredName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.8.4.11 NAME 'jobCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.12 NAME 'siteLocation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.13 NAME 'employeeStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.4 NAME 'employeeType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.14 NAME 'costCenter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.15 NAME 'costCenterDescription' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.16 NAME 'tollFreePhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.17 NAME 'otherPhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.18 NAME 'managerWorkforceID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.19 NAME 'jackNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.20 NAME 'vehicleInformation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.21 NAME 'accessCardNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.32 NAME 'isManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.8.4.22 NAME 'homeCity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.23 NAME 'homeEmailAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 1.3.6.1.4.1.1466.101.120.31 NAME 'homeFax' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 0.9.2342.19200300.100.1.20 NAME 'homePhone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.24 NAME 'homeState' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41{64512} )", + "( 2.16.840.1.113719.1.8.4.25 NAME 'homeZipCode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.26 NAME 'personalMobile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.8.4.27 NAME 'children' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.28 NAME 'spouse' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.29 NAME 'vendorName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.30 NAME 'vendorAddress' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.8.4.31 NAME 'vendorPhoneNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{64512} )", + "( 2.16.840.1.113719.1.1.4.1.303 NAME 'dgIdentity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME_VALUE_ACCESS '1' )", + "( 2.16.840.1.113719.1.1.4.1.304 NAME 'dgTimeOut' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.305 NAME 'dgAllowUnknown' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.306 NAME 'dgAllowDuplicates' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.546 NAME 'allowAliasToAncestor' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.39.4.1.1 NAME 'sASSecurityDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Security DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.4.1.2 NAME 'sASServiceDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Service DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.4.1.3 NAME 'sASSecretStore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:SecretStore' )", + "( 2.16.840.1.113719.1.39.4.1.4 NAME 'sASSecretStoreKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_NAME 'SAS:SecretStore:Key' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.5 NAME 'sASSecretStoreData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'SAS:SecretStore:Data' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.6 NAME 'sASPKIStoreKeys' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'SAS:PKIStore:Keys' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.48.4.1.1 NAME 'nDSPKIPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.2 NAME 'nDSPKIPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Private Key' )", + "( 2.16.840.1.113719.1.48.4.1.3 NAME 'nDSPKIPublicKeyCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key Certificate' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.4 NAME 'nDSPKICertificateChain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:Certificate Chain' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.16 NAME 'nDSPKIPublicKeyEC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key EC' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.17 NAME 'nDSPKIPrivateKeyEC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Private Key EC' )", + "( 2.16.840.1.113719.1.48.4.1.18 NAME 'nDSPKIPublicKeyCertificateEC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Public Key Certificate EC' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.19 NAME 'crossCertificatePairEC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'Cross Certificate Pair EC' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.20 NAME 'nDSPKICertificateChainEC' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:Certificate Chain EC' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.5 NAME 'nDSPKIParentCA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA' )", + "( 2.16.840.1.113719.1.48.4.1.6 NAME 'nDSPKIParentCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'NDSPKI:Parent CA DN' )", + "( 2.16.840.1.113719.1.48.4.1.20 NAME 'nDSPKISuiteBMode' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'NDSPKI:SuiteBMode' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.7 NAME 'nDSPKIKeyFile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Key File' )", + "( 2.16.840.1.113719.1.48.4.1.8 NAME 'nDSPKISubjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Subject Name' )", + "( 2.16.840.1.113719.1.48.4.1.11 NAME 'nDSPKIGivenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Given Name' )", + "( 2.16.840.1.113719.1.48.4.1.9 NAME 'nDSPKIKeyMaterialDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Key Material DN' )", + "( 2.16.840.1.113719.1.48.4.1.10 NAME 'nDSPKITreeCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:Tree CA DN' )", + "( 2.5.4.59 NAME 'cAECCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.12 NAME 'nDSPKIUserCertificateInfo' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'NDSPKI:userCertificateInfo' )", + "( 2.16.840.1.113719.1.48.4.1.13 NAME 'nDSPKITrustedRootCertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Trusted Root Certificate' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.14 NAME 'nDSPKINotBefore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not Before' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.15 NAME 'nDSPKINotAfter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:Not After' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.101 NAME 'nDSPKISDKeyServerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'NDSPKI:SD Key Server DN' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.102 NAME 'nDSPKISDKeyStruct' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'NDSPKI:SD Key Struct' )", + "( 2.16.840.1.113719.1.48.4.1.103 NAME 'nDSPKISDKeyCert' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key Cert' )", + "( 2.16.840.1.113719.1.48.4.1.104 NAME 'nDSPKISDKeyID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'NDSPKI:SD Key ID' )", + "( 2.16.840.1.113719.1.39.4.1.105 NAME 'nDSPKIKeystore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_NAME 'NDSPKI:Keystore' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.4.1.106 NAME 'ndspkiAdditionalRoots' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.3 NAME 'masvLabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.4 NAME 'masvProposedLabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.5 NAME 'masvDefaultRange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.6 NAME 'masvAuthorizedRange' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.2.7 NAME 'masvDomainPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.8 NAME 'masvClearanceNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.9 NAME 'masvLabelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.10 NAME 'masvLabelSecrecyLevelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.11 NAME 'masvLabelSecrecyCategoryNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.12 NAME 'masvLabelIntegrityLevelNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.13 NAME 'masvLabelIntegrityCategoryNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.14 NAME 'masvPolicyUpdate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.31.4.1.16 NAME 'masvNDSAttributeLabels' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.31.4.1.15 NAME 'masvPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.2 NAME 'sASLoginSequence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_NAME 'SAS:Login Sequence' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.8 NAME 'sASLoginPolicyUpdate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Login Policy Update' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'sasNMASProductOptions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.74 NAME 'sasAuditConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.14 NAME 'sASNDSPasswordWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:NDS Password Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.15 NAME 'sASPolicyCredentials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Policy Credentials' X-NDS_SERVER_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.16 NAME 'sASPolicyMethods' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Methods' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.17 NAME 'sASPolicyObjectVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Policy Object Version' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.18 NAME 'sASPolicyServiceSubtypes' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Service Subtypes' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.19 NAME 'sASPolicyServices' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Services' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.20 NAME 'sASPolicyUsers' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'SAS:Policy Users' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.21 NAME 'sASAllowNDSPasswordWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'SAS:Allow NDS Password Window' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.9 NAME 'sASMethodIdentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Method Identifier' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.10 NAME 'sASMethodVendor' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Method Vendor' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.11 NAME 'sASAdvisoryMethodGrade' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Advisory Method Grade' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.12 NAME 'sASVendorSupport' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'SAS:Vendor Support' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.13 NAME 'sasCertificateSearchContainers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.70 NAME 'sasNMASMethodConfigData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.22 NAME 'sASLoginClientMethodNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Client Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.23 NAME 'sASLoginServerMethodNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Server Method NetWare' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.24 NAME 'sASLoginClientMethodWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Client Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.25 NAME 'sASLoginServerMethodWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NAME 'SAS:Login Server Method WINNT' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.26 NAME 'sasLoginClientMethodSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.27 NAME 'sasLoginServerMethodSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.28 NAME 'sasLoginClientMethodLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.29 NAME 'sasLoginServerMethodLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.30 NAME 'sasLoginClientMethodTru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.31 NAME 'sasLoginServerMethodTru64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.32 NAME 'sasLoginClientMethodAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.33 NAME 'sasLoginServerMethodAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.34 NAME 'sasLoginClientMethodHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.35 NAME 'sasLoginServerMethodHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1000 NAME 'sasLoginClientMethods390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1001 NAME 'sasLoginServerMethods390' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1002 NAME 'sasLoginClientMethodLinuxX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1003 NAME 'sasLoginServerMethodLinuxX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1004 NAME 'sasLoginClientMethodWinX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1005 NAME 'sasLoginServerMethodWinX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1006 NAME 'sasLoginClientMethodSolaris64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1007 NAME 'sasLoginServerMethodSolaris64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1008 NAME 'sasLoginClientMethodAIX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1009 NAME 'sasLoginServerMethodAIX64' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1011 NAME 'sasLoginServerMethodSolarisi386' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1012 NAME 'sasLoginClientMethodSolarisi386' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.78 NAME 'sasUnsignedMethodModules' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.79 NAME 'sasServerModuleName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.80 NAME 'sasServerModuleEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.81 NAME 'sasSASLMechanismName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.82 NAME 'sasSASLMechanismEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.83 NAME 'sasClientModuleName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.84 NAME 'sasClientModuleEntryPointName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.36 NAME 'sASLoginMethodContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Login Method Container DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.37 NAME 'sASLoginPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'SAS:Login Policy DN' X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.63 NAME 'sasPostLoginMethodContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'rADIUSActiveConnections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Active Connections' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.39 NAME 'rADIUSAgedInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Aged Interval' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.40 NAME 'rADIUSAttributeList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Attribute List' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.41 NAME 'rADIUSAttributeLists' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Attribute Lists' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.42 NAME 'rADIUSClient' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Client' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.43 NAME 'rADIUSCommonNameResolution' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Common Name Resolution' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.44 NAME 'rADIUSConcurrentLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Concurrent Limit' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.45 NAME 'rADIUSConnectionHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Connection History' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.46 NAME 'rADIUSDASVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:DAS Version' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.47 NAME 'rADIUSDefaultProfile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Default Profile' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.48 NAME 'rADIUSDialAccessGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'RADIUS:Dial Access Group' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.49 NAME 'rADIUSEnableCommonNameLogin' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS:Enable Common Name Login' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.50 NAME 'rADIUSEnableDialAccess' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NAME 'RADIUS:Enable Dial Access' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.51 NAME 'rADIUSInterimAcctingTimeout' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Interim Accting Timeout' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.52 NAME 'rADIUSLookupContexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'RADIUS:Lookup Contexts' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.53 NAME 'rADIUSMaxDASHistoryRecord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Max DAS History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.54 NAME 'rADIUSMaximumHistoryRecord' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Maximum History Record' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.55 NAME 'rADIUSPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Password' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.56 NAME 'rADIUSPasswordPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'RADIUS:Password Policy' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.57 NAME 'rADIUSPrivateKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Private Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.58 NAME 'rADIUSProxyContext' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Proxy Context' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.59 NAME 'rADIUSProxyDomain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Domain' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.60 NAME 'rADIUSProxyTarget' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'RADIUS:Proxy Target' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.61 NAME 'rADIUSPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'RADIUS:Public Key' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.62 NAME 'rADIUSServiceList' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'RADIUS:Service List' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.3 NAME 'sASLoginSecret' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.4 NAME 'sASLoginSecretKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Secret Key' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.5 NAME 'sASEncryptionType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'SAS:Encryption Type' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.6 NAME 'sASLoginConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Configuration' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.7 NAME 'sASLoginConfigurationKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'SAS:Login Configuration Key' X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.73 NAME 'sasDefaultLoginSequence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.64 NAME 'sasAuthorizedLoginSequences' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.69 NAME 'sasAllowableSubjectNames' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.71 NAME 'sasLoginFailureDelay' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.72 NAME 'sasMethodVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1010 NAME 'sasUpdateLoginInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1011 NAME 'sasOTPEnabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1012 NAME 'sasOTPCounter' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1013 NAME 'sasOTPLookAheadWindow' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1014 NAME 'sasOTPDigits' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1015 NAME 'sasOTPReSync' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.39.42.1.0.1016 NAME 'sasUpdateLoginTimeInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.6.4.1 NAME 'snmpGroupDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.2 NAME 'snmpServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.6.4.3 NAME 'snmpTrapConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.4 NAME 'snmpTrapDescription' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.5 NAME 'snmpTrapInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.6.4.6 NAME 'snmpTrapDisable' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.528 NAME 'ndapPartitionPasswordMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.529 NAME 'ndapClassPasswordMgmt' SYNTAX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.530 NAME 'ndapPasswordMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.537 NAME 'ndapPartitionLoginMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.538 NAME 'ndapClassLoginMgmt' SYNTAX 2.16.840.1.113719.1.1.5.1.0 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.539 NAME 'ndapLoginMgmt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.1 NAME 'nspmPasswordKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.2 NAME 'nspmPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.3 NAME 'nspmDistributionPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.4 NAME 'nspmPasswordHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.5 NAME 'nspmAdministratorChangeCount' SYNTAX 2.16.840.1.113719.1.1.5.1.22 SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.6 NAME 'nspmPasswordPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.7 NAME 'nspmPreviousDistributionPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.39.43.4.8 NAME 'nspmDoNotExpirePassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 1.3.6.1.4.1.42.2.27.8.1.16 NAME 'pwdChangedTime' 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' 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.19 NAME 'pwdFailureTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 NO-USER-MODIFICATION USAGE directoryOperation )", + "( 2.16.840.1.113719.1.39.43.4.100 NAME 'nspmConfigurationOptions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.102 NAME 'nspmChangePasswordMessage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.103 NAME 'nspmPasswordHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.104 NAME 'nspmPasswordHistoryExpiration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 1.3.6.1.4.1.42.2.27.8.1.4 NAME 'pwdInHistory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.105 NAME 'nspmMinPasswordLifetime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.106 NAME 'nspmAdminsDoNotExpirePassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.107 NAME 'nspmPasswordACL' SYNTAX 2.16.840.1.113719.1.1.5.1.17 )", + "( 2.16.840.1.113719.1.39.43.4.200 NAME 'nspmMaximumLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.201 NAME 'nspmMinUpperCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.202 NAME 'nspmMaxUpperCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.203 NAME 'nspmMinLowerCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.204 NAME 'nspmMaxLowerCaseCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.205 NAME 'nspmNumericCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.206 NAME 'nspmNumericAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.207 NAME 'nspmNumericAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.208 NAME 'nspmMinNumericCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.209 NAME 'nspmMaxNumericCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.210 NAME 'nspmSpecialCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.211 NAME 'nspmSpecialAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.212 NAME 'nspmSpecialAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.213 NAME 'nspmMinSpecialCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.214 NAME 'nspmMaxSpecialCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.215 NAME 'nspmMaxRepeatedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.216 NAME 'nspmMaxConsecutiveCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.217 NAME 'nspmMinUniqueCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.218 NAME 'nspmDisallowedAttributeValues' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.219 NAME 'nspmExcludeList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.220 NAME 'nspmCaseSensitive' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.221 NAME 'nspmPolicyPrecedence' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.222 NAME 'nspmExtendedCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.223 NAME 'nspmExtendedAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.224 NAME 'nspmExtendedAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.225 NAME 'nspmMinExtendedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.226 NAME 'nspmMaxExtendedCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.227 NAME 'nspmUpperAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.228 NAME 'nspmUpperAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.229 NAME 'nspmLowerAsFirstCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.230 NAME 'nspmLowerAsLastCharacter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.231 NAME 'nspmComplexityRules' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.233 NAME 'nspmAD2K8Syntax' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.234 NAME 'nspmAD2K8maxViolation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.235 NAME 'nspmXCharLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.236 NAME 'nspmXCharHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.237 NAME 'nspmUnicodeAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.238 NAME 'nspmNonAlphaCharactersAllowed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.239 NAME 'nspmMinNonAlphaCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.240 NAME 'nspmMaxNonAlphaCharacters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.241 NAME 'nspmGraceLoginHistoryLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.300 NAME 'nspmPolicyAgentContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.301 NAME 'nspmPolicyAgentNetWare' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.302 NAME 'nspmPolicyAgentWINNT' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.303 NAME 'nspmPolicyAgentSolaris' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.304 NAME 'nspmPolicyAgentLinux' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.305 NAME 'nspmPolicyAgentAIX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.43.4.306 NAME 'nspmPolicyAgentHPUX' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 0.9.2342.19200300.100.1.55 NAME 'audio' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.1 NAME 'carLicense' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113730.3.1.241 NAME 'displayName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 1.3.6.1.4.1.250.1.57 NAME 'labeledUri' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 0.9.2342.19200300.100.1.7 NAME 'ldapPhoto' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 0.9.2342.19200300.100.1.21 NAME 'secretary' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.12.4.1.0 NAME 'auditAEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:A Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.2.0 NAME 'auditBEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:B Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.3.0 NAME 'auditContents' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Contents' )", + "( 2.16.840.1.113719.1.12.4.4.0 NAME 'auditType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'Audit:Type' )", + "( 2.16.840.1.113719.1.12.4.5.0 NAME 'auditCurrentEncryptionKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Current Encryption Key' )", + "( 2.16.840.1.113719.1.12.4.6.0 NAME 'auditFileLink' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'Audit:File Link' )", + "( 2.16.840.1.113719.1.12.4.7.0 NAME 'auditLinkList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NAME 'Audit:Link List' )", + "( 2.16.840.1.113719.1.12.4.8.0 NAME 'auditPath' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Path' )", + "( 2.16.840.1.113719.1.12.4.9.0 NAME 'auditPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_NAME 'Audit:Policy' )", + "( 2.16.840.1.113719.1.38.4.1.1 NAME 'wANMANWANPolicy' SYNTAX 2.16.840.1.113719.1.1.5.1.13{64512} X-NDS_NAME 'WANMAN:WAN Policy' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.2 NAME 'wANMANLANAreaMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NAME 'WANMAN:LAN Area Membership' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.3 NAME 'wANMANCost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME 'WANMAN:Cost' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.38.4.1.4 NAME 'wANMANDefaultCost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NAME 'WANMAN:Default Cost' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.135.4.30 NAME 'rbsAssignedRoles' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.31 NAME 'rbsContent' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.32 NAME 'rbsContentMembership' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.33 NAME 'rbsEntryPoint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.34 NAME 'rbsMember' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.35 NAME 'rbsOwnedCollections' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.135.4.36 NAME 'rbsPath' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.37 NAME 'rbsParameters' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} )", + "( 2.16.840.1.113719.1.135.4.38 NAME 'rbsTaskRights' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.135.4.39 NAME 'rbsTrusteeOf' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.40 NAME 'rbsType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE X-NDS_LOWER_BOUND '1' X-NDS_UPPER_BOUND '256' )", + "( 2.16.840.1.113719.1.135.4.41 NAME 'rbsURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.42 NAME 'rbsTaskTemplates' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.135.4.43 NAME 'rbsTaskTemplatesURL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.44 NAME 'rbsGALabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.45 NAME 'rbsPageMembership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} )", + "( 2.16.840.1.113719.1.135.4.46 NAME 'rbsTargetObjectType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.135.4.47 NAME 'rbsContext' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.48 NAME 'rbsXMLInfo' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.135.4.51 NAME 'rbsAssignedRoles2' SYNTAX 2.16.840.1.113719.1.1.5.1.25 )", + "( 2.16.840.1.113719.1.135.4.52 NAME 'rbsOwnedCollections2' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.1.4.1.540 NAME 'prSyncPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.541 NAME 'prSyncAttributes' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_SERVER_READ '1' )", + "( 2.16.840.1.113719.1.1.4.1.542 NAME 'dsEncryptedReplicationConfig' SYNTAX 2.16.840.1.113719.1.1.5.1.19 )", + "( 2.16.840.1.113719.1.1.4.1.543 NAME 'encryptionPolicyDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.544 NAME 'attrEncryptionRequiresSecure' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.545 NAME 'attrEncryptionDefinition' SYNTAX 2.16.840.1.113719.1.1.5.1.6{64512} X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.48.4.1.16 NAME 'ndspkiCRLFileName' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.17 NAME 'ndspkiStatus' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.18 NAME 'ndspkiIssueTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.19 NAME 'ndspkiNextIssueTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.20 NAME 'ndspkiAttemptTime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.21 NAME 'ndspkiTimeInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.22 NAME 'ndspkiCRLMaxProcessingInterval' SYNTAX 2.16.840.1.113719.1.1.5.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.23 NAME 'ndspkiCRLNumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.24 NAME 'ndspkiDistributionPoints' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.25 NAME 'ndspkiCRLProcessData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.26 NAME 'ndspkiCRLConfigurationDNList' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.27 NAME 'ndspkiCADN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.28 NAME 'ndspkiCRLContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.29 NAME 'ndspkiIssuedCertContainerDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.30 NAME 'ndspkiDistributionPointDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.31 NAME 'ndspkiCRLConfigurationDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.32 NAME 'ndspkiDirectory' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} )", + "( 2.5.4.38 NAME 'authorityRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-NDS_NAME 'ndspkiAuthorityRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.39 NAME 'certificateRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-NDS_NAME 'ndspkiCertificateRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.5.4.53 NAME 'deltaRevocationList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-NDS_NAME 'ndspkiDeltaRevocationList' X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.36 NAME 'ndspkiTrustedRootList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.37 NAME 'ndspkiSecurityRightsLevel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.48.4.1.38 NAME 'ndspkiKMOExport' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.48.4.1.39 NAME 'ndspkiCRLECConfigurationDNList' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.40 NAME 'ndspkiCRLType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.41 NAME 'ndspkiCRLExtendValidity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.42 NAME 'ndspkiDefaultRSAKeySize' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.43 NAME 'ndspkiDefaultECCurve' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.48.4.1.44 NAME 'ndspkiDefaultCertificateLife' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.7.4.1 NAME 'notfSMTPEmailHost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.2 NAME 'notfSMTPEmailFrom' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.3 NAME 'notfSMTPEmailUserName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.5 NAME 'notfMergeTemplateData' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.7.4.6 NAME 'notfMergeTemplateSubject' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.1 NAME 'nsimRequiredQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.2 NAME 'nsimRandomQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.3 NAME 'nsimNumberRandomQuestions' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.4 NAME 'nsimMinResponseLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.5 NAME 'nsimMaxResponseLength' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.6 NAME 'nsimForgottenLoginConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.7 NAME 'nsimForgottenAction' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.8 NAME 'nsimAssignments' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.9 NAME 'nsimChallengeSetDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.10 NAME 'nsimChallengeSetGUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.11 NAME 'nsimPwdRuleEnforcement' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.39.44.4.12 NAME 'nsimHint' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.39.44.4.13 NAME 'nsimPasswordReminder' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.4 NAME 'sssProxyStoreKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.266.4.5 NAME 'sssProxyStoreSecrets' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} USAGE directoryOperation X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.266.4.6 NAME 'sssActiveServerList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.266.4.7 NAME 'sssCacheRefreshInterval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.8 NAME 'sssAdminList' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.266.4.9 NAME 'sssAdminGALabel' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.10 NAME 'sssEnableReadTimestamps' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.11 NAME 'sssDisableMasterPasswords' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.12 NAME 'sssEnableAdminAccess' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.266.4.13 NAME 'sssReadSecretPolicies' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} )", + "( 2.16.840.1.113719.1.266.4.14 NAME 'sssServerPolicyOverrideDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.1.531 NAME 'eDirCloneSource' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.1.532 NAME 'eDirCloneKeys' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} NO-USER-MODIFICATION USAGE directoryOperation X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' X-NDS_HIDDEN '1' )", + "( 2.16.840.1.113719.1.1.4.1.533 NAME 'eDirCloneLock' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} SINGLE-VALUE X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )", + "( 2.16.840.1.113719.1.1.4.711 NAME 'groupMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", + "( 2.16.840.1.113719.1.1.4.712 NAME 'nestedConfig' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", + "( 2.16.840.1.113719.1.1.4.717 NAME 'xdasDSConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.1.4.718 NAME 'xdasConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.1.4.719 NAME 'xdasVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_UPPER_BOUND '32768' )", + "( 2.16.840.1.113719.1.347.4.79 NAME 'NAuditInstrumentation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.347.4.2 NAME 'NAuditLoggingServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_PUBLIC_READ '1' )", + "( 2.16.840.1.113719.1.1.4.724 NAME 'cefConfiguration' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64512} )", + "( 2.16.840.1.113719.1.1.4.725 NAME 'cefVersion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{32768} SINGLE-VALUE X-NDS_UPPER_BOUND '32768' )" + ], + "createTimestamp": [], + "dITContentRules": [], + "dITStructureRules": [], + "ldapSyntaxes": [ + "( 1.3.6.1.4.1.1466.115.121.1.1 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.2 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.3 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.4 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.5 X-NDS_SYNTAX '21' )", + "( 1.3.6.1.4.1.1466.115.121.1.6 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.7 X-NDS_SYNTAX '7' )", + "( 2.16.840.1.113719.1.1.5.1.6 X-NDS_SYNTAX '6' )", + "( 1.3.6.1.4.1.1466.115.121.1.8 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.9 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.10 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.22 X-NDS_SYNTAX '22' )", + "( 1.3.6.1.4.1.1466.115.121.1.11 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.12 X-NDS_SYNTAX '1' )", + "( 1.3.6.1.4.1.1466.115.121.1.13 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.14 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.15 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.16 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.17 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.18 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.19 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.20 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.21 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.22 X-NDS_SYNTAX '11' )", + "( 1.3.6.1.4.1.1466.115.121.1.23 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.24 X-NDS_SYNTAX '24' )", + "( 1.3.6.1.4.1.1466.115.121.1.25 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.26 X-NDS_SYNTAX '2' )", + "( 1.3.6.1.4.1.1466.115.121.1.27 X-NDS_SYNTAX '8' )", + "( 1.3.6.1.4.1.1466.115.121.1.28 X-NDS_SYNTAX '9' )", + "( 1.2.840.113556.1.4.906 X-NDS_SYNTAX '29' )", + "( 1.3.6.1.4.1.1466.115.121.1.54 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.56 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.57 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.29 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.30 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.31 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.32 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.33 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.55 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.34 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.35 X-NDS_SYNTAX '3' )", + "( 2.16.840.1.113719.1.1.5.1.19 X-NDS_SYNTAX '19' )", + "( 1.3.6.1.4.1.1466.115.121.1.36 X-NDS_SYNTAX '5' )", + "( 2.16.840.1.113719.1.1.5.1.17 X-NDS_SYNTAX '17' )", + "( 1.3.6.1.4.1.1466.115.121.1.37 X-NDS_SYNTAX '3' )", + "( 2.16.840.1.113719.1.1.5.1.13 X-NDS_SYNTAX '13' )", + "( 1.3.6.1.4.1.1466.115.121.1.40 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.38 X-NDS_SYNTAX '20' )", + "( 1.3.6.1.4.1.1466.115.121.1.39 X-NDS_SYNTAX '3' )", + "( 1.3.6.1.4.1.1466.115.121.1.41 X-NDS_SYNTAX '18' )", + "( 1.3.6.1.4.1.1466.115.121.1.43 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.44 X-NDS_SYNTAX '4' )", + "( 1.3.6.1.4.1.1466.115.121.1.42 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.16 X-NDS_SYNTAX '16' )", + "( 1.3.6.1.4.1.1466.115.121.1.58 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.45 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.46 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.47 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.48 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.49 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.12 X-NDS_SYNTAX '12' )", + "( 2.16.840.1.113719.1.1.5.1.23 X-NDS_SYNTAX '23' )", + "( 2.16.840.1.113719.1.1.5.1.15 X-NDS_SYNTAX '15' )", + "( 2.16.840.1.113719.1.1.5.1.14 X-NDS_SYNTAX '14' )", + "( 1.3.6.1.4.1.1466.115.121.1.50 X-NDS_SYNTAX '10' )", + "( 1.3.6.1.4.1.1466.115.121.1.51 X-NDS_SYNTAX '9' )", + "( 1.3.6.1.4.1.1466.115.121.1.52 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.25 X-NDS_SYNTAX '25' )", + "( 1.3.6.1.4.1.1466.115.121.1.53 X-NDS_SYNTAX '9' )", + "( 2.16.840.1.113719.1.1.5.1.26 X-NDS_SYNTAX '26' )", + "( 2.16.840.1.113719.1.1.5.1.27 X-NDS_SYNTAX '27' )" + ], + "matchingRuleUse": [], + "matchingRules": [], + "modifyTimestamp": [ + "20190831135835Z" + ], + "nameForms": [], + "objectClass": [ + "top", + "subschema" + ], + "objectClasses": [ + "( 2.5.6.0 NAME 'Top' STRUCTURAL MUST objectClass MAY ( cAPublicKey $ cAPrivateKey $ certificateValidityInterval $ authorityRevocation $ lastReferencedTime $ equivalentToMe $ ACL $ backLink $ binderyProperty $ Obituary $ Reference $ revision $ ndsCrossCertificatePair $ certificateRevocation $ usedBy $ GUID $ otherGUID $ DirXML-Associations $ creatorsName $ modifiersName $ objectVersion $ auxClassCompatibility $ unknownBaseClass $ unknownAuxiliaryClass $ masvProposedLabel $ masvDefaultRange $ masvAuthorizedRange $ auditFileLink $ rbsAssignedRoles $ rbsOwnedCollections $ rbsAssignedRoles2 $ rbsOwnedCollections2 ) X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '16#subtree#[Creator]#[Entry Rights]' )", + "( 1.3.6.1.4.1.42.2.27.1.2.1 NAME 'aliasObject' SUP Top STRUCTURAL MUST aliasedObjectName X-NDS_NAME 'Alias' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.2 NAME 'Country' SUP Top STRUCTURAL MUST c MAY ( description $ searchGuide $ sssActiveServerList $ sssServerPolicyOverrideDN ) X-NDS_NAMING 'c' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.3 NAME 'Locality' SUP Top STRUCTURAL MAY ( description $ l $ seeAlso $ st $ street $ searchGuide $ sssActiveServerList $ sssServerPolicyOverrideDN ) X-NDS_NAMING ( 'l' 'st' ) X-NDS_CONTAINMENT ( 'Country' 'organizationalUnit' 'Locality' 'Organization' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.4 NAME 'Organization' SUP ( ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST o MAY ( description $ facsimileTelephoneNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ printerControl $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ businessCategory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'o' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Locality' 'domain' ) X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Self]#loginScript' '2#entry#[Self]#printJobConfiguration') )", + "( 2.5.6.5 NAME 'organizationalUnit' SUP ( ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST ou MAY ( description $ facsimileTelephoneNumber $ l $ loginScript $ eMailAddress $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ printJobConfiguration $ printerControl $ seeAlso $ st $ street $ telephoneNumber $ loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ nNSDomain $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber $ businessCategory $ searchGuide $ rADIUSAttributeLists $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSServiceList $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'ou' X-NDS_CONTAINMENT ( 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Unit' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Self]#loginScript' '2#entry#[Self]#printJobConfiguration') )", + "( 2.5.6.8 NAME 'organizationalRole' SUP Top STRUCTURAL MUST cn MAY ( description $ facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ roleOccupant $ seeAlso $ st $ street $ telephoneNumber $ mailboxLocation $ mailboxID $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ internationaliSDNNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Role' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.9 NAME ( 'groupOfNames' 'group' 'groupOfUniqueNames' ) SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ ou $ o $ owner $ seeAlso $ groupID $ fullName $ eMailAddress $ mailboxLocation $ mailboxID $ Profile $ profileMembership $ loginScript $ businessCategory $ nspmPasswordPolicyDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Group' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.6 NAME 'Person' SUP ndsLoginProperties STRUCTURAL MUST ( cn $ sn ) MAY ( description $ seeAlso $ telephoneNumber $ fullName $ givenName $ initials $ generationQualifier $ uid $ assistant $ assistantPhone $ city $ st $ company $ co $ directReports $ manager $ mailstop $ mobile $ personalTitle $ pager $ workforceID $ instantMessagingID $ preferredName $ photo $ jobCode $ siteLocation $ employeeStatus $ employeeType $ costCenter $ costCenterDescription $ tollFreePhoneNumber $ otherPhoneNumber $ managerWorkforceID $ roomNumber $ jackNumber $ departmentNumber $ vehicleInformation $ accessCardNumber $ isManager $ userPassword ) X-NDS_NAMING ( 'cn' 'uid' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.5.6.7 NAME 'organizationalPerson' SUP Person STRUCTURAL MAY ( facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ st $ street $ title $ mailboxLocation $ mailboxID $ uid $ mail $ employeeNumber $ destinationIndicator $ internationaliSDNNumber $ preferredDeliveryMethod $ registeredAddress $ teletexTerminalIdentifier $ telexNumber $ x121Address $ businessCategory $ roomNumber $ x500UniqueIdentifier ) X-NDS_NAMING ( 'cn' 'ou' 'uid' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Organizational Person' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organizationalPerson STRUCTURAL MAY ( groupMembership $ ndsHomeDirectory $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRemaining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestriction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ printJobConfiguration $ privateKey $ Profile $ publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ messageServer $ Language $ ndsUID $ lockedByIntruder $ serverHolds $ lastLoginTime $ typeCreatorMap $ higherPrivileges $ printerControl $ securityFlags $ profileMembership $ Timezone $ sASServiceDN $ sASSecretStore $ sASSecretStoreKey $ sASSecretStoreData $ sASPKIStoreKeys $ userCertificate $ nDSPKIUserCertificateInfo $ nDSPKIKeystore $ rADIUSActiveConnections $ rADIUSAttributeLists $ rADIUSConcurrentLimit $ rADIUSConnectionHistory $ rADIUSDefaultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSPassword $ rADIUSServiceList $ audio $ businessCategory $ carLicense $ departmentNumber $ employeeNumber $ employeeType $ displayName $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledUri $ mail $ manager $ mobile $ o $ pager $ ldapPhoto $ preferredLanguage $ roomNumber $ secretary $ uid $ userSMIMECertificate $ x500UniqueIdentifier $ userPKCS12 $ sssProxyStoreKey $ sssProxyStoreSecrets $ sssServerPolicyOverrideDN ) X-NDS_NAME 'User' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#subtree#[Self]#[All Attributes Rights]' '6#entry#[Self]#loginScript' '1#subtree#[Root Template]#[Entry Rights]' '2#entry#[Public]#messageServer' '2#entry#[Root Template]#groupMembership' '6#entry#[Self]#printJobConfiguration' '2#entry#[Root Template]#networkAddress') )", + "( 2.5.6.14 NAME 'Device' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ networkAddress $ ou $ o $ owner $ seeAlso $ serialNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.4 NAME 'Computer' SUP Device STRUCTURAL MAY ( operator $ server $ status ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.17 NAME 'Printer' SUP Device STRUCTURAL MAY ( Cartridge $ printerConfiguration $ defaultQueue $ hostDevice $ printServer $ Memory $ networkAddressRestriction $ notify $ operator $ pageDescriptionLanguage $ queue $ status $ supportedTypefaces ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.21 NAME 'Resource' SUP Top ABSTRACT MUST cn MAY ( description $ hostResourceName $ l $ ou $ o $ seeAlso $ Uses ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.20 NAME 'Queue' SUP Resource STRUCTURAL MUST queueDirectory MAY ( Device $ operator $ server $ User $ networkAddress $ Volume $ hostServer ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.3 NAME 'binderyQueue' SUP Queue STRUCTURAL MUST binderyType X-NDS_NAMING ( 'cn' 'binderyType' ) X-NDS_NAME 'Bindery Queue' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.26 NAME 'Volume' SUP Resource STRUCTURAL MUST hostServer MAY status X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Root Template]#hostResourceName' '2#entry#[Root Template]#hostServer') )", + "( 2.16.840.1.113719.1.1.6.1.7 NAME 'directoryMap' SUP Resource STRUCTURAL MUST hostServer MAY path X-NDS_NAME 'Directory Map' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.19 NAME 'Profile' SUP Top STRUCTURAL MUST ( cn $ loginScript ) MAY ( description $ l $ ou $ o $ seeAlso $ fullName ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.22 NAME 'Server' SUP Top ABSTRACT MUST cn MAY ( description $ hostDevice $ l $ ou $ o $ privateKey $ publicKey $ Resource $ seeAlso $ status $ User $ Version $ networkAddress $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ fullName $ securityEquals $ securityFlags $ Timezone $ ndapClassPasswordMgmt $ ndapClassLoginMgmt ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#entry#[Public]#networkAddress' '16#subtree#[Self]#[Entry Rights]') )", + "( 2.16.840.1.113719.1.1.6.1.10 NAME 'ncpServer' SUP Server STRUCTURAL MAY ( operator $ supportedServices $ messagingServer $ dsRevision $ permanentConfigParms $ ndsPredicateStatsDN $ languageId $ indexDefinition $ CachedAttrsOnExtRefs $ NCPKeyMaterialName $ NDSRightsToMonitor $ ldapServerDN $ httpServerDN $ emboxConfig $ sASServiceDN $ cACertificate $ cAECCertificate $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKICertificateChain $ nDSPKIParentCADN $ nDSPKISDKeyID $ nDSPKISDKeyStruct $ snmpGroupDN $ wANMANWANPolicy $ wANMANLANAreaMembership $ wANMANCost $ wANMANDefaultCost $ encryptionPolicyDN $ eDirCloneSource $ eDirCloneLock $ xdasDSConfiguration $ xdasConfiguration $ xdasVersion $ NAuditLoggingServer $ NAuditInstrumentation $ cefConfiguration $ cefVersion ) X-NDS_NAME 'NCP Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Public]#messagingServer' )", + "( 2.16.840.1.113719.1.1.6.1.18 NAME 'printServer' SUP Server STRUCTURAL MAY ( operator $ printer $ sAPName ) X-NDS_NAME 'Print Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#subtree#[Root Template]#[All Attributes Rights]' )", + "( 2.16.840.1.113719.1.1.6.1.31 NAME 'CommExec' SUP Server STRUCTURAL MAY networkAddressRestriction X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.2 NAME 'binderyObject' SUP Top STRUCTURAL MUST ( binderyObjectRestriction $ binderyType $ cn ) X-NDS_NAMING ( 'cn' 'binderyType' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'Bindery Object' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.15 NAME 'Partition' AUXILIARY MAY ( Convergence $ partitionCreationTime $ Replica $ inheritedACL $ lowConvergenceSyncInterval $ receivedUpTo $ synchronizedUpTo $ authorityRevocation $ certificateRevocation $ cAPrivateKey $ cAPublicKey $ ndsCrossCertificatePair $ lowConvergenceResetTime $ highConvergenceSyncInterval $ partitionControl $ replicaUpTo $ partitionStatus $ transitiveVector $ purgeVector $ synchronizationTolerance $ obituaryNotify $ localReceivedUpTo $ federationControl $ syncPanePoint $ syncWindowVector $ EBAPartitionConfiguration $ authoritative $ allowAliasToAncestor $ sASSecurityDN $ masvLabel $ ndapPartitionPasswordMgmt $ ndapPartitionLoginMgmt $ prSyncPolicyDN $ dsEncryptedReplicationConfig ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.0 NAME 'aFPServer' SUP Server STRUCTURAL MAY ( serialNumber $ supportedConnections ) X-NDS_NAME 'AFP Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.27 NAME 'messagingServer' SUP Server STRUCTURAL MAY ( messagingDatabaseLocation $ messageRoutingGroup $ Postmaster $ supportedServices $ messagingServerType $ supportedGateway ) X-NDS_NAME 'Messaging Server' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '1#subtree#[Self]#[Entry Rights]' '2#subtree#[Self]#[All Attributes Rights]' '6#entry#[Self]#status' '2#entry#[Public]#messagingServerType' '2#entry#[Public]#messagingDatabaseLocation') )", + "( 2.16.840.1.113719.1.1.6.1.28 NAME 'messageRoutingGroup' SUP groupOfNames STRUCTURAL X-NDS_NAME 'Message Routing Group' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '1#subtree#[Self]#[Entry Rights]' '2#subtree#[Self]#[All Attributes Rights]') )", + "( 2.16.840.1.113719.1.1.6.1.29 NAME 'externalEntity' SUP Top STRUCTURAL MUST cn MAY ( description $ seeAlso $ facsimileTelephoneNumber $ l $ eMailAddress $ ou $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ st $ street $ title $ externalName $ mailboxLocation $ mailboxID ) X-NDS_NAMING ( 'cn' 'ou' ) X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'External Entity' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Public]#externalName' )", + "( 2.16.840.1.113719.1.1.6.1.30 NAME 'List' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ ou $ o $ eMailAddress $ mailboxLocation $ mailboxID $ owner $ seeAlso $ fullName ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES '2#entry#[Root Template]#member' )", + "( 2.16.840.1.113719.1.1.6.1.32 NAME 'treeRoot' SUP Top STRUCTURAL MUST T MAY ( EBATreeConfiguration $ sssActiveServerList ) X-NDS_NAMING 'T' X-NDS_NAME 'Tree Root' X-NDS_NONREMOVABLE '1' )", + "( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP ( Top $ ndsLoginProperties $ ndsContainerLoginProperties ) STRUCTURAL MUST dc MAY ( searchGuide $ o $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ l $ associatedName $ description $ sssActiveServerList $ sssServerPolicyOverrideDN $ userPassword ) X-NDS_NAMING 'dc' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NONREMOVABLE '1' )", + "( 1.3.6.1.4.1.1466.344 NAME 'dcObject' AUXILIARY MUST dc X-NDS_NAMING 'dc' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.33 NAME 'ndsLoginProperties' SUP Top ABSTRACT MAY ( groupMembership $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRemaining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestriction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ privateKey $ Profile $ publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimumAccountBalance $ Language $ lockedByIntruder $ serverHolds $ lastLoginTime $ higherPrivileges $ securityFlags $ profileMembership $ Timezone $ loginActivationTime $ UTF8LoginScript $ loginScriptCharset $ sASNDSPasswordWindow $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasAllowableSubjectNames $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPCounter $ sasOTPDigits $ sasOTPReSync $ sasUpdateLoginTimeInterval $ ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordKey $ nspmPassword $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotExpirePassword $ nspmDistributionPassword $ nspmPreviousDistributionPassword $ nspmPasswordHistory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN $ nsimHint $ nsimPasswordReminder $ userPassword ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.141.6.1 NAME 'federationBoundary' AUXILIARY MUST federationBoundaryType MAY ( federationControl $ federationDNSName $ federationSearchPath ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.34 NAME 'ndsContainerLoginProperties' SUP Top ABSTRACT MAY ( loginIntruderLimit $ intruderAttemptResetInterval $ detectIntruder $ lockoutAfterDetection $ intruderLockoutResetInterval $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPDigits $ sasUpdateLoginTimeInterval $ ndapPasswordMgmt $ ndapLoginMgmt $ nspmPasswordPolicyDN ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.27.6.3 NAME 'ndsPredicateStats' SUP Top STRUCTURAL MUST ( cn $ ndsPredicateState $ ndsPredicateFlush ) MAY ( ndsPredicate $ ndsPredicateTimeout $ ndsPredicateUseValues ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.400.1 NAME 'edirSchemaVersion' SUP Top ABSTRACT MAY edirSchemaFlagVersion X-NDS_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' )", + "( 2.16.840.1.113719.1.1.6.1.47 NAME 'immediateSuperiorReference' AUXILIARY MAY ref X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.27.6.1 NAME 'ldapServer' SUP Top STRUCTURAL MUST cn MAY ( ldapHostServer $ ldapGroupDN $ ldapTraceLevel $ ldapServerBindLimit $ ldapServerIdleTimeout $ lDAPUDPPort $ lDAPSearchSizeLimit $ lDAPSearchTimeLimit $ lDAPLogLevel $ lDAPLogFilename $ lDAPBackupLogFilename $ lDAPLogSizeLimit $ Version $ searchSizeLimit $ searchTimeLimit $ ldapEnableTCP $ ldapTCPPort $ ldapEnableSSL $ ldapSSLPort $ ldapKeyMaterialName $ filteredReplicaUsage $ extensionInfo $ nonStdClientSchemaCompatMode $ sslEnableMutualAuthentication $ ldapEnablePSearch $ ldapMaximumPSearchOperations $ ldapIgnorePSearchLimitsForEvents $ ldapTLSTrustedRootContainer $ ldapEnableMonitorEvents $ ldapMaximumMonitorEventsLoad $ ldapTLSRequired $ ldapTLSVerifyClientCertificate $ ldapConfigVersion $ ldapDerefAlias $ ldapNonStdAllUserAttrsMode $ ldapBindRestrictions $ ldapDefaultReferralBehavior $ ldapReferral $ ldapSearchReferralUsage $ lDAPOtherReferralUsage $ ldapLBURPNumWriterThreads $ ldapInterfaces $ ldapChainSecureRequired $ ldapStdCompliance $ ldapDerefAliasOnAuth $ ldapGeneralizedTime $ ldapPermissiveModify $ ldapSSLConfig ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) X-NDS_NAME 'LDAP Server' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.27.6.2 NAME 'ldapGroup' SUP Top STRUCTURAL MUST cn MAY ( ldapReferral $ ldapServerList $ ldapAllowClearTextPassword $ ldapAnonymousIdentity $ lDAPSuffix $ ldapAttributeMap $ ldapClassMap $ ldapSearchReferralUsage $ lDAPOtherReferralUsage $ transitionGroupDN $ ldapAttributeList $ ldapClassList $ ldapConfigVersion $ Version $ ldapDefaultReferralBehavior $ ldapTransitionBackLink $ ldapSSLConfig $ referralIncludeFilter $ referralExcludeFilter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) X-NDS_NAME 'LDAP Group' X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.22 NAME 'pkiCA' AUXILIARY MAY ( cACertificate $ certificateRevocationList $ authorityRevocationList $ crossCertificatePair $ attributeCertificate $ publicKey $ privateKey $ networkAddress $ loginTime $ lastLoginTime $ cAECCertificate $ crossCertificatePairEC ) X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.21 NAME 'pkiUser' AUXILIARY MAY userCertificate X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.15 NAME 'strongAuthenticationUser' AUXILIARY MAY userCertificate X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.11 NAME 'applicationProcess' SUP Top STRUCTURAL MUST cn MAY ( seeAlso $ ou $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.12 NAME 'applicationEntity' SUP Top STRUCTURAL MUST ( presentationAddress $ cn ) MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL MAY knowledgeInformation X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.5.6.16 NAME 'certificationAuthority' AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY crossCertificatePair X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.18 NAME 'userSecurityInformation' AUXILIARY MAY supportedAlgorithms X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.20 NAME 'dmd' SUP ndsLoginProperties AUXILIARY MUST dmdName MAY ( searchGuide $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ physicalDeliveryOfficeName $ l $ description $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.5.6.16.2 NAME 'certificationAuthority-V2' AUXILIARY MUST ( authorityRevocationList $ certificateRevocationList $ cACertificate ) MAY ( crossCertificatePair $ deltaRevocationList ) X-NDS_NAME 'certificationAuthorityVer2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.3.6.1 NAME 'httpServer' SUP Top STRUCTURAL MUST cn MAY ( httpHostServerDN $ httpThreadsPerCPU $ httpIOBufferSize $ httpRequestTimeout $ httpKeepAliveRequestTimeout $ httpSessionTimeout $ httpKeyMaterialObject $ httpTraceLevel $ httpAuthRequiresTLS $ httpDefaultClearPort $ httpDefaultTLSPort $ httpBindRestrictions ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'domain' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.64.6.1.1 NAME 'Template' SUP Top STRUCTURAL MUST cn MAY ( trusteesOfNewObject $ newObjectSDSRights $ newObjectSFSRights $ setupScript $ runSetupScript $ membersOfTemplate $ volumeSpaceRestrictions $ setPasswordAfterCreate $ homeDirectoryRights $ accountBalance $ allowUnlimitedCredit $ description $ eMailAddress $ facsimileTelephoneNumber $ groupMembership $ higherPrivileges $ ndsHomeDirectory $ l $ Language $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginMaximumSimultaneous $ loginScript $ mailboxID $ mailboxLocation $ member $ messageServer $ minimumAccountBalance $ networkAddressRestriction $ newObjectSSelfRights $ ou $ passwordAllowChange $ passwordExpirationInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequired $ passwordUniqueRequired $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ Profile $ st $ street $ securityEquals $ securityFlags $ seeAlso $ telephoneNumber $ title $ assistant $ assistantPhone $ city $ company $ co $ manager $ managerWorkforceID $ mailstop $ siteLocation $ employeeType $ costCenter $ costCenterDescription $ tollFreePhoneNumber $ departmentNumber ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.8.6.1 NAME 'homeInfo' AUXILIARY MAY ( homeCity $ homeEmailAddress $ homeFax $ homePhone $ homeState $ homePostalAddress $ homeZipCode $ personalMobile $ spouse $ children ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.8.6.2 NAME 'contingentWorker' AUXILIARY MAY ( vendorName $ vendorAddress $ vendorPhoneNumber ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.45 NAME 'dynamicGroup' SUP ( groupOfNames $ ndsLoginProperties ) STRUCTURAL MAY ( memberQueryURL $ excludedMember $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.46 NAME 'dynamicGroupAux' SUP ( groupOfNames $ ndsLoginProperties ) AUXILIARY MAY ( memberQueryURL $ excludedMember $ dgIdentity $ dgAllowUnknown $ dgTimeOut $ dgAllowDuplicates $ userPassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.6.1.1 NAME 'sASSecurity' SUP Top STRUCTURAL MUST cn MAY ( nDSPKITreeCADN $ masvPolicyDN $ sASLoginPolicyDN $ sASLoginMethodContainerDN $ sasPostLoginMethodContainerDN $ nspmPolicyAgentContainerDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' 'treeRoot' 'Country' 'Organization' 'domain' ) X-NDS_NAME 'SAS:Security' )", + "( 2.16.840.1.113719.1.39.6.1.2 NAME 'sASService' SUP Resource STRUCTURAL MAY ( hostServer $ privateKey $ publicKey $ allowUnlimitedCredit $ fullName $ lastLoginTime $ lockedByIntruder $ loginAllowedTimeMap $ loginDisabled $ loginExpirationTime $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTime $ loginMaximumSimultaneous $ loginTime $ networkAddress $ networkAddressRestriction $ notify $ operator $ owner $ path $ securityEquals $ securityFlags $ status $ Version $ nDSPKIKeyMaterialDN $ ndspkiKMOExport ) X-NDS_NAMING 'cn' X-NDS_NAME 'SAS:Service' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.1 NAME 'nDSPKICertificateAuthority' SUP Top STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKICertificateChainEC $ nDSPKIParentCA $ nDSPKIParentCADN $ nDSPKISubjectName $ nDSPKIPublicKeyEC $ nDSPKIPrivateKeyEC $ nDSPKIPublicKeyCertificateEC $ crossCertificatePairEC $ nDSPKISuiteBMode $ cACertificate $ cAECCertificate $ ndspkiCRLContainerDN $ ndspkiIssuedCertContainerDN $ ndspkiCRLConfigurationDNList $ ndspkiCRLECConfigurationDNList $ ndspkiSecurityRightsLevel $ ndspkiDefaultRSAKeySize $ ndspkiDefaultECCurve $ ndspkiDefaultCertificateLife ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'NDSPKI:Certificate Authority' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.2 NAME 'nDSPKIKeyMaterial' SUP Top STRUCTURAL MUST cn MAY ( hostServer $ nDSPKIKeyFile $ nDSPKIPrivateKey $ nDSPKIPublicKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKISubjectName $ nDSPKIGivenName $ ndspkiAdditionalRoots $ nDSPKINotBefore $ nDSPKINotAfter ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME 'NDSPKI:Key Material' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.3 NAME 'nDSPKITrustedRoot' SUP Top STRUCTURAL MUST cn MAY ndspkiTrustedRootList X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'domain' ) X-NDS_NAME 'NDSPKI:Trusted Root' )", + "( 2.16.840.1.113719.1.48.6.1.4 NAME 'nDSPKITrustedRootObject' SUP Top STRUCTURAL MUST ( cn $ nDSPKITrustedRootCertificate ) MAY ( nDSPKISubjectName $ nDSPKINotBefore $ nDSPKINotAfter $ externalName $ givenName $ sn ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKITrustedRoot' X-NDS_NAME 'NDSPKI:Trusted Root Object' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.101 NAME 'nDSPKISDKeyAccessPartition' SUP Top STRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'NDSPKI:SD Key Access Partition' )", + "( 2.16.840.1.113719.1.48.6.1.102 NAME 'nDSPKISDKeyList' SUP Top STRUCTURAL MUST cn MAY ( nDSPKISDKeyServerDN $ nDSPKISDKeyStruct $ nDSPKISDKeyCert ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nDSPKISDKeyAccessPartition' X-NDS_NAME 'NDSPKI:SD Key List' )", + "( 2.16.840.1.113719.1.31.6.2.1 NAME 'mASVSecurityPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ masvDomainPolicy $ masvPolicyUpdate $ masvClearanceNames $ masvLabelNames $ masvLabelSecrecyLevelNames $ masvLabelSecrecyCategoryNames $ masvLabelIntegrityLevelNames $ masvLabelIntegrityCategoryNames $ masvNDSAttributeLabels ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'MASV:Security Policy' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.1 NAME 'sASLoginMethodContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'SAS:Login Method Container' )", + "( 2.16.840.1.113719.1.39.42.2.0.4 NAME 'sASLoginPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ privateKey $ publicKey $ sASAllowNDSPasswordWindow $ sASPolicyCredentials $ sASPolicyMethods $ sASPolicyObjectVersion $ sASPolicyServiceSubtypes $ sASPolicyServices $ sASPolicyUsers $ sASLoginSequence $ sASLoginPolicyUpdate $ sasNMASProductOptions $ sasPolicyMethods $ sasPolicyServices $ sasPolicyUsers $ sasAllowNDSPasswordWindow $ sasLoginFailureDelay $ sasDefaultLoginSequence $ sasAuthorizedLoginSequences $ sasAuditConfiguration $ sasUpdateLoginInfo $ sasOTPEnabled $ sasOTPLookAheadWindow $ sasOTPDigits $ sasUpdateLoginTimeInterval $ nspmPasswordPolicyDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' X-NDS_NAME 'SAS:Login Policy' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.7 NAME 'sASNMASBaseLoginMethod' SUP Top ABSTRACT MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMethodGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLoginClientMethodWINNT $ sASLoginServerMethodWINNT $ sasCertificateSearchContainers $ sasNMASMethodConfigData $ sasMethodVersion $ sASLoginPolicyUpdate $ sasUnsignedMethodModules $ sasServerModuleName $ sasServerModuleEntryPointName $ sasSASLMechanismName $ sasSASLMechanismEntryPointName $ sasClientModuleName $ sasClientModuleEntryPointName $ sasLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ sasLoginClientMethodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodTru64 $ sasLoginServerMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerMethodAIX $ sasLoginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginClientMethods390 $ sasLoginServerMethods390 $ sasLoginClientMethodLinuxX64 $ sasLoginServerMethodLinuxX64 $ sasLoginClientMethodWinX64 $ sasLoginServerMethodWinX64 $ sasLoginClientMethodSolaris64 $ sasLoginServerMethodSolaris64 $ sasLoginClientMethodSolarisi386 $ sasLoginServerMethodSolarisi386 $ sasLoginClientMethodAIX64 $ sasLoginServerMethodAIX64 ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASLoginMethodContainer' X-NDS_NAME 'SAS:NMAS Base Login Method' )", + "( 2.16.840.1.113719.1.39.42.2.0.8 NAME 'sASNMASLoginMethod' SUP sASNMASBaseLoginMethod STRUCTURAL X-NDS_NAME 'SAS:NMAS Login Method' )", + "( 2.16.840.1.113719.1.39.42.2.0.9 NAME 'rADIUSDialAccessSystem' SUP Top STRUCTURAL MUST cn MAY ( publicKey $ privateKey $ rADIUSAgedInterval $ rADIUSClient $ rADIUSCommonNameResolution $ rADIUSConcurrentLimit $ rADIUSDASVersion $ rADIUSEnableCommonNameLogin $ rADIUSEnableDialAccess $ rADIUSInterimAcctingTimeout $ rADIUSLookupContexts $ rADIUSMaxDASHistoryRecord $ rADIUSMaximumHistoryRecord $ rADIUSPasswordPolicy $ rADIUSPrivateKey $ rADIUSProxyContext $ rADIUSProxyDomain $ rADIUSProxyTarget $ rADIUSPublicKey $ sASLoginConfiguration $ sASLoginConfigurationKey ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'RADIUS:Dial Access System' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.10 NAME 'rADIUSProfile' SUP Top STRUCTURAL MUST cn MAY rADIUSAttributeList X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NAME 'RADIUS:Profile' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.42.2.0.11 NAME 'sasPostLoginMethodContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.39.42.2.0.12 NAME 'sasPostLoginMethod' SUP Top STRUCTURAL MUST cn MAY ( description $ sASLoginSecret $ sASLoginSecretKey $ sASEncryptionType $ sASLoginConfiguration $ sASLoginConfigurationKey $ sASMethodIdentifier $ sASMethodVendor $ sASVendorSupport $ sASAdvisoryMethodGrade $ sASLoginClientMethodNetWare $ sASLoginServerMethodNetWare $ sASLoginClientMethodWINNT $ sASLoginServerMethodWINNT $ sasMethodVersion $ sASLoginPolicyUpdate $ sasUnsignedMethodModules $ sasServerModuleName $ sasServerModuleEntryPointName $ sasSASLMechanismName $ sasSASLMechanismEntryPointName $ sasClientModuleName $ sasClientModuleEntryPointName $ sasLoginClientMethodSolaris $ sasLoginServerMethodSolaris $ sasLoginClientMethodLinux $ sasLoginServerMethodLinux $ sasLoginClientMethodTru64 $ sasLoginServerMethodTru64 $ sasLoginClientMethodAIX $ sasLoginServerMethodAIX $ sasLoginClientMethodHPUX $ sasLoginServerMethodHPUX $ sasLoginClientMethods390 $ sasLoginServerMethods390 $ sasLoginClientMethodLinuxX64 $ sasLoginServerMethodLinuxX64 $ sasLoginClientMethodWinX64 $ sasLoginServerMethodWinX64 $ sasLoginClientMethodSolaris64 $ sasLoginServerMethodSolaris64 $ sasLoginClientMethodSolarisi386 $ sasLoginServerMethodSolarisi386 $ sasLoginClientMethodAIX64 $ sasLoginServerMethodAIX64 ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sasPostLoginMethodContainer' )", + "( 2.16.840.1.113719.1.6.6.1 NAME 'snmpGroup' SUP Top STRUCTURAL MUST cn MAY ( Version $ snmpServerList $ snmpTrapDisable $ snmpTrapInterval $ snmpTrapDescription $ snmpTrapConfig ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'domain' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.2 NAME 'nspmPasswordPolicyContainer' SUP Top STRUCTURAL MUST cn MAY description X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Country' 'domain' 'Locality' 'Organization' 'organizationalUnit' ) )", + "( 2.16.840.1.113719.1.39.43.6.3 NAME 'nspmPolicyAgent' SUP Top STRUCTURAL MUST cn MAY ( description $ nspmPolicyAgentNetWare $ nspmPolicyAgentWINNT $ nspmPolicyAgentSolaris $ nspmPolicyAgentLinux $ nspmPolicyAgentAIX $ nspmPolicyAgentHPUX ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'nspmPasswordPolicyContainer' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.1 NAME 'nspmPasswordPolicy' SUP Top STRUCTURAL MUST cn MAY ( description $ nspmPolicyPrecedence $ nspmConfigurationOptions $ nspmChangePasswordMessage $ passwordExpirationInterval $ loginGraceLimit $ nspmMinPasswordLifetime $ passwordUniqueRequired $ nspmPasswordHistoryLimit $ nspmPasswordHistoryExpiration $ passwordAllowChange $ passwordRequired $ passwordMinimumLength $ nspmMaximumLength $ nspmCaseSensitive $ nspmMinUpperCaseCharacters $ nspmMaxUpperCaseCharacters $ nspmMinLowerCaseCharacters $ nspmMaxLowerCaseCharacters $ nspmNumericCharactersAllowed $ nspmNumericAsFirstCharacter $ nspmNumericAsLastCharacter $ nspmMinNumericCharacters $ nspmMaxNumericCharacters $ nspmSpecialCharactersAllowed $ nspmSpecialAsFirstCharacter $ nspmSpecialAsLastCharacter $ nspmMinSpecialCharacters $ nspmMaxSpecialCharacters $ nspmMaxRepeatedCharacters $ nspmMaxConsecutiveCharacters $ nspmMinUniqueCharacters $ nspmDisallowedAttributeValues $ nspmExcludeList $ nspmExtendedCharactersAllowed $ nspmExtendedAsFirstCharacter $ nspmExtendedAsLastCharacter $ nspmMinExtendedCharacters $ nspmMaxExtendedCharacters $ nspmUpperAsFirstCharacter $ nspmUpperAsLastCharacter $ nspmLowerAsFirstCharacter $ nspmLowerAsLastCharacter $ nspmComplexityRules $ nspmAD2K8Syntax $ nspmAD2K8maxViolation $ nspmXCharLimit $ nspmXCharHistoryLimit $ nspmUnicodeAllowed $ nspmNonAlphaCharactersAllowed $ nspmMinNonAlphaCharacters $ nspmMaxNonAlphaCharacters $ pwdInHistory $ nspmAdminsDoNotExpirePassword $ nspmPasswordACL $ nsimChallengeSetDN $ nsimForgottenAction $ nsimForgottenLoginConfig $ nsimAssignments $ nsimChallengeSetGUID $ nsimPwdRuleEnforcement ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'nspmPasswordPolicyContainer' 'domain' 'Locality' 'Organization' 'organizationalUnit' 'Country' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.43.6.4 NAME 'nspmPasswordAux' AUXILIARY MAY ( publicKey $ privateKey $ loginGraceLimit $ loginGraceRemaining $ passwordExpirationTime $ passwordRequired $ nspmPasswordKey $ nspmPassword $ nspmDistributionPassword $ nspmPreviousDistributionPassword $ nspmPasswordHistory $ nspmAdministratorChangeCount $ nspmPasswordPolicyDN $ pwdChangedTime $ pwdAccountLockedTime $ pwdFailureTime $ nspmDoNotExpirePassword ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.12.6.1.0 NAME 'auditFileObject' SUP Top STRUCTURAL MUST ( cn $ auditPolicy $ auditContents ) MAY ( description $ auditPath $ auditLinkList $ auditType $ auditCurrentEncryptionKey $ auditAEncryptionKey $ auditBEncryptionKey ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Top' 'Country' 'Locality' 'Organization' 'organizationalUnit' 'treeRoot' 'domain' ) X-NDS_NAME 'Audit:File Object' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.38.6.1.4 NAME 'wANMANLANArea' SUP Top STRUCTURAL MUST cn MAY ( description $ l $ member $ o $ ou $ owner $ seeAlso $ wANMANWANPolicy $ wANMANCost $ wANMANDefaultCost ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'Organization' 'organizationalUnit' ) X-NDS_NAME 'WANMAN:LAN Area' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.37.1 NAME 'rbsCollection' SUP Top STRUCTURAL MUST cn MAY ( owner $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.16.840.1.113719.1.135.6.30.1 NAME 'rbsExternalScope' SUP Top ABSTRACT MUST cn MAY ( rbsURL $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.31.1 NAME 'rbsModule' SUP Top STRUCTURAL MUST cn MAY ( rbsURL $ rbsPath $ rbsType $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' )", + "( 2.16.840.1.113719.1.135.6.32.1 NAME 'rbsRole' SUP Top STRUCTURAL MUST cn MAY ( rbsContent $ rbsMember $ rbsTrusteeOf $ rbsGALabel $ rbsParameters $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection' )", + "( 2.16.840.1.113719.1.135.6.33.1 NAME 'rbsTask' SUP Top STRUCTURAL MUST cn MAY ( rbsContentMembership $ rbsType $ rbsTaskRights $ rbsEntryPoint $ rbsParameters $ rbsTaskTemplates $ rbsTaskTemplatesURL $ description $ rbsXMLInfo ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsModule' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.34.1 NAME 'rbsBook' SUP rbsTask STRUCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.35.1 NAME 'rbsScope' SUP groupOfNames STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.45.1 NAME 'rbsCollection2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsParameters $ owner $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'domain' ) )", + "( 2.16.840.1.113719.1.135.6.38.1 NAME 'rbsExternalScope2' SUP Top ABSTRACT MUST cn MAY ( rbsXMLInfo $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.39.1 NAME 'rbsModule2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsPath $ rbsType $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' )", + "( 2.16.840.1.113719.1.135.6.40.1 NAME 'rbsRole2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsContent $ rbsMember $ rbsTrusteeOf $ rbsParameters $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsCollection2' )", + "( 2.16.840.1.113719.1.135.6.41.1 NAME 'rbsTask2' SUP Top STRUCTURAL MUST cn MAY ( rbsXMLInfo $ rbsContentMembership $ rbsType $ rbsTaskRights $ rbsEntryPoint $ rbsParameters $ description ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'rbsModule2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.42.1 NAME 'rbsBook2' SUP rbsTask2 STRUCTURAL MAY ( rbsTargetObjectType $ rbsPageMembership ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.135.6.43.1 NAME 'rbsScope2' SUP groupOfNames STRUCTURAL MAY ( rbsContext $ rbsXMLInfo ) X-NDS_CONTAINMENT 'rbsRole2' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.49 NAME 'prSyncPolicy' SUP Top STRUCTURAL MUST cn MAY prSyncAttributes X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'domain' 'Country' 'Locality' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.50 NAME 'encryptionPolicy' SUP Top STRUCTURAL MUST cn MAY ( attrEncryptionDefinition $ attrEncryptionRequiresSecure ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'domain' 'organizationalUnit' 'Organization' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.5 NAME 'ndspkiContainer' SUP Top STRUCTURAL MUST cn X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'ndspkiContainer' 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'nDSPKITrustedRoot' ) )", + "( 2.16.840.1.113719.1.48.6.1.6 NAME 'ndspkiCertificate' SUP Top STRUCTURAL MUST ( cn $ userCertificate ) MAY ( nDSPKISubjectName $ nDSPKINotBefore $ nDSPKINotAfter $ externalName $ givenName $ sn ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sASSecurity' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'ndspkiContainer' 'nDSPKITrustedRoot' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.48.6.1.7 NAME 'ndspkiCRLConfiguration' SUP Top STRUCTURAL MUST cn MAY ( ndspkiCRLFileName $ ndspkiDirectory $ ndspkiStatus $ ndspkiIssueTime $ ndspkiNextIssueTime $ ndspkiAttemptTime $ ndspkiTimeInterval $ ndspkiCRLMaxProcessingInterval $ ndspkiCRLNumber $ ndspkiDistributionPoints $ ndspkiDistributionPointDN $ ndspkiCADN $ ndspkiCRLProcessData $ nDSPKIPublicKey $ nDSPKIPrivateKey $ nDSPKIPublicKeyCertificate $ nDSPKICertificateChain $ nDSPKIParentCA $ nDSPKIParentCADN $ nDSPKISubjectName $ cACertificate $ hostServer $ ndspkiCRLType $ ndspkiCRLExtendValidity ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'ndspkiContainer' )", + "( 2.5.6.19 NAME 'cRLDistributionPoint' SUP Top STRUCTURAL MUST cn MAY ( authorityRevocationList $ authorityRevocationList $ cACertificate $ certificateRevocationList $ certificateRevocationList $ crossCertificatePair $ deltaRevocationList $ deltaRevocationList $ ndspkiCRLConfigurationDN ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'Country' 'Locality' 'organizationalUnit' 'Organization' 'sASSecurity' 'domain' 'ndspkiCRLConfiguration' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.7.6.1 NAME 'notfTemplateCollection' SUP Top STRUCTURAL MUST cn MAY ( notfSMTPEmailHost $ notfSMTPEmailFrom $ notfSMTPEmailUserName $ sASSecretStore ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.7.6.2 NAME 'notfMergeTemplate' SUP Top STRUCTURAL MUST cn MAY ( notfMergeTemplateData $ notfMergeTemplateSubject ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'notfTemplateCollection' X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.39.44.6.1 NAME 'nsimChallengeSet' SUP Top STRUCTURAL MUST cn MAY ( description $ nsimRequiredQuestions $ nsimRandomQuestions $ nsimNumberRandomQuestions $ nsimMinResponseLength $ nsimMaxResponseLength ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'nspmPasswordPolicyContainer' 'Country' 'domain' 'Locality' 'Organization' 'organizationalUnit' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.266.6.1 NAME 'sssServerPolicies' SUP Top STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimestamps $ sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sssAdminGALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT 'sASSecurity' )", + "( 2.16.840.1.113719.1.266.6.2 NAME 'sssServerPolicyOverride' SUP Top STRUCTURAL MUST cn MAY ( sssCacheRefreshInterval $ sssEnableReadTimestamps $ sssDisableMasterPasswords $ sssEnableAdminAccess $ sssAdminList $ sssAdminGALabel $ sssReadSecretPolicies ) X-NDS_NAMING 'cn' X-NDS_CONTAINMENT ( 'sssServerPolicies' 'Organization' 'organizationalUnit' 'Country' 'Locality' 'domain' ) X-NDS_NOT_CONTAINER '1' )", + "( 2.16.840.1.113719.1.1.6.1.91 NAME 'nestedGroupAux' AUXILIARY MAY ( groupMember $ excludedMember $ nestedConfig $ groupMembership ) X-NDS_NOT_CONTAINER '1' )" + ] + }, + "schema_entry": "cn=schema", + "type": "SchemaInfo" +} +""" + +edir_9_1_4_dsa_info = """ +{ + "raw": { + "abandonOps": [ + "0" + ], + "addEntryOps": [ + "0" + ], + "altServer": [], + "bindSecurityErrors": [ + "0" + ], + "chainings": [ + "0" + ], + "compareOps": [ + "0" + ], + "directoryTreeName": [ + "TEST_TREE" + ], + "dsaName": [ + "cn=MYSERVER,o=resources" + ], + "errors": [ + "0" + ], + "extendedOps": [ + "0" + ], + "inBytes": [ + "293" + ], + "inOps": [ + "3" + ], + "listOps": [ + "0" + ], + "modifyEntryOps": [ + "0" + ], + "modifyRDNOps": [ + "0" + ], + "namingContexts": [ + "" + ], + "oneLevelSearchOps": [ + "0" + ], + "outBytes": [ + "14" + ], + "readOps": [ + "1" + ], + "referralsReturned": [ + "0" + ], + "removeEntryOps": [ + "0" + ], + "repUpdatesIn": [ + "0" + ], + "repUpdatesOut": [ + "0" + ], + "searchOps": [ + "1" + ], + "securityErrors": [ + "0" + ], + "simpleAuthBinds": [ + "1" + ], + "strongAuthBinds": [ + "0" + ], + "subschemaSubentry": [ + "cn=schema" + ], + "supportedCapabilities": [], + "supportedControl": [ + "2.16.840.1.113719.1.27.101.6", + "2.16.840.1.113719.1.27.101.5", + "1.2.840.113556.1.4.319", + "2.16.840.1.113730.3.4.3", + "2.16.840.1.113730.3.4.2", + "2.16.840.1.113719.1.27.101.57", + "2.16.840.1.113719.1.27.103.7", + "2.16.840.1.113719.1.27.101.40", + "2.16.840.1.113719.1.27.101.41", + "1.2.840.113556.1.4.1413", + "1.2.840.113556.1.4.805", + "2.16.840.1.113730.3.4.18", + "1.2.840.113556.1.4.529" + ], + "supportedExtension": [ + "2.16.840.1.113719.1.148.100.1", + "2.16.840.1.113719.1.148.100.3", + "2.16.840.1.113719.1.148.100.5", + "2.16.840.1.113719.1.148.100.7", + "2.16.840.1.113719.1.148.100.9", + "2.16.840.1.113719.1.148.100.11", + "2.16.840.1.113719.1.148.100.13", + "2.16.840.1.113719.1.148.100.15", + "2.16.840.1.113719.1.148.100.17", + "2.16.840.1.113719.1.39.42.100.1", + "2.16.840.1.113719.1.39.42.100.3", + "2.16.840.1.113719.1.39.42.100.5", + "2.16.840.1.113719.1.39.42.100.7", + "2.16.840.1.113719.1.39.42.100.9", + "2.16.840.1.113719.1.39.42.100.11", + "2.16.840.1.113719.1.39.42.100.13", + "2.16.840.1.113719.1.39.42.100.15", + "2.16.840.1.113719.1.39.42.100.17", + "2.16.840.1.113719.1.39.42.100.19", + "2.16.840.1.113719.1.39.42.100.21", + "2.16.840.1.113719.1.39.42.100.23", + "2.16.840.1.113719.1.39.42.100.25", + "2.16.840.1.113719.1.39.42.100.27", + "2.16.840.1.113719.1.39.42.100.29", + "1.3.6.1.4.1.4203.1.11.1", + "2.16.840.1.113719.1.27.100.1", + "2.16.840.1.113719.1.27.100.3", + "2.16.840.1.113719.1.27.100.5", + "2.16.840.1.113719.1.27.100.7", + "2.16.840.1.113719.1.27.100.11", + "2.16.840.1.113719.1.27.100.13", + "2.16.840.1.113719.1.27.100.15", + "2.16.840.1.113719.1.27.100.17", + "2.16.840.1.113719.1.27.100.19", + "2.16.840.1.113719.1.27.100.21", + "2.16.840.1.113719.1.27.100.23", + "2.16.840.1.113719.1.27.100.25", + "2.16.840.1.113719.1.27.100.27", + "2.16.840.1.113719.1.27.100.29", + "2.16.840.1.113719.1.27.100.31", + "2.16.840.1.113719.1.27.100.33", + "2.16.840.1.113719.1.27.100.35", + "2.16.840.1.113719.1.27.100.37", + "2.16.840.1.113719.1.27.100.39", + "2.16.840.1.113719.1.27.100.41", + "2.16.840.1.113719.1.27.100.96", + "2.16.840.1.113719.1.27.100.98", + "2.16.840.1.113719.1.27.100.101", + "2.16.840.1.113719.1.27.100.103", + "2.16.840.1.113719.1.142.100.1", + "2.16.840.1.113719.1.142.100.4", + "2.16.840.1.113719.1.142.100.6", + "2.16.840.1.113719.1.27.100.9", + "2.16.840.1.113719.1.27.100.43", + "2.16.840.1.113719.1.27.100.45", + "2.16.840.1.113719.1.27.100.47", + "2.16.840.1.113719.1.27.100.49", + "2.16.840.1.113719.1.27.100.51", + "2.16.840.1.113719.1.27.100.53", + "2.16.840.1.113719.1.27.100.55", + "1.3.6.1.4.1.1466.20037", + "2.16.840.1.113719.1.27.100.79", + "2.16.840.1.113719.1.27.100.84", + "2.16.840.1.113719.1.27.103.1", + "2.16.840.1.113719.1.27.103.2" + ], + "supportedFeatures": [ + "1.3.6.1.4.1.4203.1.5.1", + "2.16.840.1.113719.1.27.99.1" + ], + "supportedGroupingTypes": [ + "2.16.840.1.113719.1.27.103.8" + ], + "supportedLDAPVersion": [ + "2", + "3" + ], + "supportedSASLMechanisms": [ + "NMAS_LOGIN" + ], + "unAuthBinds": [ + "0" + ], + "vendorName": [ + "NetIQ Corporation" + ], + "vendorVersion": [ + "LDAP Agent for NetIQ eDirectory 9.1.4 (40105.09)" + ], + "wholeSubtreeSearchOps": [ + "0" + ] + }, + "type": "DsaInfo" +} +""" \ No newline at end of file diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/slapd24.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/slapd24.py new file mode 100644 index 00000000..414c37b3 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/schemas/slapd24.py @@ -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 . + +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: , , ' 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 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" +} +""" diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/asyncStream.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/asyncStream.py new file mode 100644 index 00000000..e3481e05 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/asyncStream.py @@ -0,0 +1,119 @@ +""" +""" + +# Created on 2016.07.10 +# +# 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 . + +try: + from queue import Queue +except ImportError: # Python 2 + # noinspection PyUnresolvedReferences + from Queue import Queue + +from io import StringIO +from os import linesep + +from ..protocol.rfc2849 import decode_persistent_search_control +from ..strategy.asynchronous import AsyncStrategy +from ..core.exceptions import LDAPLDIFError +from ..utils.conv import prepare_for_stream +from ..protocol.rfc2849 import persistent_search_response_to_ldif, add_ldif_header + + +# noinspection PyProtectedMember +class AsyncStreamStrategy(AsyncStrategy): + """ + This strategy is asynchronous. It streams responses in a generator as they appear in the self._responses container + """ + def __init__(self, ldap_connection): + AsyncStrategy.__init__(self, ldap_connection) + self.can_stream = True + self.line_separator = linesep + self.all_base64 = False + self.stream = None + self.order = dict() + self._header_added = False + self.persistent_search_message_id = None + self.streaming = False + self.callback = None + if ldap_connection.pool_size: + self.events = Queue(ldap_connection.pool_size) + else: + self.events = Queue() + + del self._requests # remove _requests dict from Async Strategy + + def _start_listen(self): + AsyncStrategy._start_listen(self) + if self.streaming: + if not self.stream or (isinstance(self.stream, StringIO) and self.stream.closed): + self.set_stream(StringIO()) + + def _stop_listen(self): + AsyncStrategy._stop_listen(self) + if self.streaming: + self.stream.close() + + def accumulate_stream(self, message_id, change): + if message_id == self.persistent_search_message_id: + with self.async_lock: + self._responses[message_id] = [] + if self.streaming: + if not self._header_added and self.stream.tell() == 0: + header = add_ldif_header(['-'])[0] + self.stream.write(prepare_for_stream(header + self.line_separator + self.line_separator)) + ldif_lines = persistent_search_response_to_ldif(change) + if self.stream and ldif_lines and not self.connection.closed: + fragment = self.line_separator.join(ldif_lines) + if not self._header_added and self.stream.tell() == 0: + self._header_added = True + header = add_ldif_header(['-'])[0] + self.stream.write(prepare_for_stream(header + self.line_separator + self.line_separator)) + self.stream.write(prepare_for_stream(fragment + self.line_separator + self.line_separator)) + else: # strategy is not streaming, events are added to a queue + notification = decode_persistent_search_control(change) + if notification: + change.update(notification) + del change['controls']['2.16.840.1.113730.3.4.7'] + if not self.callback: + self.events.put(change) + else: + self.callback(change) + + def get_stream(self): + if self.streaming: + return self.stream + return None + + def set_stream(self, value): + error = False + try: + if not value.writable(): + error = True + except (ValueError, AttributeError): + error = True + + if error: + raise LDAPLDIFError('stream must be writable') + + self.stream = value + self.streaming = True diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/asynchronous.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/asynchronous.py new file mode 100644 index 00000000..613db2a7 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/asynchronous.py @@ -0,0 +1,292 @@ +""" +""" + +# Created on 2013.07.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 . + +from threading import Thread, Lock, Event +import socket + +from .. import get_config_parameter, DIGEST_MD5 +from ..core.exceptions import LDAPSSLConfigurationError, LDAPStartTLSError, LDAPOperationResult, LDAPSignatureVerificationFailedError +from ..strategy.base import BaseStrategy, RESPONSE_COMPLETE +from ..protocol.rfc4511 import LDAPMessage +from ..utils.log import log, log_enabled, format_ldap_message, ERROR, NETWORK, EXTENDED +from ..utils.asn1 import decoder, decode_message_fast +from ..protocol.sasl.digestMd5 import md5_hmac + + +# noinspection PyProtectedMember +class AsyncStrategy(BaseStrategy): + """ + This strategy is asynchronous. You send the request and get the messageId of the request sent + Receiving data from socket is managed in a separated thread in a blocking mode + Requests return an int value to indicate the messageId of the requested Operation + You get the response with get_response, it has a timeout to wait for response to appear + Connection.response will contain the whole LDAP response for the messageId requested in a dict form + Connection.request will contain the result LDAP message in a dict form + Response appear in strategy._responses dictionary + """ + + # noinspection PyProtectedMember + class ReceiverSocketThread(Thread): + """ + The thread that actually manage the receiver socket + """ + + def __init__(self, ldap_connection): + Thread.__init__(self) + self.connection = ldap_connection + self.socket_size = get_config_parameter('SOCKET_SIZE') + + def run(self): + """ + Waits for data on socket, computes the length of the message and waits for enough bytes to decode the message + Message are appended to strategy._responses + """ + unprocessed = b'' + get_more_data = True + listen = True + data = b'' + sasl_total_bytes_recieved = 0 + sasl_received_data = b'' # used to verify the signature, typo GC + sasl_next_packet = b'' + sasl_buffer_length = -1 + # sasl_signature = b'' # not needed here GC + # sasl_sec_num = b'' # used to verify the signature, not needed here GC + + while listen: + if get_more_data: + try: + data = self.connection.socket.recv(self.socket_size) + except (OSError, socket.error, AttributeError): + if self.connection.receive_timeout: # a receive timeout has been detected - keep kistening on the socket + continue + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', str(e), self.connection) + raise # unexpected exception - re-raise + if len(data) > 0: + # If we are using DIGEST-MD5 and LDAP signing is set : verify & remove the signature from the message + if self.connection.sasl_mechanism == DIGEST_MD5 and self.connection._digest_md5_kis and not self.connection.sasl_in_progress: + data = sasl_next_packet + data + + if sasl_received_data == b'' or sasl_next_packet: + # Remove the sizeOf(encoded_message + signature + 0x0001 + secNum) from data. + sasl_buffer_length = int.from_bytes(data[0:4], "big") + data = data[4:] + sasl_next_packet = b'' + sasl_total_bytes_recieved += len(data) + sasl_received_data += data + + if sasl_total_bytes_recieved >= sasl_buffer_length: + # When the LDAP response is splitted accross multiple TCP packets, the SASL buffer length is equal to the MTU of each packet..Which is usually not equal to self.socket_size + # This means that the end of one SASL packet/beginning of one other....could be located in the middle of data + # We are using "sasl_received_data" instead of "data" & "unprocessed" for this reason + + # structure of messages when LDAP signing is enabled : sizeOf(encoded_message + signature + 0x0001 + secNum) + encoded_message + signature + 0x0001 + secNum + sasl_signature = sasl_received_data[sasl_buffer_length - 16:sasl_buffer_length - 6] + sasl_sec_num = sasl_received_data[sasl_buffer_length - 4:sasl_buffer_length] + sasl_next_packet = sasl_received_data[sasl_buffer_length:] # the last "data" variable may contain another sasl packet. We'll process it at the next iteration. + sasl_received_data = sasl_received_data[:sasl_buffer_length - 16] # remove signature + 0x0001 + secNum + the next packet if any, from sasl_received_data + + kis = self.connection._digest_md5_kis # renamed to lowercase GC + calculated_signature = bytes.fromhex(md5_hmac(kis, sasl_sec_num + sasl_received_data)[0:20]) + if sasl_signature != calculated_signature: + raise LDAPSignatureVerificationFailedError("Signature verification failed for the recieved LDAP message number " + str(int.from_bytes(sasl_sec_num, 'big')) + ". Expected signature " + calculated_signature.hex() + " but got " + sasl_signature.hex() + ".") + sasl_total_bytes_recieved = 0 + unprocessed += sasl_received_data + sasl_received_data = b'' + else: + unprocessed += data + data = b'' + else: + listen = False + length = BaseStrategy.compute_ldap_message_size(unprocessed) + if length == -1 or len(unprocessed) < length: + get_more_data = True + elif len(unprocessed) >= length: # add message to message list + if self.connection.usage: + self.connection._usage.update_received_message(length) + if log_enabled(NETWORK): + log(NETWORK, 'received %d bytes via <%s>', length, self.connection) + if self.connection.fast_decoder: + ldap_resp = decode_message_fast(unprocessed[:length]) + dict_response = self.connection.strategy.decode_response_fast(ldap_resp) + else: + ldap_resp = decoder.decode(unprocessed[:length], asn1Spec=LDAPMessage())[0] + dict_response = self.connection.strategy.decode_response(ldap_resp) + message_id = int(ldap_resp['messageID']) + if log_enabled(NETWORK): + log(NETWORK, 'received 1 ldap message via <%s>', self.connection) + if log_enabled(EXTENDED): + log(EXTENDED, 'ldap message received via <%s>:%s', self.connection, format_ldap_message(ldap_resp, '<<')) + if dict_response['type'] == 'extendedResp' and (dict_response['responseName'] == '1.3.6.1.4.1.1466.20037' or hasattr(self.connection, '_awaiting_for_async_start_tls')): + if dict_response['result'] == 0: # StartTls in progress + if self.connection.server.tls: + self.connection.server.tls._start_tls(self.connection) + else: + self.connection.last_error = 'no Tls object defined in Server' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSSLConfigurationError(self.connection.last_error) + else: + self.connection.last_error = 'asynchronous StartTls failed' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPStartTLSError(self.connection.last_error) + del self.connection._awaiting_for_async_start_tls + if message_id != 0: # 0 is reserved for 'Unsolicited Notification' from server as per RFC4511 (paragraph 4.4) + with self.connection.strategy.async_lock: + if message_id in self.connection.strategy._responses: + self.connection.strategy._responses[message_id].append(dict_response) + else: + self.connection.strategy._responses[message_id] = [dict_response] + if dict_response['type'] not in ['searchResEntry', 'searchResRef', 'intermediateResponse']: + self.connection.strategy._responses[message_id].append(RESPONSE_COMPLETE) + self.connection.strategy.set_event_for_message(message_id) + + if self.connection.strategy.can_stream: # for AsyncStreamStrategy, used for PersistentSearch + self.connection.strategy.accumulate_stream(message_id, dict_response) + unprocessed = unprocessed[length:] + get_more_data = False if unprocessed else True + listen = True if self.connection.listening or unprocessed else False + else: # Unsolicited Notification + if dict_response['responseName'] == '1.3.6.1.4.1.1466.20036': # Notice of Disconnection as per RFC4511 (paragraph 4.4.1) + listen = False + else: + self.connection.last_error = 'unknown unsolicited notification from server' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPStartTLSError(self.connection.last_error) + self.connection.strategy.close() + + def __init__(self, ldap_connection): + BaseStrategy.__init__(self, ldap_connection) + self.sync = False + self.no_real_dsa = False + self.pooled = False + self._responses = None + self._requests = None + self.can_stream = False + self.receiver = None + self.async_lock = Lock() + self.event_lock = Lock() + self._events = {} + + def open(self, reset_usage=True, read_server_info=True): + """ + Open connection and start listen on the socket in a different thread + """ + with self.connection.connection_lock: + self._responses = dict() + self._requests = dict() + BaseStrategy.open(self, reset_usage, read_server_info) + + if read_server_info: + try: + self.connection.refresh_server_info() + except LDAPOperationResult: # catch errors from server if raise_exception = True + self.connection.server._dsa_info = None + self.connection.server._schema_info = None + + def close(self): + """ + Close connection and stop socket thread + """ + with self.connection.connection_lock: + BaseStrategy.close(self) + + def _add_event_for_message(self, message_id): + with self.event_lock: + # Should have the check here because the receiver thread may has created it + if message_id not in self._events: + self._events[message_id] = Event() + + def set_event_for_message(self, message_id): + with self.event_lock: + # The receiver thread may receive the response before the sender set the event for the message_id, + # so we have to check if the event exists + if message_id not in self._events: + self._events[message_id] = Event() + self._events[message_id].set() + + def _get_event_for_message(self, message_id): + with self.event_lock: + if message_id not in self._events: + raise RuntimeError('Event for message[{}] should have been created before accessing'.format(message_id)) + return self._events[message_id] + + def post_send_search(self, message_id): + """ + Clears connection.response and returns messageId + """ + self.connection.response = None + self.connection.request = None + self.connection.result = None + self._add_event_for_message(message_id) + return message_id + + def post_send_single_response(self, message_id): + """ + Clears connection.response and returns messageId. + """ + self.connection.response = None + self.connection.request = None + self.connection.result = None + self._add_event_for_message(message_id) + return message_id + + def _start_listen(self): + """ + Start thread in daemon mode + """ + if not self.connection.listening: + self.receiver = AsyncStrategy.ReceiverSocketThread(self.connection) + self.connection.listening = True + self.receiver.daemon = True + self.receiver.start() + + def _get_response(self, message_id, timeout): + """ + Performs the capture of LDAP response for this strategy + The response is only complete after the event been set + """ + event = self._get_event_for_message(message_id) + flag = event.wait(timeout) + if not flag: + # timeout + return None + + # In this stage we could ensure the response is already there + self._events.pop(message_id) + with self.async_lock: + return self._responses.pop(message_id) + + def receiving(self): + raise NotImplementedError + + def get_stream(self): + raise NotImplementedError + + def set_stream(self, value): + raise NotImplementedError diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/base.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/base.py new file mode 100644 index 00000000..6b6211ee --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/base.py @@ -0,0 +1,925 @@ +""" +""" + +# Created on 2013.07.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 dectails. +# +# 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 . + +import socket +try: # try to discover if unix sockets are available for LDAP over IPC (ldapi:// scheme) + # noinspection PyUnresolvedReferences + from socket import AF_UNIX + unix_socket_available = True +except ImportError: + unix_socket_available = False +from struct import pack +from platform import system +from random import choice + +from .. import SYNC, ANONYMOUS, get_config_parameter, BASE, ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES, DIGEST_MD5 +from ..core.results import DO_NOT_RAISE_EXCEPTIONS, RESULT_REFERRAL +from ..core.exceptions import LDAPOperationResult, LDAPSASLBindInProgressError, LDAPSocketOpenError, LDAPSessionTerminatedByServerError,\ + LDAPUnknownResponseError, LDAPUnknownRequestError, LDAPReferralError, communication_exception_factory, LDAPStartTLSError, \ + LDAPSocketSendError, LDAPExceptionError, LDAPControlError, LDAPResponseTimeoutError, LDAPTransactionError +from ..utils.uri import parse_uri +from ..protocol.rfc4511 import LDAPMessage, ProtocolOp, MessageID, SearchResultEntry +from ..operation.add import add_response_to_dict, add_request_to_dict +from ..operation.modify import modify_request_to_dict, modify_response_to_dict +from ..operation.search import search_result_reference_response_to_dict, search_result_done_response_to_dict,\ + search_result_entry_response_to_dict, search_request_to_dict, search_result_entry_response_to_dict_fast,\ + search_result_reference_response_to_dict_fast, attributes_to_dict, attributes_to_dict_fast +from ..operation.bind import bind_response_to_dict, bind_request_to_dict, sicily_bind_response_to_dict, bind_response_to_dict_fast, \ + sicily_bind_response_to_dict_fast +from ..operation.compare import compare_response_to_dict, compare_request_to_dict +from ..operation.extended import extended_request_to_dict, extended_response_to_dict, intermediate_response_to_dict, extended_response_to_dict_fast, intermediate_response_to_dict_fast +from ..core.server import Server +from ..operation.modifyDn import modify_dn_request_to_dict, modify_dn_response_to_dict +from ..operation.delete import delete_response_to_dict, delete_request_to_dict +from ..protocol.convert import prepare_changes_for_request, build_controls_list +from ..operation.abandon import abandon_request_to_dict +from ..core.tls import Tls +from ..protocol.oid import Oids +from ..protocol.rfc2696 import RealSearchControlValue +from ..protocol.microsoft import DirSyncControlResponseValue +from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, NETWORK, EXTENDED, format_ldap_message +from ..utils.asn1 import encode, decoder, ldap_result_to_dict_fast, decode_sequence +from ..utils.conv import to_unicode +from ..protocol.sasl.digestMd5 import md5_h, md5_hmac + +SESSION_TERMINATED_BY_SERVER = 'TERMINATED_BY_SERVER' +TRANSACTION_ERROR = 'TRANSACTION_ERROR' +RESPONSE_COMPLETE = 'RESPONSE_FROM_SERVER_COMPLETE' + + +# noinspection PyProtectedMember +class BaseStrategy(object): + """ + Base class for connection strategy + """ + + def __init__(self, ldap_connection): + self.connection = ldap_connection + self._outstanding = None + self._referrals = [] + self.sync = None # indicates a synchronous connection + self.no_real_dsa = None # indicates a connection to a fake LDAP server + self.pooled = None # Indicates a connection with a connection pool + self.can_stream = None # indicates if a strategy keeps a stream of responses (i.e. LdifProducer can accumulate responses with a single header). Stream must be initialized and closed in _start_listen() and _stop_listen() + self.referral_cache = {} + self.thread_safe = False # Indicates that connection can be used in a multithread application + if log_enabled(BASIC): + log(BASIC, 'instantiated <%s>: <%s>', self.__class__.__name__, self) + + def __str__(self): + s = [ + str(self.connection) if self.connection else 'None', + 'sync' if self.sync else 'async', + 'no real DSA' if self.no_real_dsa else 'real DSA', + 'pooled' if self.pooled else 'not pooled', + 'can stream output' if self.can_stream else 'cannot stream output', + ] + return ' - '.join(s) + + def open(self, reset_usage=True, read_server_info=True): + """ + Open a socket to a server. Choose a server from the server pool if available + """ + if log_enabled(NETWORK): + log(NETWORK, 'opening connection for <%s>', self.connection) + if self.connection.lazy and not self.connection._executing_deferred: + self.connection._deferred_open = True + self.connection.closed = False + if log_enabled(NETWORK): + log(NETWORK, 'deferring open connection for <%s>', self.connection) + else: + if not self.connection.closed and not self.connection._executing_deferred: # try to close connection if still open + self.close() + + self._outstanding = dict() + if self.connection.usage: + if reset_usage or not self.connection._usage.initial_connection_start_time: + self.connection._usage.start() + + if self.connection.server_pool: + new_server = self.connection.server_pool.get_server(self.connection) # get a server from the server_pool if available + if self.connection.server != new_server: + self.connection.server = new_server + if self.connection.usage: + self.connection._usage.servers_from_pool += 1 + + exception_history = [] + if not self.no_real_dsa: # tries to connect to a real server + for candidate_address in self.connection.server.candidate_addresses(): + try: + if log_enabled(BASIC): + log(BASIC, 'try to open candidate address %s', candidate_address[:-2]) + self._open_socket(candidate_address, self.connection.server.ssl, unix_socket=self.connection.server.ipc) + self.connection.server.current_address = candidate_address + self.connection.server.update_availability(candidate_address, True) + break + except Exception as e: + self.connection.server.update_availability(candidate_address, False) + # exception_history.append((datetime.now(), exc_type, exc_value, candidate_address[4])) + exception_history.append((type(e)(str(e)), candidate_address[4])) + if not self.connection.server.current_address and exception_history: + if len(exception_history) == 1: # only one exception, reraise + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', str(exception_history[0][0]) + ' ' + str((exception_history[0][1])), self.connection) + raise exception_history[0][0] + else: + if log_enabled(ERROR): + log(ERROR, 'unable to open socket for <%s>', self.connection) + raise LDAPSocketOpenError('unable to open socket', exception_history) + elif not self.connection.server.current_address: + if log_enabled(ERROR): + log(ERROR, 'invalid server address for <%s>', self.connection) + raise LDAPSocketOpenError('invalid server address') + + self.connection._deferred_open = False + self._start_listen() + if log_enabled(NETWORK): + log(NETWORK, 'connection open for <%s>', self.connection) + + def close(self): + """ + Close connection + """ + if log_enabled(NETWORK): + log(NETWORK, 'closing connection for <%s>', self.connection) + if self.connection.lazy and not self.connection._executing_deferred and (self.connection._deferred_bind or self.connection._deferred_open): + self.connection.listening = False + self.connection.closed = True + if log_enabled(NETWORK): + log(NETWORK, 'deferred connection closed for <%s>', self.connection) + else: + if not self.connection.closed: + self._stop_listen() + if not self. no_real_dsa: + self._close_socket() + if log_enabled(NETWORK): + log(NETWORK, 'connection closed for <%s>', self.connection) + + self.connection.bound = False + self.connection.request = None + self.connection.response = None + self.connection.tls_started = False + self._outstanding = None + self._referrals = [] + + if not self.connection.strategy.no_real_dsa: + self.connection.server.current_address = None + if self.connection.usage: + self.connection._usage.stop() + + def _open_socket(self, address, use_ssl=False, unix_socket=False): + """ + Tries to open and connect a socket to a Server + raise LDAPExceptionError if unable to open or connect socket + """ + try: + self.connection.socket = socket.socket(*address[:3]) + except Exception as e: + self.connection.last_error = 'socket creation error: ' + str(e) + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise communication_exception_factory(LDAPSocketOpenError, exc)(self.connection.last_error) + raise communication_exception_factory(LDAPSocketOpenError, type(e)(str(e)))(self.connection.last_error) + # Try to bind the socket locally before connecting to the remote address + # We go through our connection's source ports and try to bind our socket to our connection's source address + # with them. + # If no source address or ports were specified, this will have the same success/fail result as if we + # tried to connect to the remote server without binding locally first. + # This is actually a little bit better, as it lets us distinguish the case of "issue binding the socket + # locally" from "remote server is unavailable" with more clarity, though this will only really be an + # issue when no source address/port is specified if the system checking server availability is running + # as a very unprivileged user. + last_bind_exc = None + if unix_socket_available and self.connection.socket.family != socket.AF_UNIX: + socket_bind_succeeded = False + for source_port in self.connection.source_port_list: + try: + self.connection.socket.bind((self.connection.source_address, source_port)) + socket_bind_succeeded = True + break + except Exception as bind_ex: + last_bind_exc = bind_ex + # we'll always end up logging at error level if we cannot bind any ports to the address locally. + # but if some work and some don't you probably don't want the ones that don't at ERROR level + if log_enabled(NETWORK): + log(NETWORK, 'Unable to bind to local address <%s> with source port <%s> due to <%s>', + self.connection.source_address, source_port, bind_ex) + if not socket_bind_succeeded: + self.connection.last_error = 'socket connection error while locally binding: ' + str(last_bind_exc) + if log_enabled(ERROR): + log(ERROR, 'Unable to locally bind to local address <%s> with any of the source ports <%s> for connection <%s due to <%s>', + self.connection.source_address, self.connection.source_port_list, self.connection, last_bind_exc) + raise communication_exception_factory(LDAPSocketOpenError, type(last_bind_exc)(str(last_bind_exc)))(last_bind_exc) + + try: # set socket timeout for opening connection + if self.connection.server.connect_timeout: + self.connection.socket.settimeout(self.connection.server.connect_timeout) + self.connection.socket.connect(address[4]) + except socket.error as e: + self.connection.last_error = 'socket connection error while opening: ' + str(e) + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise communication_exception_factory(LDAPSocketOpenError, exc)(self.connection.last_error) + raise communication_exception_factory(LDAPSocketOpenError, type(e)(str(e)))(self.connection.last_error) + + # Set connection recv timeout (must be set after connect, + # because socket.settimeout() affects both, connect() as + # well as recv(). Set it before tls.wrap_socket() because + # the recv timeout should take effect during the TLS + # handshake. + if self.connection.receive_timeout is not None: + try: # set receive timeout for the connection socket + self.connection.socket.settimeout(self.connection.receive_timeout) + if system().lower() == 'windows': + self.connection.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, int(1000 * self.connection.receive_timeout)) + else: + self.connection.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, pack('LL', self.connection.receive_timeout, 0)) + except socket.error as e: + self.connection.last_error = 'unable to set receive timeout for socket connection: ' + str(e) + + # if exc: + # if log_enabled(ERROR): + # log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise communication_exception_factory(LDAPSocketOpenError, exc)(self.connection.last_error) + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise communication_exception_factory(LDAPSocketOpenError, type(e)(str(e)))(self.connection.last_error) + + if use_ssl: + try: + self.connection.server.tls.wrap_socket(self.connection, do_handshake=True) + if self.connection.usage: + self.connection._usage.wrapped_sockets += 1 + except Exception as e: + self.connection.last_error = 'socket ssl wrapping error: ' + str(e) + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise communication_exception_factory(LDAPSocketOpenError, type(e)(str(e)))(self.connection.last_error) + if self.connection.usage: + self.connection._usage.open_sockets += 1 + + self.connection.closed = False + + def _close_socket(self): + """ + Try to close a socket + don't raise exception if unable to close socket, assume socket is already closed + """ + + try: + self.connection.socket.shutdown(socket.SHUT_RDWR) + except Exception: + pass + + try: + self.connection.socket.close() + except Exception: + pass + + self.connection.socket = None + self.connection.closed = True + + if self.connection.usage: + self.connection._usage.closed_sockets += 1 + + def _stop_listen(self): + self.connection.listening = False + + def send(self, message_type, request, controls=None): + """ + Send an LDAP message + Returns the message_id + """ + self.connection.request = None + if self.connection.listening: + if self.connection.sasl_in_progress and message_type not in ['bindRequest']: # as per RFC4511 (4.2.1) + self.connection.last_error = 'cannot send operation requests while SASL bind is in progress' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSASLBindInProgressError(self.connection.last_error) + message_id = self.connection.server.next_message_id() + ldap_message = LDAPMessage() + ldap_message['messageID'] = MessageID(message_id) + ldap_message['protocolOp'] = ProtocolOp().setComponentByName(message_type, request) + message_controls = build_controls_list(controls) + if message_controls is not None: + ldap_message['controls'] = message_controls + self.connection.request = BaseStrategy.decode_request(message_type, request, controls) + self._outstanding[message_id] = self.connection.request + self.sending(ldap_message) + else: + self.connection.last_error = 'unable to send message, socket is not open' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketOpenError(self.connection.last_error) + + return message_id + + def get_response(self, message_id, timeout=None, get_request=False): + """ + Get response LDAP messages + Responses are returned by the underlying connection strategy + Check if message_id LDAP message is still outstanding and wait for timeout to see if it appears in _get_response + Result is stored in connection.result + Responses without result is stored in connection.response + A tuple (responses, result) is returned + """ + if timeout is None: + timeout = get_config_parameter('RESPONSE_WAITING_TIMEOUT') + response = None + result = None + # request = None + if self._outstanding and message_id in self._outstanding: + responses = self._get_response(message_id, timeout) + + if not responses: + if log_enabled(ERROR): + log(ERROR, 'socket timeout, no response from server for <%s>', self.connection) + raise LDAPResponseTimeoutError('no response from server') + + if responses == SESSION_TERMINATED_BY_SERVER: + try: # try to close the session but don't raise any error if server has already closed the session + self.close() + except (socket.error, LDAPExceptionError): + pass + self.connection.last_error = 'session terminated by server' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSessionTerminatedByServerError(self.connection.last_error) + elif responses == TRANSACTION_ERROR: # Novell LDAP Transaction unsolicited notification + self.connection.last_error = 'transaction error' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPTransactionError(self.connection.last_error) + + # if referral in response opens a new connection to resolve referrals if requested + + if responses[-2]['result'] == RESULT_REFERRAL: + if self.connection.usage: + self.connection._usage.referrals_received += 1 + if self.connection.auto_referrals: + ref_response, ref_result = self.do_operation_on_referral(self._outstanding[message_id], responses[-2]['referrals']) + if ref_response is not None: + responses = ref_response + [ref_result] + responses.append(RESPONSE_COMPLETE) + elif ref_result is not None: + responses = [ref_result, RESPONSE_COMPLETE] + + self._referrals = [] + + if responses: + result = responses[-2] + response = responses[:-2] + self.connection.result = None + self.connection.response = None + + if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection) + self._outstanding.pop(message_id) + self.connection.result = result.copy() + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + # checks if any response has a range tag + # self._auto_range_searching is set as a flag to avoid recursive searches + if self.connection.auto_range and not hasattr(self, '_auto_range_searching') and any((True for resp in response if 'raw_attributes' in resp for name in resp['raw_attributes'] if ';range=' in name)): + self._auto_range_searching = result.copy() + temp_response = response[:] # copy + if self.do_search_on_auto_range(self._outstanding[message_id], response): + for resp in temp_response: + if resp['type'] == 'searchResEntry': + keys = [key for key in resp['raw_attributes'] if ';range=' in key] + for key in keys: + del resp['raw_attributes'][key] + del resp['attributes'][key] + response = temp_response + result = self._auto_range_searching + del self._auto_range_searching + + if self.connection.empty_attributes: + for entry in response: + if entry['type'] == 'searchResEntry': + for attribute_type in self._outstanding[message_id]['attributes']: + if attribute_type not in entry['raw_attributes'] and attribute_type not in (ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES): + entry['raw_attributes'][attribute_type] = list() + entry['attributes'][attribute_type] = list() + if log_enabled(PROTOCOL): + log(PROTOCOL, 'attribute set to empty list for missing attribute <%s> in <%s>', attribute_type, self) + if not self.connection.auto_range: + attrs_to_remove = [] + # removes original empty attribute in case a range tag is returned + for attribute_type in entry['attributes']: + if ';range' in attribute_type.lower(): + orig_attr, _, _ = attribute_type.partition(';') + attrs_to_remove.append(orig_attr) + for attribute_type in attrs_to_remove: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'attribute type <%s> removed in response because of same attribute returned as range by the server in <%s>', attribute_type, self) + del entry['raw_attributes'][attribute_type] + del entry['attributes'][attribute_type] + + request = self._outstanding.pop(message_id) + else: + if log_enabled(ERROR): + log(ERROR, 'message id not in outstanding queue for <%s>', self.connection) + raise(LDAPResponseTimeoutError('message id not in outstanding queue')) + + if get_request: + return response, result, request + else: + return response, result + + @staticmethod + def compute_ldap_message_size(data): + """ + Compute LDAP Message size according to BER definite length rules + Returns -1 if too few data to compute message length + """ + if isinstance(data, str): # fix for Python 2, data is string not bytes + data = bytearray(data) # Python 2 bytearray is equivalent to Python 3 bytes + + ret_value = -1 + if len(data) > 2: + if data[1] <= 127: # BER definite length - short form. Highest bit of byte 1 is 0, message length is in the last 7 bits - Value can be up to 127 bytes long + ret_value = data[1] + 2 + else: # BER definite length - long form. Highest bit of byte 1 is 1, last 7 bits counts the number of following octets containing the value length + bytes_length = data[1] - 128 + if len(data) >= bytes_length + 2: + value_length = 0 + cont = bytes_length + for byte in data[2:2 + bytes_length]: + cont -= 1 + value_length += byte * (256 ** cont) + ret_value = value_length + 2 + bytes_length + + return ret_value + + def decode_response(self, ldap_message): + """ + Convert received LDAPMessage to a dict + """ + message_type = ldap_message.getComponentByName('protocolOp').getName() + component = ldap_message['protocolOp'].getComponent() + controls = ldap_message['controls'] if ldap_message['controls'].hasValue() else None + if message_type == 'bindResponse': + if not bytes(component['matchedDN']).startswith(b'NTLM'): # patch for microsoft ntlm authentication + result = bind_response_to_dict(component) + else: + result = sicily_bind_response_to_dict(component) + elif message_type == 'searchResEntry': + result = search_result_entry_response_to_dict(component, self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names) + elif message_type == 'searchResDone': + result = search_result_done_response_to_dict(component) + elif message_type == 'searchResRef': + result = search_result_reference_response_to_dict(component) + elif message_type == 'modifyResponse': + result = modify_response_to_dict(component) + elif message_type == 'addResponse': + result = add_response_to_dict(component) + elif message_type == 'delResponse': + result = delete_response_to_dict(component) + elif message_type == 'modDNResponse': + result = modify_dn_response_to_dict(component) + elif message_type == 'compareResponse': + result = compare_response_to_dict(component) + elif message_type == 'extendedResp': + result = extended_response_to_dict(component) + elif message_type == 'intermediateResponse': + result = intermediate_response_to_dict(component) + else: + if log_enabled(ERROR): + log(ERROR, 'unknown response <%s> for <%s>', message_type, self.connection) + raise LDAPUnknownResponseError('unknown response') + result['type'] = message_type + if controls: + result['controls'] = dict() + for control in controls: + decoded_control = self.decode_control(control) + result['controls'][decoded_control[0]] = decoded_control[1] + return result + + def decode_response_fast(self, ldap_message): + """ + Convert received LDAPMessage from fast ber decoder to a dict + """ + if ldap_message['protocolOp'] == 1: # bindResponse + if not ldap_message['payload'][1][3].startswith(b'NTLM'): # patch for microsoft ntlm authentication + result = bind_response_to_dict_fast(ldap_message['payload']) + else: + result = sicily_bind_response_to_dict_fast(ldap_message['payload']) + result['type'] = 'bindResponse' + elif ldap_message['protocolOp'] == 4: # searchResEntry' + result = search_result_entry_response_to_dict_fast(ldap_message['payload'], self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names) + result['type'] = 'searchResEntry' + elif ldap_message['protocolOp'] == 5: # searchResDone + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'searchResDone' + elif ldap_message['protocolOp'] == 19: # searchResRef + result = search_result_reference_response_to_dict_fast(ldap_message['payload']) + result['type'] = 'searchResRef' + elif ldap_message['protocolOp'] == 7: # modifyResponse + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'modifyResponse' + elif ldap_message['protocolOp'] == 9: # addResponse + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'addResponse' + elif ldap_message['protocolOp'] == 11: # delResponse + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'delResponse' + elif ldap_message['protocolOp'] == 13: # modDNResponse + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'modDNResponse' + elif ldap_message['protocolOp'] == 15: # compareResponse + result = ldap_result_to_dict_fast(ldap_message['payload']) + result['type'] = 'compareResponse' + elif ldap_message['protocolOp'] == 24: # extendedResp + result = extended_response_to_dict_fast(ldap_message['payload']) + result['type'] = 'extendedResp' + elif ldap_message['protocolOp'] == 25: # intermediateResponse + result = intermediate_response_to_dict_fast(ldap_message['payload']) + result['type'] = 'intermediateResponse' + else: + if log_enabled(ERROR): + log(ERROR, 'unknown response <%s> for <%s>', ldap_message['protocolOp'], self.connection) + raise LDAPUnknownResponseError('unknown response') + if ldap_message['controls']: + result['controls'] = dict() + for control in ldap_message['controls']: + decoded_control = self.decode_control_fast(control[3]) + result['controls'][decoded_control[0]] = decoded_control[1] + return result + + @staticmethod + def decode_control(control): + """ + decode control, return a 2-element tuple where the first element is the control oid + and the second element is a dictionary with description (from Oids), criticality and decoded control value + """ + control_type = str(control['controlType']) + criticality = bool(control['criticality']) + control_value = bytes(control['controlValue']) + unprocessed = None + if control_type == '1.2.840.113556.1.4.319': # simple paged search as per RFC2696 + control_resp, unprocessed = decoder.decode(control_value, asn1Spec=RealSearchControlValue()) + control_value = dict() + control_value['size'] = int(control_resp['size']) + control_value['cookie'] = bytes(control_resp['cookie']) + elif control_type == '1.2.840.113556.1.4.841': # DirSync AD + control_resp, unprocessed = decoder.decode(control_value, asn1Spec=DirSyncControlResponseValue()) + control_value = dict() + control_value['more_results'] = bool(control_resp['MoreResults']) # more_result if nonzero + control_value['cookie'] = bytes(control_resp['CookieServer']) + elif control_type == '1.3.6.1.1.13.1' or control_type == '1.3.6.1.1.13.2': # Pre-Read control, Post-Read Control as per RFC 4527 + control_resp, unprocessed = decoder.decode(control_value, asn1Spec=SearchResultEntry()) + control_value = dict() + control_value['result'] = attributes_to_dict(control_resp['attributes']) + if unprocessed: + if log_enabled(ERROR): + log(ERROR, 'unprocessed control response in substrate') + raise LDAPControlError('unprocessed control response in substrate') + return control_type, {'description': Oids.get(control_type, ''), 'criticality': criticality, 'value': control_value} + + @staticmethod + def decode_control_fast(control, from_server=True): + """ + decode control, return a 2-element tuple where the first element is the control oid + and the second element is a dictionary with description (from Oids), criticality and decoded control value + """ + control_type = str(to_unicode(control[0][3], from_server=from_server)) + criticality = False + control_value = None + for r in control[1:]: + if r[2] == 4: # controlValue + control_value = r[3] + else: + criticality = False if r[3] == 0 else True # criticality (booleand default to False) + if control_type == '1.2.840.113556.1.4.319': # simple paged search as per RFC2696 + control_resp = decode_sequence(control_value, 0, len(control_value)) + control_value = dict() + control_value['size'] = int(control_resp[0][3][0][3]) + control_value['cookie'] = bytes(control_resp[0][3][1][3]) + elif control_type == '1.2.840.113556.1.4.841': # DirSync AD + control_resp = decode_sequence(control_value, 0, len(control_value)) + control_value = dict() + control_value['more_results'] = True if control_resp[0][3][0][3] else False # more_result if nonzero + control_value['cookie'] = control_resp[0][3][2][3] + elif control_type == '1.3.6.1.1.13.1' or control_type == '1.3.6.1.1.13.2': # Pre-Read control, Post-Read Control as per RFC 4527 + control_resp = decode_sequence(control_value, 0, len(control_value)) + control_value = dict() + control_value['result'] = attributes_to_dict_fast(control_resp[0][3][1][3]) + return control_type, {'description': Oids.get(control_type, ''), 'criticality': criticality, 'value': control_value} + + @staticmethod + def decode_request(message_type, component, controls=None): + # message_type = ldap_message.getComponentByName('protocolOp').getName() + # component = ldap_message['protocolOp'].getComponent() + if message_type == 'bindRequest': + result = bind_request_to_dict(component) + elif message_type == 'unbindRequest': + result = dict() + elif message_type == 'addRequest': + result = add_request_to_dict(component) + elif message_type == 'compareRequest': + result = compare_request_to_dict(component) + elif message_type == 'delRequest': + result = delete_request_to_dict(component) + elif message_type == 'extendedReq': + result = extended_request_to_dict(component) + elif message_type == 'modifyRequest': + result = modify_request_to_dict(component) + elif message_type == 'modDNRequest': + result = modify_dn_request_to_dict(component) + elif message_type == 'searchRequest': + result = search_request_to_dict(component) + elif message_type == 'abandonRequest': + result = abandon_request_to_dict(component) + else: + if log_enabled(ERROR): + log(ERROR, 'unknown request <%s>', message_type) + raise LDAPUnknownRequestError('unknown request') + result['type'] = message_type + result['controls'] = controls + + return result + + def valid_referral_list(self, referrals): + referral_list = [] + for referral in referrals: + candidate_referral = parse_uri(referral) + if candidate_referral: + for ref_host in self.connection.server.allowed_referral_hosts: + if ref_host[0] == candidate_referral['host'] or ref_host[0] == '*': + if candidate_referral['host'] not in self._referrals: + candidate_referral['anonymousBindOnly'] = not ref_host[1] + referral_list.append(candidate_referral) + break + + return referral_list + + def do_next_range_search(self, request, response, attr_name): + done = False + current_response = response + while not done: + attr_type, _, returned_range = attr_name.partition(';range=') + _, _, high_range = returned_range.partition('-') + response['raw_attributes'][attr_type] += current_response['raw_attributes'][attr_name] + response['attributes'][attr_type] += current_response['attributes'][attr_name] + if high_range != '*': + if log_enabled(PROTOCOL): + log(PROTOCOL, 'performing next search on auto-range <%s> via <%s>', str(int(high_range) + 1), self.connection) + requested_range = attr_type + ';range=' + str(int(high_range) + 1) + '-*' + result = self.connection.search(search_base=response['dn'], + search_filter='(objectclass=*)', + search_scope=BASE, + dereference_aliases=request['dereferenceAlias'], + attributes=[attr_type + ';range=' + str(int(high_range) + 1) + '-*']) + if self.connection.strategy.thread_safe: + status, result, _response, _ = result + else: + status = result + result = self.connection.result + _response = self.connection.response + + if self.connection.strategy.sync: + if status: + current_response = _response[0] + else: + done = True + else: + current_response, _ = self.get_response(status) + current_response = current_response[0] + + if not done: + if requested_range in current_response['raw_attributes'] and len(current_response['raw_attributes'][requested_range]) == 0: + del current_response['raw_attributes'][requested_range] + del current_response['attributes'][requested_range] + attr_name = list(filter(lambda a: ';range=' in a, current_response['raw_attributes'].keys()))[0] + continue + done = True + + def do_search_on_auto_range(self, request, response): + for resp in [r for r in response if r['type'] == 'searchResEntry']: + for attr_name in list(resp['raw_attributes'].keys()): # generate list to avoid changing of dict size error + if ';range=' in attr_name: + attr_type, _, range_values = attr_name.partition(';range=') + if range_values in ('1-1', '0-0'): # DirSync returns these values for adding and removing members + return False + if attr_type not in resp['raw_attributes'] or resp['raw_attributes'][attr_type] is None: + resp['raw_attributes'][attr_type] = list() + if attr_type not in resp['attributes'] or resp['attributes'][attr_type] is None: + resp['attributes'][attr_type] = list() + self.do_next_range_search(request, resp, attr_name) + return True + + def create_referral_connection(self, referrals): + referral_connection = None + selected_referral = None + cachekey = None + valid_referral_list = self.valid_referral_list(referrals) + if valid_referral_list: + preferred_referral_list = [referral for referral in valid_referral_list if + referral['ssl'] == self.connection.server.ssl] + selected_referral = choice(preferred_referral_list) if preferred_referral_list else choice( + valid_referral_list) + + cachekey = (selected_referral['host'], selected_referral['port'] or self.connection.server.port, selected_referral['ssl']) + if self.connection.use_referral_cache and cachekey in self.referral_cache: + referral_connection = self.referral_cache[cachekey] + else: + referral_server = Server(host=selected_referral['host'], + port=selected_referral['port'] or self.connection.server.port, + use_ssl=selected_referral['ssl'], + get_info=self.connection.server.get_info, + formatter=self.connection.server.custom_formatter, + connect_timeout=self.connection.server.connect_timeout, + mode=self.connection.server.mode, + allowed_referral_hosts=self.connection.server.allowed_referral_hosts, + tls=Tls(local_private_key_file=self.connection.server.tls.private_key_file, + local_certificate_file=self.connection.server.tls.certificate_file, + validate=self.connection.server.tls.validate, + version=self.connection.server.tls.version, + ca_certs_file=self.connection.server.tls.ca_certs_file) if + selected_referral['ssl'] else None) + + from ..core.connection import Connection + + referral_connection = Connection(server=referral_server, + user=self.connection.user if not selected_referral['anonymousBindOnly'] else None, + password=self.connection.password if not selected_referral['anonymousBindOnly'] else None, + version=self.connection.version, + authentication=self.connection.authentication if not selected_referral['anonymousBindOnly'] else ANONYMOUS, + client_strategy=SYNC, + auto_referrals=True, + read_only=self.connection.read_only, + check_names=self.connection.check_names, + raise_exceptions=self.connection.raise_exceptions, + fast_decoder=self.connection.fast_decoder, + receive_timeout=self.connection.receive_timeout, + sasl_mechanism=self.connection.sasl_mechanism, + sasl_credentials=self.connection.sasl_credentials) + + if self.connection.usage: + self.connection._usage.referrals_connections += 1 + + referral_connection.open() + referral_connection.strategy._referrals = self._referrals + if self.connection.tls_started and not referral_server.ssl: # if the original server was in start_tls mode and the referral server is not in ssl then start_tls on the referral connection + if not referral_connection.start_tls(): + error = 'start_tls in referral not successful' + (' - ' + referral_connection.last_error if referral_connection.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.unbind() + raise LDAPStartTLSError(error) + + if self.connection.bound: + referral_connection.bind() + + if self.connection.usage: + self.connection._usage.referrals_followed += 1 + + return selected_referral, referral_connection, cachekey + + def do_operation_on_referral(self, request, referrals): + if log_enabled(PROTOCOL): + log(PROTOCOL, 'following referral for <%s>', self.connection) + selected_referral, referral_connection, cachekey = self.create_referral_connection(referrals) + if selected_referral: + if request['type'] == 'searchRequest': + referral_connection.search(selected_referral['base'] or request['base'], + selected_referral['filter'] or request['filter'], + selected_referral['scope'] or request['scope'], + request['dereferenceAlias'], + selected_referral['attributes'] or request['attributes'], + request['sizeLimit'], + request['timeLimit'], + request['typesOnly'], + controls=request['controls']) + elif request['type'] == 'addRequest': + referral_connection.add(selected_referral['base'] or request['entry'], + None, + request['attributes'], + controls=request['controls']) + elif request['type'] == 'compareRequest': + referral_connection.compare(selected_referral['base'] or request['entry'], + request['attribute'], + request['value'], + controls=request['controls']) + elif request['type'] == 'delRequest': + referral_connection.delete(selected_referral['base'] or request['entry'], + controls=request['controls']) + elif request['type'] == 'extendedReq': + referral_connection.extended(request['name'], + request['value'], + controls=request['controls'], + no_encode=True + ) + elif request['type'] == 'modifyRequest': + referral_connection.modify(selected_referral['base'] or request['entry'], + prepare_changes_for_request(request['changes']), + controls=request['controls']) + elif request['type'] == 'modDNRequest': + referral_connection.modify_dn(selected_referral['base'] or request['entry'], + request['newRdn'], + request['deleteOldRdn'], + request['newSuperior'], + controls=request['controls']) + else: + self.connection.last_error = 'referral operation not permitted' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPReferralError(self.connection.last_error) + + response = referral_connection.response + result = referral_connection.result + if self.connection.use_referral_cache: + self.referral_cache[cachekey] = referral_connection + else: + referral_connection.unbind() + else: + response = None + result = None + + return response, result + + def sending(self, ldap_message): + if log_enabled(NETWORK): + log(NETWORK, 'sending 1 ldap message for <%s>', self.connection) + try: + encoded_message = encode(ldap_message) + if self.connection.sasl_mechanism == DIGEST_MD5 and self.connection._digest_md5_kic and not self.connection.sasl_in_progress: + # If we are using DIGEST-MD5 and LDAP signing is enabled: add a signature to the message + sec_num = self.connection._digest_md5_sec_num # added underscore GC + kic = self.connection._digest_md5_kic # lowercase GC + + # RFC 2831 : encoded_message = sizeOf(encored_message + signature + 0x0001 + secNum) + encoded_message + signature + 0x0001 + secNum + signature = bytes.fromhex(md5_hmac(kic, int(sec_num).to_bytes(4, 'big') + encoded_message)[0:20]) + encoded_message = int(len(encoded_message) + 4 + 2 + 10).to_bytes(4, 'big') + encoded_message + signature + int(1).to_bytes(2, 'big') + int(sec_num).to_bytes(4, 'big') + self.connection._digest_md5_sec_num += 1 + + self.connection.socket.sendall(encoded_message) + if log_enabled(EXTENDED): + log(EXTENDED, 'ldap message sent via <%s>:%s', self.connection, format_ldap_message(ldap_message, '>>')) + if log_enabled(NETWORK): + log(NETWORK, 'sent %d bytes via <%s>', len(encoded_message), self.connection) + except socket.error as e: + self.connection.last_error = 'socket sending error' + str(e) + encoded_message = None + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise communication_exception_factory(LDAPSocketSendError, exc)(self.connection.last_error) + raise communication_exception_factory(LDAPSocketSendError, type(e)(str(e)))(self.connection.last_error) + if self.connection.usage: + self.connection._usage.update_transmitted_message(self.connection.request, len(encoded_message)) + + def _start_listen(self): + # overridden on strategy class + raise NotImplementedError + + def _get_response(self, message_id, timeout): + # overridden in strategy class + raise NotImplementedError + + def receiving(self): + # overridden in strategy class + raise NotImplementedError + + def post_send_single_response(self, message_id): + # overridden in strategy class + raise NotImplementedError + + def post_send_search(self, message_id): + # overridden in strategy class + raise NotImplementedError + + def get_stream(self): + raise NotImplementedError + + def set_stream(self, value): + raise NotImplementedError + + def unbind_referral_cache(self): + while len(self.referral_cache) > 0: + cachekey, referral_connection = self.referral_cache.popitem() + referral_connection.unbind() diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/ldifProducer.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/ldifProducer.py new file mode 100644 index 00000000..a39c4d73 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/ldifProducer.py @@ -0,0 +1,152 @@ +""" +""" + +# Created on 2013.07.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 . + +from io import StringIO +from os import linesep +import random + +from ..core.exceptions import LDAPLDIFError +from ..utils.conv import prepare_for_stream +from ..protocol.rfc4511 import LDAPMessage, MessageID, ProtocolOp, LDAP_MAX_INT +from ..protocol.rfc2849 import operation_to_ldif, add_ldif_header +from ..protocol.convert import build_controls_list +from .base import BaseStrategy + + +class LdifProducerStrategy(BaseStrategy): + """ + This strategy is used to create the LDIF stream for the Add, Delete, Modify, ModifyDn operations. + You send the request and get the request in the ldif-change representation of the operation. + NO OPERATION IS SENT TO THE LDAP SERVER! + Connection.request will contain the result LDAP message in a dict form + Connection.response will contain the ldif-change format of the requested operation if available + You don't need a real server to connect to for this strategy + """ + + def __init__(self, ldap_connection): + BaseStrategy.__init__(self, ldap_connection) + self.sync = True + self.no_real_dsa = True + self.pooled = False + self.can_stream = True + self.line_separator = linesep + self.all_base64 = False + self.stream = None + self.order = dict() + self._header_added = False + random.seed() + + def _open_socket(self, address, use_ssl=False, unix_socket=False): # fake open socket + self.connection.socket = NotImplemented # placeholder for a dummy socket + if self.connection.usage: + self.connection._usage.open_sockets += 1 + + self.connection.closed = False + + def _close_socket(self): + if self.connection.usage: + self.connection._usage.closed_sockets += 1 + + self.connection.socket = None + self.connection.closed = True + + def _start_listen(self): + self.connection.listening = True + self.connection.closed = False + self.connection.bound = True + self._header_added = False + if not self.stream or (isinstance(self.stream, StringIO) and self.stream.closed): + self.set_stream(StringIO()) + + def _stop_listen(self): + self.stream.close() + self.connection.listening = False + self.connection.bound = False + self.connection.closed = True + + def receiving(self): + return None + + def send(self, message_type, request, controls=None): + """ + Build the LDAPMessage without sending to server + """ + message_id = random.randint(0, LDAP_MAX_INT) + ldap_message = LDAPMessage() + ldap_message['messageID'] = MessageID(message_id) + ldap_message['protocolOp'] = ProtocolOp().setComponentByName(message_type, request) + message_controls = build_controls_list(controls) + if message_controls is not None: + ldap_message['controls'] = message_controls + + self.connection.request = BaseStrategy.decode_request(message_type, request, controls) + self.connection.request['controls'] = controls + if self._outstanding is None: + self._outstanding = dict() + self._outstanding[message_id] = self.connection.request + return message_id + + def post_send_single_response(self, message_id): + self.connection.response = None + self.connection.result = None + if self._outstanding and message_id in self._outstanding: + request = self._outstanding.pop(message_id) + ldif_lines = operation_to_ldif(self.connection.request['type'], request, self.all_base64, self.order.get(self.connection.request['type'])) + if self.stream and ldif_lines and not self.connection.closed: + self.accumulate_stream(self.line_separator.join(ldif_lines)) + ldif_lines = add_ldif_header(ldif_lines) + self.connection.response = self.line_separator.join(ldif_lines) + return self.connection.response + + return None + + def post_send_search(self, message_id): + raise LDAPLDIFError('LDIF-CONTENT cannot be produced for Search operations') + + def _get_response(self, message_id, timeout): + pass + + def accumulate_stream(self, fragment): + if not self._header_added and self.stream.tell() == 0: + self._header_added = True + header = add_ldif_header(['-'])[0] + self.stream.write(prepare_for_stream(header + self.line_separator + self.line_separator)) + self.stream.write(prepare_for_stream(fragment + self.line_separator + self.line_separator)) + + def get_stream(self): + return self.stream + + def set_stream(self, value): + error = False + try: + if not value.writable(): + error = True + except (ValueError, AttributeError): + error = True + + if error: + raise LDAPLDIFError('stream must be writable') + + self.stream = value diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/mockAsync.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockAsync.py new file mode 100644 index 00000000..5633ff5f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockAsync.py @@ -0,0 +1,200 @@ +""" +""" + +# Created on 2016.04.30 +# +# 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 . + +from .. import ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES +from .mockBase import MockBaseStrategy +from .asynchronous import AsyncStrategy +from ..operation.search import search_result_done_response_to_dict, search_result_entry_response_to_dict +from ..core.results import DO_NOT_RAISE_EXCEPTIONS +from ..utils.log import log, log_enabled, ERROR, PROTOCOL +from ..core.exceptions import LDAPResponseTimeoutError, LDAPOperationResult +from ..operation.bind import bind_response_to_dict +from ..operation.delete import delete_response_to_dict +from ..operation.add import add_response_to_dict +from ..operation.compare import compare_response_to_dict +from ..operation.modifyDn import modify_dn_response_to_dict +from ..operation.modify import modify_response_to_dict +from ..operation.search import search_result_done_response_to_dict, search_result_entry_response_to_dict +from ..operation.extended import extended_response_to_dict + +# LDAPResult ::= SEQUENCE { +# resultCode ENUMERATED { +# success (0), +# operationsError (1), +# protocolError (2), +# timeLimitExceeded (3), +# sizeLimitExceeded (4), +# compareFalse (5), +# compareTrue (6), +# authMethodNotSupported (7), +# strongerAuthRequired (8), +# -- 9 reserved -- +# referral (10), +# adminLimitExceeded (11), +# unavailableCriticalExtension (12), +# confidentialityRequired (13), +# saslBindInProgress (14), +# noSuchAttribute (16), +# undefinedAttributeType (17), +# inappropriateMatching (18), +# constraintViolation (19), +# attributeOrValueExists (20), +# invalidAttributeSyntax (21), +# -- 22-31 unused -- +# noSuchObject (32), +# aliasProblem (33), +# invalidDNSyntax (34), +# -- 35 reserved for undefined isLeaf -- +# aliasDereferencingProblem (36), +# -- 37-47 unused -- +# inappropriateAuthentication (48), +# invalidCredentials (49), +# insufficientAccessRights (50), +# busy (51), +# unavailable (52), +# unwillingToPerform (53), +# loopDetect (54), +# -- 55-63 unused -- +# namingViolation (64), +# objectClassViolation (65), +# notAllowedOnNonLeaf (66), +# notAllowedOnRDN (67), +# entryAlreadyExists (68), +# objectClassModsProhibited (69), +# -- 70 reserved for CLDAP -- +# affectsMultipleDSAs (71), +# -- 72-79 unused -- +# other (80), +# ... }, +# matchedDN LDAPDN, +# diagnosticMessage LDAPString, +# referral [3] Referral OPTIONAL } + + +class MockAsyncStrategy(MockBaseStrategy, AsyncStrategy): # class inheritance sequence is important, MockBaseStrategy must be the first one + """ + This strategy create a mock LDAP server, with asynchronous access + It can be useful to test LDAP without accessing a real Server + """ + def __init__(self, ldap_connection): + AsyncStrategy.__init__(self, ldap_connection) + MockBaseStrategy.__init__(self) + #outstanding = dict() # a dictionary with the message id as key and a tuple (result, response) as value + + def post_send_search(self, payload): + message_id, message_type, request, controls = payload + async_response = [] + async_result = dict() + if message_type == 'searchRequest': + responses, result = self.mock_search(request, controls) + result['type'] = 'searchResDone' + for entry in responses: + response = search_result_entry_response_to_dict(entry, self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names) + response['type'] = 'searchResEntry' + + if self.connection.empty_attributes: + for attribute_type in request['attributes']: + attribute_name = str(attribute_type) + if attribute_name not in response['raw_attributes'] and attribute_name not in (ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES): + response['raw_attributes'][attribute_name] = list() + response['attributes'][attribute_name] = list() + if log_enabled(PROTOCOL): + log(PROTOCOL, 'attribute set to empty list for missing attribute <%s> in <%s>', + attribute_type, self) + if not self.connection.auto_range: + attrs_to_remove = [] + # removes original empty attribute in case a range tag is returned + for attribute_type in response['attributes']: + attribute_name = str(attribute_type) + if ';range' in attribute_name.lower(): + orig_attr, _, _ = attribute_name.partition(';') + attrs_to_remove.append(orig_attr) + for attribute_type in attrs_to_remove: + if log_enabled(PROTOCOL): + log(PROTOCOL, + 'attribute type <%s> removed in response because of same attribute returned as range by the server in <%s>', + attribute_type, self) + del response['raw_attributes'][attribute_type] + del response['attributes'][attribute_type] + + async_response.append(response) + async_result = search_result_done_response_to_dict(result) + async_result['type'] = 'searchResDone' + self._responses[message_id] = (request, async_result, async_response) + return message_id + + def post_send_single_response(self, payload): # payload is a tuple sent by self.send() made of message_type, request, controls + message_id, message_type, request, controls = payload + responses = [] + result = None + if message_type == 'bindRequest': + result = bind_response_to_dict(self.mock_bind(request, controls)) + result['type'] = 'bindResponse' + elif message_type == 'unbindRequest': + self.bound = None + elif message_type == 'abandonRequest': + pass + elif message_type == 'delRequest': + result = delete_response_to_dict(self.mock_delete(request, controls)) + result['type'] = 'delResponse' + elif message_type == 'addRequest': + result = add_response_to_dict(self.mock_add(request, controls)) + result['type'] = 'addResponse' + elif message_type == 'compareRequest': + result = compare_response_to_dict(self.mock_compare(request, controls)) + result['type'] = 'compareResponse' + elif message_type == 'modDNRequest': + result = modify_dn_response_to_dict(self.mock_modify_dn(request, controls)) + result['type'] = 'modDNResponse' + elif message_type == 'modifyRequest': + result = modify_response_to_dict(self.mock_modify(request, controls)) + result['type'] = 'modifyResponse' + elif message_type == 'extendedReq': + result = extended_response_to_dict(self.mock_extended(request, controls)) + result['type'] = 'extendedResp' + responses.append(result) + if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + self._responses[message_id] = (request, result, responses) + return message_id + + + def get_response(self, message_id, timeout=None, get_request=False): + if message_id in self._responses: + request, result, response = self._responses.pop(message_id) + else: + raise(LDAPResponseTimeoutError('message id not in outstanding queue')) + + if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + if get_request: + return response, result, request + else: + return response, result diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/mockBase.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockBase.py new file mode 100644 index 00000000..be5b0bec --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockBase.py @@ -0,0 +1,921 @@ +""" +""" + +# Created on 2016.04.30 +# +# 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 . + +import json +import re + +from random import SystemRandom + +from pyasn1.type.univ import OctetString + +from .. import SEQUENCE_TYPES, ALL_ATTRIBUTES +from ..operation.bind import bind_request_to_dict +from ..operation.delete import delete_request_to_dict +from ..operation.add import add_request_to_dict +from ..operation.compare import compare_request_to_dict +from ..operation.modifyDn import modify_dn_request_to_dict +from ..operation.modify import modify_request_to_dict +from ..operation.extended import extended_request_to_dict +from ..operation.search import search_request_to_dict, parse_filter, ROOT, AND, OR, NOT, MATCH_APPROX, \ + MATCH_GREATER_OR_EQUAL, MATCH_LESS_OR_EQUAL, MATCH_EXTENSIBLE, MATCH_PRESENT,\ + MATCH_SUBSTRING, MATCH_EQUAL +from ..utils.conv import json_hook, to_unicode, to_raw +from ..core.exceptions import LDAPDefinitionError, LDAPPasswordIsMandatoryError, LDAPInvalidValueError, LDAPSocketOpenError +from ..core.results import RESULT_SUCCESS, RESULT_OPERATIONS_ERROR, RESULT_UNAVAILABLE_CRITICAL_EXTENSION, \ + RESULT_INVALID_CREDENTIALS, RESULT_NO_SUCH_OBJECT, RESULT_ENTRY_ALREADY_EXISTS, RESULT_COMPARE_TRUE, \ + RESULT_COMPARE_FALSE, RESULT_NO_SUCH_ATTRIBUTE, RESULT_UNWILLING_TO_PERFORM, RESULT_PROTOCOL_ERROR, RESULT_CONSTRAINT_VIOLATION, RESULT_NOT_ALLOWED_ON_RDN +from ..utils.ciDict import CaseInsensitiveDict +from ..utils.dn import to_dn, safe_dn, safe_rdn +from ..protocol.sasl.sasl import validate_simple_password +from ..protocol.formatters.standard import find_attribute_validator, format_attribute_values +from ..protocol.rfc2696 import paged_search_control +from ..utils.log import log, log_enabled, ERROR, BASIC +from ..utils.asn1 import encode +from ..utils.conv import ldap_escape_to_bytes +from ..strategy.base import BaseStrategy # needed for decode_control() method +from ..protocol.rfc4511 import LDAPMessage, ProtocolOp, MessageID +from ..protocol.convert import build_controls_list + + +# LDAPResult ::= SEQUENCE { +# resultCode ENUMERATED { +# success (0), +# operationsError (1), +# protocolError (2), +# timeLimitExceeded (3), +# sizeLimitExceeded (4), +# compareFalse (5), +# compareTrue (6), +# authMethodNotSupported (7), +# strongerAuthRequired (8), +# -- 9 reserved -- +# referral (10), +# adminLimitExceeded (11), +# unavailableCriticalExtension (12), +# confidentialityRequired (13), +# saslBindInProgress (14), +# noSuchAttribute (16), +# undefinedAttributeType (17), +# inappropriateMatching (18), +# constraintViolation (19), +# attributeOrValueExists (20), +# invalidAttributeSyntax (21), +# -- 22-31 unused -- +# noSuchObject (32), +# aliasProblem (33), +# invalidDNSyntax (34), +# -- 35 reserved for undefined isLeaf -- +# aliasDereferencingProblem (36), +# -- 37-47 unused -- +# inappropriateAuthentication (48), +# invalidCredentials (49), +# insufficientAccessRights (50), +# busy (51), +# unavailable (52), +# unwillingToPerform (53), +# loopDetect (54), +# -- 55-63 unused -- +# namingViolation (64), +# objectClassViolation (65), +# notAllowedOnNonLeaf (66), +# notAllowedOnRDN (67), +# entryAlreadyExists (68), +# objectClassModsProhibited (69), +# -- 70 reserved for CLDAP -- +# affectsMultipleDSAs (71), +# -- 72-79 unused -- +# other (80), +# ... }, +# matchedDN LDAPDN, +# diagnosticMessage LDAPString, +# referral [3] Referral OPTIONAL } + +# noinspection PyProtectedMember,PyUnresolvedReferences + +SEARCH_CONTROLS = ['1.2.840.113556.1.4.319' # simple paged search [RFC 2696] + ] +SERVER_ENCODING = 'utf-8' + + +def random_cookie(): + return to_raw(SystemRandom().random())[-6:] + + +class PagedSearchSet(object): + def __init__(self, response, size, criticality): + self.size = size + self.response = response + self.cookie = None + self.sent = 0 + self.done = False + + def next(self, size=None): + if size: + self.size=size + + message = '' + response = self.response[self.sent: self.sent + self.size] + self.sent += self.size + if self.sent > len(self.response): + self.done = True + self.cookie = '' + else: + self.cookie = random_cookie() + + response_control = paged_search_control(False, len(self.response), self.cookie) + result = {'resultCode': RESULT_SUCCESS, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None, + 'controls': [BaseStrategy.decode_control(response_control)] + } + return response, result + + +class MockBaseStrategy(object): + """ + Base class for connection strategy + """ + + def __init__(self): + if not hasattr(self.connection.server, 'dit'): # create entries dict if not already present + self.connection.server.dit = CaseInsensitiveDict() + self.entries = self.connection.server.dit # for simpler reference + self.no_real_dsa = True + self.bound = None + self.custom_validators = None + self.operational_attributes = ['entryDN'] + self.add_entry('cn=schema', [], validate=False) # add default entry for schema + self._paged_sets = [] # list of paged search in progress + if log_enabled(BASIC): + log(BASIC, 'instantiated <%s>: <%s>', self.__class__.__name__, self) + + def _start_listen(self): + self.connection.listening = True + self.connection.closed = False + if self.connection.usage: + self.connection._usage.open_sockets += 1 + + def _stop_listen(self): + self.connection.listening = False + self.connection.closed = True + if self.connection.usage: + self.connection._usage.closed_sockets += 1 + + def _prepare_value(self, attribute_type, value, validate=True): + """ + Prepare a value for being stored in the mock DIT + :param value: object to store + :return: raw value to store in the DIT + """ + if validate: # if loading from json dump do not validate values: + validator = find_attribute_validator(self.connection.server.schema, attribute_type, self.custom_validators) + validated = validator(value) + if validated is False: + raise LDAPInvalidValueError('value non valid for attribute \'%s\'' % attribute_type) + elif validated is not True: # a valid LDAP value equivalent to the actual value + value = validated + raw_value = to_raw(value) + if not isinstance(raw_value, bytes): + raise LDAPInvalidValueError('The value "%s" of type %s for "%s" must be bytes or an offline schema needs to be provided when Mock strategy is used.' % ( + value, + type(value), + attribute_type, + )) + return raw_value + + def _update_attribute(self, dn, attribute_type, value): + pass + + def add_entry(self, dn, attributes, validate=True): + with self.connection.server.dit_lock: + escaped_dn = safe_dn(dn) + if escaped_dn not in self.connection.server.dit: + new_entry = CaseInsensitiveDict() + for attribute in attributes: + if attribute in self.operational_attributes: # no restore of operational attributes, should be computed at runtime + continue + if not isinstance(attributes[attribute], SEQUENCE_TYPES): # entry attributes are always lists of bytes values + attributes[attribute] = [attributes[attribute]] + if self.connection.server.schema and self.connection.server.schema.attribute_types[attribute].single_value and len(attributes[attribute]) > 1: # multiple values in single-valued attribute + return False + if attribute.lower() == 'objectclass' and self.connection.server.schema: # builds the objectClass hierarchy only if schema is present + class_set = set() + for object_class in attributes[attribute]: + if self.connection.server.schema.object_classes and object_class not in self.connection.server.schema.object_classes: + return False + # walkups the class hierarchy and buils a set of all classes in it + class_set.add(object_class) + class_set_size = 0 + while class_set_size != len(class_set): + new_classes = set() + class_set_size = len(class_set) + for class_name in class_set: + if self.connection.server.schema.object_classes[class_name].superior: + new_classes.update(self.connection.server.schema.object_classes[class_name].superior) + class_set.update(new_classes) + new_entry['objectClass'] = [to_raw(value) for value in class_set] + else: + new_entry[attribute] = [self._prepare_value(attribute, value, validate) for value in attributes[attribute]] + for rdn in safe_rdn(escaped_dn, decompose=True): # adds rdns to entry attributes + if rdn[0] not in new_entry: # if rdn attribute is missing adds attribute and its value + new_entry[rdn[0]] = [to_raw(rdn[1])] + else: + raw_rdn = to_raw(rdn[1]) + if raw_rdn not in new_entry[rdn[0]]: # add rdn value if rdn attribute is present but value is missing + new_entry[rdn[0]].append(raw_rdn) + new_entry['entryDN'] = [to_raw(escaped_dn)] + self.connection.server.dit[escaped_dn] = new_entry + return True + return False + + def remove_entry(self, dn): + with self.connection.server.dit_lock: + escaped_dn = safe_dn(dn) + if escaped_dn in self.connection.server.dit: + del self.connection.server.dit[escaped_dn] + return True + return False + + def entries_from_json(self, json_entry_file): + target = open(json_entry_file, 'r') + definition = json.load(target, object_hook=json_hook) + if 'entries' not in definition: + self.connection.last_error = 'invalid JSON definition, missing "entries" section' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPDefinitionError(self.connection.last_error) + if not self.connection.server.dit: + self.connection.server.dit = CaseInsensitiveDict() + for entry in definition['entries']: + if 'raw' not in entry: + self.connection.last_error = 'invalid JSON definition, missing "raw" section' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPDefinitionError(self.connection.last_error) + if 'dn' not in entry: + self.connection.last_error = 'invalid JSON definition, missing "dn" section' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPDefinitionError(self.connection.last_error) + self.add_entry(entry['dn'], entry['raw'], validate=False) + target.close() + + def mock_bind(self, request_message, controls): + # BindRequest ::= [APPLICATION 0] SEQUENCE { + # version INTEGER (1 .. 127), + # name LDAPDN, + # authentication AuthenticationChoice } + # + # BindResponse ::= [APPLICATION 1] SEQUENCE { + # COMPONENTS OF LDAPResult, + # serverSaslCreds [7] OCTET STRING OPTIONAL } + # + # request: version, name, authentication + # response: LDAPResult + serverSaslCreds + request = bind_request_to_dict(request_message) + identity = request['name'] + if 'simple' in request['authentication']: + try: + password = validate_simple_password(request['authentication']['simple']) + except LDAPPasswordIsMandatoryError: + password = '' + identity = '' + else: + self.connection.last_error = 'only Simple Bind allowed in Mock strategy' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPDefinitionError(self.connection.last_error) + # checks userPassword for password. userPassword must be a text string or a list of text strings + if identity in self.connection.server.dit: + if 'userPassword' in self.connection.server.dit[identity]: + # if self.connection.server.dit[identity]['userPassword'] == password or password in self.connection.server.dit[identity]['userPassword']: + if self.equal(identity, 'userPassword', password): + result_code = RESULT_SUCCESS + message = '' + self.bound = identity + else: + result_code = RESULT_INVALID_CREDENTIALS + message = 'invalid credentials' + else: # no user found, returns invalidCredentials + result_code = RESULT_INVALID_CREDENTIALS + message = 'missing userPassword attribute' + elif identity == '': + result_code = RESULT_SUCCESS + message = '' + self.bound = identity + else: + result_code = RESULT_INVALID_CREDENTIALS + message = 'missing object' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None, + 'serverSaslCreds': None + } + + def mock_delete(self, request_message, controls): + # DelRequest ::= [APPLICATION 10] LDAPDN + # + # DelResponse ::= [APPLICATION 11] LDAPResult + # + # request: entry + # response: LDAPResult + request = delete_request_to_dict(request_message) + dn = safe_dn(request['entry']) + if dn in self.connection.server.dit: + del self.connection.server.dit[dn] + result_code = RESULT_SUCCESS + message = '' + else: + result_code = RESULT_NO_SUCH_OBJECT + message = 'object not found' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + def mock_add(self, request_message, controls): + # AddRequest ::= [APPLICATION 8] SEQUENCE { + # entry LDAPDN, + # attributes AttributeList } + # + # AddResponse ::= [APPLICATION 9] LDAPResult + # + # request: entry, attributes + # response: LDAPResult + request = add_request_to_dict(request_message) + dn = safe_dn(request['entry']) + attributes = request['attributes'] + # converts attributes values to bytes + + if dn not in self.connection.server.dit: + if self.add_entry(dn, attributes): + result_code = RESULT_SUCCESS + message = '' + else: + result_code = RESULT_OPERATIONS_ERROR + message = 'error adding entry' + else: + result_code = RESULT_ENTRY_ALREADY_EXISTS + message = 'entry already exist' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + def mock_compare(self, request_message, controls): + # CompareRequest ::= [APPLICATION 14] SEQUENCE { + # entry LDAPDN, + # ava AttributeValueAssertion } + # + # CompareResponse ::= [APPLICATION 15] LDAPResult + # + # request: entry, attribute, value + # response: LDAPResult + request = compare_request_to_dict(request_message) + dn = safe_dn(request['entry']) + attribute = request['attribute'] + value = to_raw(request['value']) + if dn in self.connection.server.dit: + if attribute in self.connection.server.dit[dn]: + if self.equal(dn, attribute, value): + result_code = RESULT_COMPARE_TRUE + message = '' + else: + result_code = RESULT_COMPARE_FALSE + message = '' + else: + result_code = RESULT_NO_SUCH_ATTRIBUTE + message = 'attribute not found' + else: + result_code = RESULT_NO_SUCH_OBJECT + message = 'object not found' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + def mock_modify_dn(self, request_message, controls): + # ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { + # entry LDAPDN, + # newrdn RelativeLDAPDN, + # deleteoldrdn BOOLEAN, + # newSuperior [0] LDAPDN OPTIONAL } + # + # ModifyDNResponse ::= [APPLICATION 13] LDAPResult + # + # request: entry, newRdn, deleteOldRdn, newSuperior + # response: LDAPResult + request = modify_dn_request_to_dict(request_message) + dn = safe_dn(request['entry']) + new_rdn = request['newRdn'] + delete_old_rdn = request['deleteOldRdn'] + new_superior = safe_dn(request['newSuperior']) if request['newSuperior'] else '' + dn_components = to_dn(dn) + if dn in self.connection.server.dit: + if new_superior and new_rdn: # performs move in the DIT + new_dn = safe_dn(dn_components[0] + ',' + new_superior) + self.connection.server.dit[new_dn] = self.connection.server.dit[dn].copy() + moved_entry = self.connection.server.dit[new_dn] + if delete_old_rdn: + del self.connection.server.dit[dn] + result_code = RESULT_SUCCESS + message = 'entry moved' + moved_entry['entryDN'] = [to_raw(new_dn)] + elif new_rdn and not new_superior: # performs rename + new_dn = safe_dn(new_rdn + ',' + safe_dn(dn_components[1:])) + self.connection.server.dit[new_dn] = self.connection.server.dit[dn].copy() + renamed_entry = self.connection.server.dit[new_dn] + del self.connection.server.dit[dn] + renamed_entry['entryDN'] = [to_raw(new_dn)] + + for rdn in safe_rdn(new_dn, decompose=True): # adds rdns to entry attributes + renamed_entry[rdn[0]] = [to_raw(rdn[1])] + + result_code = RESULT_SUCCESS + message = 'entry rdn renamed' + else: + result_code = RESULT_UNWILLING_TO_PERFORM + message = 'newRdn or newSuperior missing' + else: + result_code = RESULT_NO_SUCH_OBJECT + message = 'object not found' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + def mock_modify(self, request_message, controls): + # ModifyRequest ::= [APPLICATION 6] SEQUENCE { + # object LDAPDN, + # changes SEQUENCE OF change SEQUENCE { + # operation ENUMERATED { + # add (0), + # delete (1), + # replace (2), + # ... }, + # modification PartialAttribute } } + # + # ModifyResponse ::= [APPLICATION 7] LDAPResult + # + # request: entry, changes + # response: LDAPResult + # + # changes is a dictionary in the form {'attribute': [(operation, [val1, ...]), ...], ...} + # operation is 0 (add), 1 (delete), 2 (replace), 3 (increment) + request = modify_request_to_dict(request_message) + dn = safe_dn(request['entry']) + changes = request['changes'] + result_code = 0 + message = '' + rdns = [rdn[0] for rdn in safe_rdn(dn, decompose=True)] + if dn in self.connection.server.dit: + entry = self.connection.server.dit[dn] + original_entry = entry.copy() # to preserve atomicity of operation + for modification in changes: + operation = modification['operation'] + attribute = modification['attribute']['type'] + elements = modification['attribute']['value'] + if operation == 0: # add + if attribute not in entry and elements: # attribute not present, creates the new attribute and add elements + if self.connection.server.schema and self.connection.server.schema.attribute_types and self.connection.server.schema.attribute_types[attribute].single_value and len(elements) > 1: # multiple values in single-valued attribute + result_code = RESULT_CONSTRAINT_VIOLATION + message = 'attribute is single-valued' + else: + entry[attribute] = [to_raw(element) for element in elements] + else: # attribute present, adds elements to current values + if self.connection.server.schema and self.connection.server.schema.attribute_types and self.connection.server.schema.attribute_types[attribute].single_value: # multiple values in single-valued attribute + result_code = RESULT_CONSTRAINT_VIOLATION + message = 'attribute is single-valued' + else: + entry[attribute].extend([to_raw(element) for element in elements]) + elif operation == 1: # delete + if attribute not in entry: # attribute must exist + result_code = RESULT_NO_SUCH_ATTRIBUTE + message = 'attribute must exists for deleting its values' + elif attribute in rdns: # attribute can't be used in dn + result_code = RESULT_NOT_ALLOWED_ON_RDN + message = 'cannot delete an rdn' + else: + if not elements: # deletes whole attribute if element list is empty + del entry[attribute] + else: + for element in elements: + raw_element = to_raw(element) + if self.equal(dn, attribute, raw_element): # removes single element + entry[attribute].remove(raw_element) + else: + result_code = 1 + message = 'value to delete not found' + if not entry[attribute]: # removes the whole attribute if no elements remained + del entry[attribute] + elif operation == 2: # replace + if attribute not in entry and elements: # attribute not present, creates the new attribute and add elements + if self.connection.server.schema and self.connection.server.schema.attribute_types and self.connection.server.schema.attribute_types[attribute].single_value and len(elements) > 1: # multiple values in single-valued attribute + result_code = RESULT_CONSTRAINT_VIOLATION + message = 'attribute is single-valued' + else: + entry[attribute] = [to_raw(element) for element in elements] + elif not elements and attribute in rdns: # attribute can't be used in dn + result_code = RESULT_NOT_ALLOWED_ON_RDN + message = 'cannot replace an rdn' + elif not elements: # deletes whole attribute if element list is empty + if attribute in entry: + del entry[attribute] + else: # substitutes elements + entry[attribute] = [to_raw(element) for element in elements] + elif operation == 3: # increment + if attribute not in entry: # attribute must exist + result_code = RESULT_NO_SUCH_ATTRIBUTE + message = 'attribute must exists for incrementing its values' + else: + if len(elements) != 1: + result_code = RESULT_PROTOCOL_ERROR + message = 'only one increment value is allowed' + else: + try: + entry[attribute] = [bytes(str(int(value) + int(elements[0])), encoding='utf-8') for value in entry[attribute]] + except: + result_code = RESULT_UNWILLING_TO_PERFORM + message = 'unable to increment value' + + if result_code: # an error has happened, restores the original dn + self.connection.server.dit[dn] = original_entry + else: + result_code = RESULT_NO_SUCH_OBJECT + message = 'object not found' + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + def mock_search(self, request_message, controls): + # SearchRequest ::= [APPLICATION 3] SEQUENCE { + # baseObject LDAPDN, + # scope ENUMERATED { + # baseObject (0), + # singleLevel (1), + # wholeSubtree (2), + # ... }, + # derefAliases ENUMERATED { + # neverDerefAliases (0), + # derefInSearching (1), + # derefFindingBaseObj (2), + # derefAlways (3) }, + # sizeLimit INTEGER (0 .. maxInt), + # timeLimit INTEGER (0 .. maxInt), + # typesOnly BOOLEAN, + # filter Filter, + # attributes AttributeSelection } + # + # SearchResultEntry ::= [APPLICATION 4] SEQUENCE { + # objectName LDAPDN, + # attributes PartialAttributeList } + # + # + # SearchResultReference ::= [APPLICATION 19] SEQUENCE + # SIZE (1..MAX) OF uri URI + # + # SearchResultDone ::= [APPLICATION 5] LDAPResult + # + # request: base, scope, dereferenceAlias, sizeLimit, timeLimit, typesOnly, filter, attributes + # response_entry: object, attributes + # response_done: LDAPResult + request = search_request_to_dict(request_message) + if controls: + decoded_controls = [self.decode_control(control) for control in controls if control] + for decoded_control in decoded_controls: + if decoded_control[1]['criticality'] and decoded_control[0] not in SEARCH_CONTROLS: + message = 'Critical requested control ' + str(decoded_control[0]) + ' not available' + result = {'resultCode': RESULT_UNAVAILABLE_CRITICAL_EXTENSION, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + return [], result + elif decoded_control[0] == '1.2.840.113556.1.4.319': # Simple paged search + if not decoded_control[1]['value']['cookie']: # new paged search + response, result = self._execute_search(request) + if result['resultCode'] == RESULT_SUCCESS: # success + paged_set = PagedSearchSet(response, int(decoded_control[1]['value']['size']), decoded_control[1]['criticality']) + response, result = paged_set.next() + if paged_set.done: # paged search already completed, no need to store the set + del paged_set + else: + self._paged_sets.append(paged_set) + return response, result + else: + return [], result + else: + for paged_set in self._paged_sets: + if paged_set.cookie == decoded_control[1]['value']['cookie']: # existing paged set + response, result = paged_set.next() # returns next bunch of entries as per paged set specifications + if paged_set.done: + self._paged_sets.remove(paged_set) + return response, result + # paged set not found + message = 'Invalid cookie in simple paged search' + result = {'resultCode': RESULT_OPERATIONS_ERROR, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + return [], result + + else: + return self._execute_search(request) + + def _execute_search(self, request): + responses = [] + base = safe_dn(request['base']) + scope = request['scope'] + attributes = request['attributes'] + if '+' in attributes: # operational attributes requested + attributes.extend(self.operational_attributes) + attributes.remove('+') + + attributes = [attr.lower() for attr in request['attributes']] + + filter_root = parse_filter(request['filter'], self.connection.server.schema, auto_escape=True, auto_encode=False, validator=self.connection.server.custom_validator, check_names=self.connection.check_names) + candidates = [] + if scope == 0: # base object + if base in self.connection.server.dit or base.lower() == 'cn=schema': + candidates.append(base) + elif scope == 1: # single level + for entry in self.connection.server.dit: + if entry.lower().endswith(base.lower()) and ',' not in entry[:-len(base) - 1]: # only leafs without commas in the remaining dn + candidates.append(entry) + elif scope == 2: # whole subtree + for entry in self.connection.server.dit: + if entry.lower().endswith(base.lower()): + candidates.append(entry) + + if not candidates: # incorrect base + result_code = RESULT_NO_SUCH_OBJECT + message = 'incorrect base object' + else: + matched = self.evaluate_filter_node(filter_root, candidates) + if self.connection.raise_exceptions and 0 < request['sizeLimit'] < len(matched): + result_code = 4 + message = 'size limit exceeded' + else: + for match in matched: + responses.append({ + 'object': match, + 'attributes': [{'type': attribute, + 'vals': [] if request['typesOnly'] else self.connection.server.dit[match][attribute]} + for attribute in self.connection.server.dit[match] + if attribute.lower() in attributes or ALL_ATTRIBUTES in attributes] + }) + if '+' not in attributes: # remove operational attributes + for op_attr in self.operational_attributes: + if op_attr.lower() in attributes: + # if the op_attr was explicitly requested, then keep it + continue + for i, attr in enumerate(responses[len(responses)-1]['attributes']): + if attr['type'] == op_attr: + del responses[len(responses)-1]['attributes'][i] + result_code = 0 + message = '' + + result = {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None + } + + return responses[:request['sizeLimit']] if request['sizeLimit'] > 0 else responses, result + + def mock_extended(self, request_message, controls): + # ExtendedRequest ::= [APPLICATION 23] SEQUENCE { + # requestName [0] LDAPOID, + # requestValue [1] OCTET STRING OPTIONAL } + # + # ExtendedResponse ::= [APPLICATION 24] SEQUENCE { + # COMPONENTS OF LDAPResult, + # responseName [10] LDAPOID OPTIONAL, + # responseValue [11] OCTET STRING OPTIONAL } + # + # IntermediateResponse ::= [APPLICATION 25] SEQUENCE { + # responseName [0] LDAPOID OPTIONAL, + # responseValue [1] OCTET STRING OPTIONAL } + request = extended_request_to_dict(request_message) + + result_code = RESULT_UNWILLING_TO_PERFORM + message = 'not implemented' + response_name = None + response_value = None + if self.connection.server.info: + for extension in self.connection.server.info.supported_extensions: + if request['name'] == extension[0]: # server can answer the extended request + if extension[0] == '2.16.840.1.113719.1.27.100.31': # getBindDNRequest [NOVELL] + result_code = 0 + message = '' + response_name = OctetString('2.16.840.1.113719.1.27.100.32') # getBindDNResponse [NOVELL] + response_value = OctetString(self.bound) + elif extension[0] == '1.3.6.1.4.1.4203.1.11.3': # WhoAmI [RFC4532] + result_code = 0 + message = '' + response_name = OctetString('1.3.6.1.4.1.4203.1.11.3') # WhoAmI [RFC4532] + response_value = OctetString(self.bound) + break + + return {'resultCode': result_code, + 'matchedDN': '', + 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), + 'referral': None, + 'responseName': response_name, + 'responseValue': response_value + } + + def evaluate_filter_node(self, node, candidates): + """After evaluation each 2 sets are added to each MATCH node, one for the matched object and one for unmatched object. + The unmatched object set is needed if a superior node is a NOT that reverts the evaluation. The BOOLEAN nodes mix the sets + returned by the MATCH nodes""" + node.matched = set() + node.unmatched = set() + + if node.elements: + for element in node.elements: + self.evaluate_filter_node(element, candidates) + + if node.tag == ROOT: + return node.elements[0].matched + elif node.tag == AND: + first_element = node.elements[0] + node.matched.update(first_element.matched) + node.unmatched.update(first_element.unmatched) + + for element in node.elements[1:]: + node.matched.intersection_update(element.matched) + node.unmatched.intersection_update(element.unmatched) + elif node.tag == OR: + for element in node.elements: + node.matched.update(element.matched) + node.unmatched.update(element.unmatched) + elif node.tag == NOT: + node.matched = node.elements[0].unmatched + node.unmatched = node.elements[0].matched + elif node.tag == MATCH_GREATER_OR_EQUAL: + attr_name = node.assertion['attr'] + attr_value = node.assertion['value'] + for candidate in candidates: + if attr_name in self.connection.server.dit[candidate]: + for value in self.connection.server.dit[candidate][attr_name]: + if value.isdigit() and attr_value.isdigit(): # int comparison + if int(value) >= int(attr_value): + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + else: + if to_unicode(value, SERVER_ENCODING).lower() >= to_unicode(attr_value, SERVER_ENCODING).lower(): # case insensitive string comparison + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + elif node.tag == MATCH_LESS_OR_EQUAL: + attr_name = node.assertion['attr'] + attr_value = node.assertion['value'] + for candidate in candidates: + if attr_name in self.connection.server.dit[candidate]: + for value in self.connection.server.dit[candidate][attr_name]: + if value.isdigit() and attr_value.isdigit(): # int comparison + if int(value) <= int(attr_value): + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + else: + if to_unicode(value, SERVER_ENCODING).lower() <= to_unicode(attr_value, SERVER_ENCODING).lower(): # case insentive string comparison + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + elif node.tag == MATCH_EXTENSIBLE: + self.connection.last_error = 'Extensible match not allowed in Mock strategy' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPDefinitionError(self.connection.last_error) + elif node.tag == MATCH_PRESENT: + attr_name = node.assertion['attr'] + for candidate in candidates: + if attr_name in self.connection.server.dit[candidate]: + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + elif node.tag == MATCH_SUBSTRING: + attr_name = node.assertion['attr'] + # rebuild the original substring filter + if 'initial' in node.assertion and node.assertion['initial'] is not None: + substring_filter = re.escape(to_unicode(node.assertion['initial'], SERVER_ENCODING)) + else: + substring_filter = '' + + if 'any' in node.assertion and node.assertion['any'] is not None: + for middle in node.assertion['any']: + substring_filter += '.*' + re.escape(to_unicode(middle, SERVER_ENCODING)) + + if 'final' in node.assertion and node.assertion['final'] is not None: + substring_filter += '.*' + re.escape(to_unicode(node.assertion['final'], SERVER_ENCODING)) + + if substring_filter and not node.assertion.get('any', None) and not node.assertion.get('final', None): # only initial, adds .* + substring_filter += '.*' + + regex_filter = re.compile(substring_filter, flags=re.UNICODE | re.IGNORECASE) # unicode AND ignorecase + for candidate in candidates: + if attr_name in self.connection.server.dit[candidate]: + for value in self.connection.server.dit[candidate][attr_name]: + if regex_filter.match(to_unicode(value, SERVER_ENCODING)): + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + else: + node.unmatched.add(candidate) + elif node.tag == MATCH_EQUAL or node.tag == MATCH_APPROX: + attr_name = node.assertion['attr'] + attr_value = node.assertion['value'] + for candidate in candidates: + if attr_name in self.connection.server.dit[candidate] and self.equal(candidate, attr_name, attr_value): + node.matched.add(candidate) + else: + node.unmatched.add(candidate) + + def equal(self, dn, attribute_type, value_to_check): + # value is the value to match + attribute_values = self.connection.server.dit[dn][attribute_type] + if not isinstance(attribute_values, SEQUENCE_TYPES): + attribute_values = [attribute_values] + escaped_value_to_check = ldap_escape_to_bytes(value_to_check) + for attribute_value in attribute_values: + if self._check_equality(escaped_value_to_check, attribute_value): + return True + if self._check_equality(self._prepare_value(attribute_type, value_to_check), attribute_value): + return True + return False + + @staticmethod + def _check_equality(value1, value2): + if value1 == value2: # exact matching + return True + if str(value1).isdigit() and str(value2).isdigit(): + if int(value1) == int(value2): # int comparison + return True + try: + if to_unicode(value1, SERVER_ENCODING).lower() == to_unicode(value2, SERVER_ENCODING).lower(): # case insensitive comparison + return True + except UnicodeError: + pass + + return False + + def send(self, message_type, request, controls=None): + self.connection.request = self.decode_request(message_type, request, controls) + if self.connection.listening: + message_id = self.connection.server.next_message_id() + if self.connection.usage: # ldap message is built for updating metrics only + ldap_message = LDAPMessage() + ldap_message['messageID'] = MessageID(message_id) + ldap_message['protocolOp'] = ProtocolOp().setComponentByName(message_type, request) + message_controls = build_controls_list(controls) + if message_controls is not None: + ldap_message['controls'] = message_controls + asn1_request = BaseStrategy.decode_request(message_type, request, controls) + self.connection._usage.update_transmitted_message(asn1_request, len(encode(ldap_message))) + return message_id, message_type, request, controls + else: + self.connection.last_error = 'unable to send message, connection is not open' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketOpenError(self.connection.last_error) + diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/mockSync.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockSync.py new file mode 100644 index 00000000..c96acb61 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/mockSync.py @@ -0,0 +1,133 @@ +""" +""" + +# Created on 2014.11.17 +# +# 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 . + +from ..core.results import DO_NOT_RAISE_EXCEPTIONS +from .mockBase import MockBaseStrategy +from .. import ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES +from .sync import SyncStrategy +from ..operation.bind import bind_response_to_dict +from ..operation.delete import delete_response_to_dict +from ..operation.add import add_response_to_dict +from ..operation.compare import compare_response_to_dict +from ..operation.modifyDn import modify_dn_response_to_dict +from ..operation.modify import modify_response_to_dict +from ..operation.search import search_result_done_response_to_dict, search_result_entry_response_to_dict +from ..operation.extended import extended_response_to_dict +from ..core.exceptions import LDAPSocketOpenError, LDAPOperationResult +from ..utils.log import log, log_enabled, ERROR, PROTOCOL + + +class MockSyncStrategy(MockBaseStrategy, SyncStrategy): # class inheritance sequence is important, MockBaseStrategy must be the first one + """ + This strategy create a mock LDAP server, with synchronous access + It can be useful to test LDAP without accessing a real Server + """ + def __init__(self, ldap_connection): + SyncStrategy.__init__(self, ldap_connection) + MockBaseStrategy.__init__(self) + + def post_send_search(self, payload): + message_id, message_type, request, controls = payload + self.connection.response = [] + self.connection.result = dict() + if message_type == 'searchRequest': + responses, result = self.mock_search(request, controls) + for entry in responses: + response = search_result_entry_response_to_dict(entry, self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names) + response['type'] = 'searchResEntry' + ### + if self.connection.empty_attributes: + for attribute_type in request['attributes']: + attribute_name = str(attribute_type) + if attribute_name not in response['raw_attributes'] and attribute_name not in (ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES): + response['raw_attributes'][attribute_name] = list() + response['attributes'][attribute_name] = list() + if log_enabled(PROTOCOL): + log(PROTOCOL, 'attribute set to empty list for missing attribute <%s> in <%s>', + attribute_type, self) + if not self.connection.auto_range: + attrs_to_remove = [] + # removes original empty attribute in case a range tag is returned + for attribute_type in response['attributes']: + attribute_name = str(attribute_type) + if ';range' in attribute_name.lower(): + orig_attr, _, _ = attribute_name.partition(';') + attrs_to_remove.append(orig_attr) + for attribute_type in attrs_to_remove: + if log_enabled(PROTOCOL): + log(PROTOCOL, + 'attribute type <%s> removed in response because of same attribute returned as range by the server in <%s>', + attribute_type, self) + del response['raw_attributes'][attribute_type] + del response['attributes'][attribute_type] + ### + self.connection.response.append(response) + result = search_result_done_response_to_dict(result) + result['type'] = 'searchResDone' + self.connection.result = result + if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + + return self.connection.response + + def post_send_single_response(self, payload): # payload is a tuple sent by self.send() made of message_type, request, controls + message_id, message_type, request, controls = payload + responses = [] + result = None + if message_type == 'bindRequest': + result = bind_response_to_dict(self.mock_bind(request, controls)) + result['type'] = 'bindResponse' + elif message_type == 'unbindRequest': + self.bound = None + elif message_type == 'abandonRequest': + pass + elif message_type == 'delRequest': + result = delete_response_to_dict(self.mock_delete(request, controls)) + result['type'] = 'delResponse' + elif message_type == 'addRequest': + result = add_response_to_dict(self.mock_add(request, controls)) + result['type'] = 'addResponse' + elif message_type == 'compareRequest': + result = compare_response_to_dict(self.mock_compare(request, controls)) + result['type'] = 'compareResponse' + elif message_type == 'modDNRequest': + result = modify_dn_response_to_dict(self.mock_modify_dn(request, controls)) + result['type'] = 'modDNResponse' + elif message_type == 'modifyRequest': + result = modify_response_to_dict(self.mock_modify(request, controls)) + result['type'] = 'modifyResponse' + elif message_type == 'extendedReq': + result = extended_response_to_dict(self.mock_extended(request, controls)) + result['type'] = 'extendedResp' + self.connection.result = result + responses.append(result) + if self.connection.raise_exceptions and result and result['result'] not in DO_NOT_RAISE_EXCEPTIONS: + if log_enabled(PROTOCOL): + log(PROTOCOL, 'operation result <%s> for <%s>', result, self.connection) + raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type']) + return responses + diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/restartable.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/restartable.py new file mode 100644 index 00000000..55f17060 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/restartable.py @@ -0,0 +1,260 @@ +""" +""" + +# Created on 2014.03.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 . + +from time import sleep +import socket + +from .. import get_config_parameter +from .sync import SyncStrategy +from ..core.exceptions import LDAPSocketOpenError, LDAPOperationResult, LDAPMaximumRetriesError, LDAPStartTLSError +from ..utils.log import log, log_enabled, ERROR, BASIC + + +# noinspection PyBroadException,PyProtectedMember +class RestartableStrategy(SyncStrategy): + def __init__(self, ldap_connection): + SyncStrategy.__init__(self, ldap_connection) + self.sync = True + self.no_real_dsa = False + self.pooled = False + self.can_stream = False + self.restartable_sleep_time = get_config_parameter('RESTARTABLE_SLEEPTIME') + self.restartable_tries = get_config_parameter('RESTARTABLE_TRIES') + self._restarting = False + self._last_bind_controls = None + self._current_message_type = None + self._current_request = None + self._current_controls = None + self._restart_tls = None + self.exception_history = [] + + def open(self, reset_usage=False, read_server_info=True): + SyncStrategy.open(self, reset_usage, read_server_info) + + def _open_socket(self, address, use_ssl=False, unix_socket=False): + """ + Try to open and connect a socket to a Server + raise LDAPExceptionError if unable to open or connect socket + if connection is restartable tries for the number of restarting requested or forever + """ + try: + SyncStrategy._open_socket(self, address, use_ssl, unix_socket) # try to open socket using SyncWait + self._reset_exception_history() + return + except Exception as e: # machinery for restartable connection + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + + if not self._restarting: # if not already performing a restart + self._restarting = True + counter = self.restartable_tries + while counter > 0: # includes restartable_tries == True + if log_enabled(BASIC): + log(BASIC, 'try #%d to open Restartable connection <%s>', self.restartable_tries - counter, self.connection) + sleep(self.restartable_sleep_time) + if not self.connection.closed: + try: # resetting connection + self.connection.unbind() + except (socket.error, LDAPSocketOpenError): # don't trace catch socket errors because socket could already be closed + pass + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + try: # reissuing same operation + if self.connection.server_pool: + new_server = self.connection.server_pool.get_server(self.connection) # get a server from the server_pool if available + if self.connection.server != new_server: + self.connection.server = new_server + if self.connection.usage: + self.connection._usage.servers_from_pool += 1 + SyncStrategy._open_socket(self, address, use_ssl, unix_socket) # calls super (not restartable) _open_socket() + if self.connection.usage: + self.connection._usage.restartable_successes += 1 + self.connection.closed = False + self._restarting = False + self._reset_exception_history() + return + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + if self.connection.usage: + self.connection._usage.restartable_failures += 1 + if not isinstance(self.restartable_tries, bool): + counter -= 1 + self._restarting = False + self.connection.last_error = 'restartable connection strategy failed while opening socket' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPMaximumRetriesError(self.connection.last_error, self.exception_history, self.restartable_tries) + + def send(self, message_type, request, controls=None): + self._current_message_type = message_type + self._current_request = request + self._current_controls = controls + if not self._restart_tls: # RFCs doesn't define how to stop tls once started + self._restart_tls = self.connection.tls_started + if message_type == 'bindRequest': # stores controls used in bind operation to be used again when restarting the connection + self._last_bind_controls = controls + + try: + message_id = SyncStrategy.send(self, message_type, request, controls) # tries to send using SyncWait + self._reset_exception_history() + return message_id + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + if not self._restarting: # machinery for restartable connection + self._restarting = True + counter = self.restartable_tries + while counter > 0: + if log_enabled(BASIC): + log(BASIC, 'try #%d to send in Restartable connection <%s>', self.restartable_tries - counter, self.connection) + sleep(self.restartable_sleep_time) + if not self.connection.closed: + try: # resetting connection + self.connection.unbind() + except (socket.error, LDAPSocketOpenError): # don't trace socket errors because socket could already be closed + pass + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + failure = False + try: # reopening connection + self.connection.open(reset_usage=False, read_server_info=False) + if self._restart_tls: # restart tls if start_tls was previously used + if not self.connection.start_tls(read_server_info=False): + error = 'restart tls in restartable not successful' + (' - ' + self.connection.last_error if self.connection.last_error else '') + if log_enabled(ERROR): + log(ERROR, '%s for <%s>', error, self) + self.connection.unbind() + raise LDAPStartTLSError(error) + if message_type != 'bindRequest': + self.connection.bind(read_server_info=False, controls=self._last_bind_controls) # binds with previously used controls unless the request is already a bindRequest + if not self.connection.server.schema and not self.connection.server.info: + self.connection.refresh_server_info() + else: + self.connection._fire_deferred(read_info=False) # in case of lazy connection, not open by the refresh_server_info + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + failure = True + + if not failure: + try: # reissuing same operation + ret_value = self.connection.send(message_type, request, controls) + if self.connection.usage: + self.connection._usage.restartable_successes += 1 + self._restarting = False + self._reset_exception_history() + return ret_value # successful send + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + failure = True + + if failure and self.connection.usage: + self.connection._usage.restartable_failures += 1 + + if not isinstance(self.restartable_tries, bool): + counter -= 1 + + self._restarting = False + + self.connection.last_error = 'restartable connection failed to send' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPMaximumRetriesError(self.connection.last_error, self.exception_history, self.restartable_tries) + + def post_send_single_response(self, message_id): + try: + ret_value = SyncStrategy.post_send_single_response(self, message_id) + self._reset_exception_history() + return ret_value + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + + # if an LDAPExceptionError is raised then resend the request + try: + ret_value = SyncStrategy.post_send_single_response(self, self.send(self._current_message_type, self._current_request, self._current_controls)) + self._reset_exception_history() + return ret_value + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + if not isinstance(e, LDAPOperationResult): + self.connection.last_error = 'restartable connection strategy failed in post_send_single_response' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise + + def post_send_search(self, message_id): + try: + ret_value = SyncStrategy.post_send_search(self, message_id) + self._reset_exception_history() + return ret_value + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + + # if an LDAPExceptionError is raised then resend the request + try: + ret_value = SyncStrategy.post_send_search(self, self.connection.send(self._current_message_type, self._current_request, self._current_controls)) + self._reset_exception_history() + return ret_value + except Exception as e: + if log_enabled(ERROR): + log(ERROR, '<%s> while restarting <%s>', e, self.connection) + self._add_exception_to_history(type(e)(str(e))) + if not isinstance(e, LDAPOperationResult): + self.connection.last_error = e.args + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise e + + def _add_exception_to_history(self, exc): + if not isinstance(self.restartable_tries, bool): # doesn't accumulate when restarting forever + if not isinstance(exc, LDAPMaximumRetriesError): # doesn't add the LDAPMaximumRetriesError exception + self.exception_history.append(exc) + + def _reset_exception_history(self): + if self.exception_history: + self.exception_history = [] + + def get_stream(self): + raise NotImplementedError + + def set_stream(self, value): + raise NotImplementedError diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/reusable.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/reusable.py new file mode 100644 index 00000000..01bd9d32 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/reusable.py @@ -0,0 +1,495 @@ +""" +""" + +# Created on 2014.03.23 +# +# 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 . + +from datetime import datetime +from os import linesep +from threading import Thread, Lock +from time import sleep + +from .. import RESTARTABLE, get_config_parameter, AUTO_BIND_DEFAULT, AUTO_BIND_NONE, AUTO_BIND_NO_TLS, AUTO_BIND_TLS_AFTER_BIND, AUTO_BIND_TLS_BEFORE_BIND +from .base import BaseStrategy +from ..core.usage import ConnectionUsage +from ..core.exceptions import LDAPConnectionPoolNameIsMandatoryError, LDAPConnectionPoolNotStartedError, LDAPOperationResult, LDAPExceptionError, LDAPResponseTimeoutError +from ..utils.log import log, log_enabled, ERROR, BASIC +from ..protocol.rfc4511 import LDAP_MAX_INT + +TERMINATE_REUSABLE = 'TERMINATE_REUSABLE_CONNECTION' + +BOGUS_BIND = -1 +BOGUS_UNBIND = -2 +BOGUS_EXTENDED = -3 +BOGUS_ABANDON = -4 + +try: + from queue import Queue, Empty +except ImportError: # Python 2 + # noinspection PyUnresolvedReferences + from Queue import Queue, Empty + + +# noinspection PyProtectedMember +class ReusableStrategy(BaseStrategy): + """ + A pool of reusable SyncWaitRestartable connections with lazy behaviour and limited lifetime. + The connection using this strategy presents itself as a normal connection, but internally the strategy has a pool of + connections that can be used as needed. Each connection lives in its own thread and has a busy/available status. + The strategy performs the requested operation on the first available connection. + The pool of connections is instantiated at strategy initialization. + Strategy has two customizable properties, the total number of connections in the pool and the lifetime of each connection. + When lifetime is expired the connection is closed and will be open again when needed. + """ + pools = dict() + + def receiving(self): + raise NotImplementedError + + def _start_listen(self): + raise NotImplementedError + + def _get_response(self, message_id, timeout): + raise NotImplementedError + + def get_stream(self): + raise NotImplementedError + + def set_stream(self, value): + raise NotImplementedError + + # noinspection PyProtectedMember + class ConnectionPool(object): + """ + Container for the Connection Threads + """ + def __new__(cls, connection): + if connection.pool_name in ReusableStrategy.pools: # returns existing connection pool + pool = ReusableStrategy.pools[connection.pool_name] + if not pool.started: # if pool is not started remove it from the pools singleton and create a new onw + del ReusableStrategy.pools[connection.pool_name] + return object.__new__(cls) + if connection.pool_keepalive and pool.keepalive != connection.pool_keepalive: # change lifetime + pool.keepalive = connection.pool_keepalive + if connection.pool_lifetime and pool.lifetime != connection.pool_lifetime: # change keepalive + pool.lifetime = connection.pool_lifetime + if connection.pool_size and pool.pool_size != connection.pool_size: # if pool size has changed terminate and recreate the connections + pool.terminate_pool() + pool.pool_size = connection.pool_size + return pool + else: + return object.__new__(cls) + + def __init__(self, connection): + if not hasattr(self, 'workers'): + self.name = connection.pool_name + self.master_connection = connection + self.workers = [] + self.pool_size = connection.pool_size or get_config_parameter('REUSABLE_THREADED_POOL_SIZE') + self.lifetime = connection.pool_lifetime or get_config_parameter('REUSABLE_THREADED_LIFETIME') + self.keepalive = connection.pool_keepalive + self.request_queue = Queue() + self.open_pool = False + self.bind_pool = False + self.tls_pool = False + self._incoming = dict() + self.counter = 0 + self.terminated_usage = ConnectionUsage() if connection._usage else None + self.terminated = False + self.pool_lock = Lock() + ReusableStrategy.pools[self.name] = self + self.started = False + if log_enabled(BASIC): + log(BASIC, 'instantiated ConnectionPool: <%r>', self) + + def __str__(self): + s = 'POOL: ' + str(self.name) + ' - status: ' + ('started' if self.started else 'terminated') + s += ' - responses in queue: ' + str(len(self._incoming)) + s += ' - pool size: ' + str(self.pool_size) + s += ' - lifetime: ' + str(self.lifetime) + s += ' - keepalive: ' + str(self.keepalive) + s += ' - open: ' + str(self.open_pool) + s += ' - bind: ' + str(self.bind_pool) + s += ' - tls: ' + str(self.tls_pool) + linesep + s += 'MASTER CONN: ' + str(self.master_connection) + linesep + s += 'WORKERS:' + if self.workers: + for i, worker in enumerate(self.workers): + s += linesep + str(i).rjust(5) + ': ' + str(worker) + else: + s += linesep + ' no active workers in pool' + + return s + + def __repr__(self): + return self.__str__() + + def get_info_from_server(self): + for worker in self.workers: + with worker.worker_lock: + if not worker.connection.server.schema or not worker.connection.server.info: + worker.get_info_from_server = True + else: + worker.get_info_from_server = False + + def rebind_pool(self): + for worker in self.workers: + with worker.worker_lock: + worker.connection.rebind(self.master_connection.user, + self.master_connection.password, + self.master_connection.authentication, + self.master_connection.sasl_mechanism, + self.master_connection.sasl_credentials) + + def start_pool(self): + if not self.started: + self.create_pool() + for worker in self.workers: + with worker.worker_lock: + worker.thread.start() + self.started = True + self.terminated = False + if log_enabled(BASIC): + log(BASIC, 'worker started for pool <%s>', self) + return True + return False + + def create_pool(self): + if log_enabled(BASIC): + log(BASIC, 'created pool <%s>', self) + self.workers = [ReusableStrategy.PooledConnectionWorker(self.master_connection, self.request_queue) for _ in range(self.pool_size)] + + def terminate_pool(self): + if not self.terminated: + if log_enabled(BASIC): + log(BASIC, 'terminating pool <%s>', self) + self.started = False + self.request_queue.join() # waits for all queue pending operations + for _ in range(len([worker for worker in self.workers if worker.thread.is_alive()])): # put a TERMINATE signal on the queue for each active thread + self.request_queue.put((TERMINATE_REUSABLE, None, None, None)) + self.request_queue.join() # waits for all queue terminate operations + self.terminated = True + if log_enabled(BASIC): + log(BASIC, 'pool terminated for <%s>', self) + + class PooledConnectionThread(Thread): + """ + The thread that holds the Reusable connection and receive operation request via the queue + Result are sent back in the pool._incoming list when ready + """ + def __init__(self, worker, master_connection): + Thread.__init__(self) + self.daemon = True + self.worker = worker + self.master_connection = master_connection + if log_enabled(BASIC): + log(BASIC, 'instantiated PooledConnectionThread: <%r>', self) + + # noinspection PyProtectedMember + def run(self): + self.worker.running = True + terminate = False + pool = self.master_connection.strategy.pool + while not terminate: + try: + counter, message_type, request, controls = pool.request_queue.get(block=True, timeout=self.master_connection.strategy.pool.keepalive) + except Empty: # issue an Abandon(0) operation to keep the connection live - Abandon(0) is a harmless operation + if not self.worker.connection.closed: + self.worker.connection.abandon(0) + continue + + with self.worker.worker_lock: + self.worker.busy = True + if counter == TERMINATE_REUSABLE: + terminate = True + if self.worker.connection.bound: + try: + self.worker.connection.unbind() + if log_enabled(BASIC): + log(BASIC, 'thread terminated') + except LDAPExceptionError: + pass + else: + if (datetime.now() - self.worker.creation_time).seconds >= self.master_connection.strategy.pool.lifetime: # destroy and create a new connection + try: + self.worker.connection.unbind() + except LDAPExceptionError: + pass + self.worker.new_connection() + if log_enabled(BASIC): + log(BASIC, 'thread respawn') + if message_type not in ['bindRequest', 'unbindRequest']: + try: + if pool.open_pool and self.worker.connection.closed: + self.worker.connection.open(read_server_info=False) + if pool.tls_pool and not self.worker.connection.tls_started: + self.worker.connection.start_tls(read_server_info=False) + if pool.bind_pool and not self.worker.connection.bound: + self.worker.connection.bind(read_server_info=False) + elif pool.open_pool and not self.worker.connection.closed: # connection already open, issues a start_tls + if pool.tls_pool and not self.worker.connection.tls_started: + self.worker.connection.start_tls(read_server_info=False) + if self.worker.get_info_from_server and counter: + self.worker.connection.refresh_server_info() + self.worker.get_info_from_server = False + response = None + result = None + if message_type == 'searchRequest': + response = self.worker.connection.post_send_search(self.worker.connection.send(message_type, request, controls)) + else: + response = self.worker.connection.post_send_single_response(self.worker.connection.send(message_type, request, controls)) + result = self.worker.connection.result + with pool.pool_lock: + pool._incoming[counter] = (response, result, BaseStrategy.decode_request(message_type, request, controls)) + except LDAPOperationResult as e: # raise_exceptions has raised an exception. It must be redirected to the original connection thread + with pool.pool_lock: + pool._incoming[counter] = (e, None, None) + # pool._incoming[counter] = (type(e)(str(e)), None, None) + # except LDAPOperationResult as e: # raise_exceptions has raised an exception. It must be redirected to the original connection thread + # exc = e + # with pool.pool_lock: + # if exc: + # pool._incoming[counter] = (exc, None, None) + # else: + # pool._incoming[counter] = (response, result, BaseStrategy.decode_request(message_type, request, controls)) + + self.worker.busy = False + pool.request_queue.task_done() + self.worker.task_counter += 1 + if log_enabled(BASIC): + log(BASIC, 'thread terminated') + if self.master_connection.usage: + pool.terminated_usage += self.worker.connection.usage + self.worker.running = False + + class PooledConnectionWorker(object): + """ + Container for the restartable connection. it includes a thread and a lock to execute the connection in the pool + """ + def __init__(self, connection, request_queue): + self.master_connection = connection + self.request_queue = request_queue + self.running = False + self.busy = False + self.get_info_from_server = False + self.connection = None + self.creation_time = None + self.task_counter = 0 + self.new_connection() + self.thread = ReusableStrategy.PooledConnectionThread(self, self.master_connection) + self.worker_lock = Lock() + if log_enabled(BASIC): + log(BASIC, 'instantiated PooledConnectionWorker: <%s>', self) + + def __str__(self): + s = 'CONN: ' + str(self.connection) + linesep + ' THREAD: ' + s += 'running' if self.running else 'halted' + s += ' - ' + ('busy' if self.busy else 'available') + s += ' - ' + ('created at: ' + self.creation_time.isoformat()) + s += ' - time to live: ' + str(self.master_connection.strategy.pool.lifetime - (datetime.now() - self.creation_time).seconds) + s += ' - requests served: ' + str(self.task_counter) + + return s + + def new_connection(self): + from ..core.connection import Connection + # noinspection PyProtectedMember + self.creation_time = datetime.now() + self.connection = Connection(server=self.master_connection.server_pool if self.master_connection.server_pool else self.master_connection.server, + user=self.master_connection.user, + password=self.master_connection.password, + auto_bind=AUTO_BIND_NONE, # do not perform auto_bind because it reads again the schema + version=self.master_connection.version, + authentication=self.master_connection.authentication, + client_strategy=RESTARTABLE, + auto_referrals=self.master_connection.auto_referrals, + auto_range=self.master_connection.auto_range, + sasl_mechanism=self.master_connection.sasl_mechanism, + sasl_credentials=self.master_connection.sasl_credentials, + check_names=self.master_connection.check_names, + collect_usage=self.master_connection._usage, + read_only=self.master_connection.read_only, + raise_exceptions=self.master_connection.raise_exceptions, + lazy=False, + fast_decoder=self.master_connection.fast_decoder, + receive_timeout=self.master_connection.receive_timeout, + return_empty_attributes=self.master_connection.empty_attributes) + + # simulates auto_bind, always with read_server_info=False + if self.master_connection.auto_bind and self.master_connection.auto_bind not in [AUTO_BIND_NONE, AUTO_BIND_DEFAULT]: + if log_enabled(BASIC): + log(BASIC, 'performing automatic bind for <%s>', self.connection) + self.connection.open(read_server_info=False) + if self.master_connection.auto_bind == AUTO_BIND_NO_TLS: + self.connection.bind(read_server_info=False) + elif self.master_connection.auto_bind == AUTO_BIND_TLS_BEFORE_BIND: + self.connection.start_tls(read_server_info=False) + self.connection.bind(read_server_info=False) + elif self.master_connection.auto_bind == AUTO_BIND_TLS_AFTER_BIND: + self.connection.bind(read_server_info=False) + self.connection.start_tls(read_server_info=False) + + if self.master_connection.server_pool: + self.connection.server_pool = self.master_connection.server_pool + self.connection.server_pool.initialize(self.connection) + + # ReusableStrategy methods + def __init__(self, ldap_connection): + BaseStrategy.__init__(self, ldap_connection) + self.sync = False + self.no_real_dsa = False + self.pooled = True + self.can_stream = False + if hasattr(ldap_connection, 'pool_name') and ldap_connection.pool_name: + self.pool = ReusableStrategy.ConnectionPool(ldap_connection) + else: + if log_enabled(ERROR): + log(ERROR, 'reusable connection must have a pool_name') + raise LDAPConnectionPoolNameIsMandatoryError('reusable connection must have a pool_name') + + def open(self, reset_usage=True, read_server_info=True): + # read_server_info not used + self.pool.open_pool = True + self.pool.start_pool() + self.connection.closed = False + if self.connection.usage: + if reset_usage or not self.connection._usage.initial_connection_start_time: + self.connection._usage.start() + + def terminate(self): + self.pool.terminate_pool() + self.pool.open_pool = False + self.connection.bound = False + self.connection.closed = True + self.pool.bind_pool = False + self.pool.tls_pool = False + + def _close_socket(self): + """ + Doesn't really close the socket + """ + self.connection.closed = True + + if self.connection.usage: + self.connection._usage.closed_sockets += 1 + + def send(self, message_type, request, controls=None): + if self.pool.started: + if message_type == 'bindRequest': + self.pool.bind_pool = True + counter = BOGUS_BIND + elif message_type == 'unbindRequest': + self.pool.bind_pool = False + counter = BOGUS_UNBIND + elif message_type == 'abandonRequest': + counter = BOGUS_ABANDON + elif message_type == 'extendedReq' and self.connection.starting_tls: + self.pool.tls_pool = True + counter = BOGUS_EXTENDED + else: + with self.pool.pool_lock: + self.pool.counter += 1 + if self.pool.counter > LDAP_MAX_INT: + self.pool.counter = 1 + counter = self.pool.counter + self.pool.request_queue.put((counter, message_type, request, controls)) + return counter + if log_enabled(ERROR): + log(ERROR, 'reusable connection pool not started') + raise LDAPConnectionPoolNotStartedError('reusable connection pool not started') + + def validate_bind(self, controls): + # in case of a new connection or different credentials + if (self.connection.user != self.pool.master_connection.user or + self.connection.password != self.pool.master_connection.password or + self.connection.authentication != self.pool.master_connection.authentication or + self.connection.sasl_mechanism != self.pool.master_connection.sasl_mechanism or + self.connection.sasl_credentials != self.pool.master_connection.sasl_credentials): + self.pool.master_connection.user = self.connection.user + self.pool.master_connection.password = self.connection.password + self.pool.master_connection.authentication = self.connection.authentication + self.pool.master_connection.sasl_mechanism = self.connection.sasl_mechanism + self.pool.master_connection.sasl_credentials = self.connection.sasl_credentials + self.pool.rebind_pool() + temp_connection = self.pool.workers[0].connection + old_lazy = temp_connection.lazy + temp_connection.lazy = False + if not self.connection.server.schema or not self.connection.server.info: + result = self.pool.workers[0].connection.bind(controls=controls) + else: + result = self.pool.workers[0].connection.bind(controls=controls, read_server_info=False) + + temp_connection.unbind() + temp_connection.lazy = old_lazy + if result: + self.pool.bind_pool = True # bind pool if bind is validated + return result + + def get_response(self, counter, timeout=None, get_request=False): + sleeptime = get_config_parameter('RESPONSE_SLEEPTIME') + request=None + if timeout is None: + timeout = get_config_parameter('RESPONSE_WAITING_TIMEOUT') + if counter == BOGUS_BIND: # send a bogus bindResponse + response = list() + result = {'description': 'success', 'referrals': None, 'type': 'bindResponse', 'result': 0, 'dn': '', 'message': '', 'saslCreds': None} + elif counter == BOGUS_UNBIND: # bogus unbind response + response = None + result = None + elif counter == BOGUS_ABANDON: # abandon cannot be executed because of multiple connections + response = list() + result = {'result': 0, 'referrals': None, 'responseName': '1.3.6.1.4.1.1466.20037', 'type': 'extendedResp', 'description': 'success', 'responseValue': 'None', 'dn': '', 'message': ''} + elif counter == BOGUS_EXTENDED: # bogus startTls extended response + response = list() + result = {'result': 0, 'referrals': None, 'responseName': '1.3.6.1.4.1.1466.20037', 'type': 'extendedResp', 'description': 'success', 'responseValue': 'None', 'dn': '', 'message': ''} + self.connection.starting_tls = False + else: + response = None + result = None + while timeout >= 0: # waiting for completed message to appear in _incoming + try: + with self.connection.strategy.pool.pool_lock: + response, result, request = self.connection.strategy.pool._incoming.pop(counter) + except KeyError: + sleep(sleeptime) + timeout -= sleeptime + continue + break + + if timeout <= 0: + if log_enabled(ERROR): + log(ERROR, 'no response from worker threads in Reusable connection') + raise LDAPResponseTimeoutError('no response from worker threads in Reusable connection') + + if isinstance(response, LDAPOperationResult): + raise response # an exception has been raised with raise_exceptions + + if get_request: + return response, result, request + + return response, result + + def post_send_single_response(self, counter): + return counter + + def post_send_search(self, counter): + return counter diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/safeRestartable.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/safeRestartable.py new file mode 100644 index 00000000..60d88fa7 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/safeRestartable.py @@ -0,0 +1,32 @@ +""" +""" + +# Created on 2020.07.12 +# +# 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 . + +from .restartable import RestartableStrategy + + +class SafeRestartableStrategy(RestartableStrategy): + def __init__(self, ldap_connection): + RestartableStrategy.__init__(self, ldap_connection) + self.thread_safe = True diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/safeSync.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/safeSync.py new file mode 100644 index 00000000..ea0c276f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/safeSync.py @@ -0,0 +1,32 @@ +""" +""" + +# Created on 2020.07.12 +# +# 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 . + +from .sync import SyncStrategy + + +class SafeSyncStrategy(SyncStrategy): + def __init__(self, ldap_connection): + SyncStrategy.__init__(self, ldap_connection) + self.thread_safe = True diff --git a/plugins/ldap-user-sync/vendor/ldap3/strategy/sync.py b/plugins/ldap-user-sync/vendor/ldap3/strategy/sync.py new file mode 100644 index 00000000..49224c6f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/strategy/sync.py @@ -0,0 +1,251 @@ +""" +""" + +# Created on 2013.07.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 . + +import socket + +from .. import SEQUENCE_TYPES, get_config_parameter, DIGEST_MD5 +from ..core.exceptions import LDAPSocketReceiveError, communication_exception_factory, LDAPExceptionError, LDAPExtensionError, LDAPOperationResult, LDAPSignatureVerificationFailedError +from ..strategy.base import BaseStrategy, SESSION_TERMINATED_BY_SERVER, RESPONSE_COMPLETE, TRANSACTION_ERROR +from ..protocol.rfc4511 import LDAPMessage +from ..utils.log import log, log_enabled, ERROR, NETWORK, EXTENDED, format_ldap_message +from ..utils.asn1 import decoder, decode_message_fast +from ..protocol.sasl.digestMd5 import md5_hmac + +LDAP_MESSAGE_TEMPLATE = LDAPMessage() + + +# noinspection PyProtectedMember +class SyncStrategy(BaseStrategy): + """ + This strategy is synchronous. You send the request and get the response + Requests return a boolean value to indicate the result of the requested Operation + Connection.response will contain the whole LDAP response for the messageId requested in a dict form + Connection.request will contain the result LDAP message in a dict form + """ + + def __init__(self, ldap_connection): + BaseStrategy.__init__(self, ldap_connection) + self.sync = True + self.no_real_dsa = False + self.pooled = False + self.can_stream = False + self.socket_size = get_config_parameter('SOCKET_SIZE') + + def open(self, reset_usage=True, read_server_info=True): + BaseStrategy.open(self, reset_usage, read_server_info) + if read_server_info and not self.connection._deferred_open: + try: + self.connection.refresh_server_info() + except LDAPOperationResult: # catch errors from server if raise_exception = True + self.connection.server._dsa_info = None + self.connection.server._schema_info = None + + def _start_listen(self): + if not self.connection.listening and not self.connection.closed: + self.connection.listening = True + + def receiving(self): + """ + Receives data over the socket + Checks if the socket is closed + """ + messages = [] + receiving = True + unprocessed = b'' + data = b'' + get_more_data = True + # exc = None # not needed here GC + sasl_total_bytes_recieved = 0 + sasl_received_data = b'' # used to verify the signature + sasl_next_packet = b'' + # sasl_signature = b'' # not needed here? GC + # sasl_sec_num = b'' # used to verify the signature # not needed here, reformatted to lowercase GC + sasl_buffer_length = -1 # added, not initialized? GC + while receiving: + if get_more_data: + try: + data = self.connection.socket.recv(self.socket_size) + except (OSError, socket.error, AttributeError) as e: + self.connection.last_error = 'error receiving data: ' + str(e) + try: # try to close the connection before raising exception + self.close() + except (socket.error, LDAPExceptionError): + pass + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise communication_exception_factory(LDAPSocketReceiveError, exc)(self.connection.last_error) + raise communication_exception_factory(LDAPSocketReceiveError, type(e)(str(e)))(self.connection.last_error) + + # If we are using DIGEST-MD5 and LDAP signing is set : verify & remove the signature from the message + if self.connection.sasl_mechanism == DIGEST_MD5 and self.connection._digest_md5_kis and not self.connection.sasl_in_progress: + data = sasl_next_packet + data + + if sasl_received_data == b'' or sasl_next_packet: + # Remove the sizeOf(encoded_message + signature + 0x0001 + secNum) from data. + sasl_buffer_length = int.from_bytes(data[0:4], "big") + data = data[4:] + sasl_next_packet = b'' + sasl_total_bytes_recieved += len(data) + sasl_received_data += data + + if sasl_total_bytes_recieved >= sasl_buffer_length: + # When the LDAP response is splitted accross multiple TCP packets, the SASL buffer length is equal to the MTU of each packet..Which is usually not equal to self.socket_size + # This means that the end of one SASL packet/beginning of one other....could be located in the middle of data + # We are using "sasl_received_data" instead of "data" & "unprocessed" for this reason + + # structure of messages when LDAP signing is enabled : sizeOf(encoded_message + signature + 0x0001 + secNum) + encoded_message + signature + 0x0001 + secNum + sasl_signature = sasl_received_data[sasl_buffer_length - 16:sasl_buffer_length - 6] + sasl_sec_num = sasl_received_data[sasl_buffer_length - 4:sasl_buffer_length] + sasl_next_packet = sasl_received_data[sasl_buffer_length:] # the last "data" variable may contain another sasl packet. We'll process it at the next iteration. + sasl_received_data = sasl_received_data[:sasl_buffer_length - 16] # remove signature + 0x0001 + secNum + the next packet if any, from sasl_received_data + + kis = self.connection._digest_md5_kis # renamed to lowercase GC + calculated_signature = bytes.fromhex(md5_hmac(kis, sasl_sec_num + sasl_received_data)[0:20]) + if sasl_signature != calculated_signature: + raise LDAPSignatureVerificationFailedError("Signature verification failed for the recieved LDAP message number " + str(int.from_bytes(sasl_sec_num, 'big')) + ". Expected signature " + calculated_signature.hex() + " but got " + sasl_signature.hex() + ".") + sasl_total_bytes_recieved = 0 + unprocessed += sasl_received_data + sasl_received_data = b'' + else: + unprocessed += data + if len(data) > 0: + length = BaseStrategy.compute_ldap_message_size(unprocessed) + if length == -1: # too few data to decode message length + get_more_data = True + continue + if len(unprocessed) < length: + get_more_data = True + else: + if log_enabled(NETWORK): + log(NETWORK, 'received %d bytes via <%s>', len(unprocessed[:length]), self.connection) + messages.append(unprocessed[:length]) + unprocessed = unprocessed[length:] + get_more_data = False + if len(unprocessed) == 0: + receiving = False + else: + receiving = False + + if log_enabled(NETWORK): + log(NETWORK, 'received %d ldap messages via <%s>', len(messages), self.connection) + return messages + + def post_send_single_response(self, message_id): + """ + Executed after an Operation Request (except Search) + Returns the result message or None + """ + responses, result = self.get_response(message_id) + self.connection.result = result + if result['type'] == 'intermediateResponse': # checks that all responses are intermediates (there should be only one) + for response in responses: + if response['type'] != 'intermediateResponse': + self.connection.last_error = 'multiple messages received error' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketReceiveError(self.connection.last_error) + + responses.append(result) + return responses + + def post_send_search(self, message_id): + """ + Executed after a search request + Returns the result message and store in connection.response the objects found + """ + responses, result = self.get_response(message_id) + self.connection.result = result + if isinstance(responses, SEQUENCE_TYPES): + self.connection.response = responses[:] # copy search result entries + return responses + + self.connection.last_error = 'error receiving response' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketReceiveError(self.connection.last_error) + + def _get_response(self, message_id, timeout): + """ + Performs the capture of LDAP response for SyncStrategy + """ + ldap_responses = [] + response_complete = False + while not response_complete: + responses = self.receiving() + if responses: + for response in responses: + if len(response) > 0: + if self.connection.usage: + self.connection._usage.update_received_message(len(response)) + if self.connection.fast_decoder: + ldap_resp = decode_message_fast(response) + dict_response = self.decode_response_fast(ldap_resp) + else: + ldap_resp, _ = decoder.decode(response, asn1Spec=LDAP_MESSAGE_TEMPLATE) # unprocessed unused because receiving() waits for the whole message + dict_response = self.decode_response(ldap_resp) + if log_enabled(EXTENDED): + log(EXTENDED, 'ldap message received via <%s>:%s', self.connection, format_ldap_message(ldap_resp, '<<')) + if int(ldap_resp['messageID']) == message_id: + ldap_responses.append(dict_response) + if dict_response['type'] not in ['searchResEntry', 'searchResRef', 'intermediateResponse']: + response_complete = True + elif int(ldap_resp['messageID']) == 0: # 0 is reserved for 'Unsolicited Notification' from server as per RFC4511 (paragraph 4.4) + if dict_response['responseName'] == '1.3.6.1.4.1.1466.20036': # Notice of Disconnection as per RFC4511 (paragraph 4.4.1) + return SESSION_TERMINATED_BY_SERVER + elif dict_response['responseName'] == '2.16.840.1.113719.1.27.103.4': # Novell LDAP transaction error unsolicited notification + return TRANSACTION_ERROR + else: + self.connection.last_error = 'unknown unsolicited notification from server' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketReceiveError(self.connection.last_error) + elif int(ldap_resp['messageID']) != message_id and dict_response['type'] == 'extendedResp': + self.connection.last_error = 'multiple extended responses to a single extended request' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPExtensionError(self.connection.last_error) + # pass # ignore message with invalid messageId when receiving multiple extendedResp. This is not allowed by RFC4511 but some LDAP server do it + else: + self.connection.last_error = 'invalid messageId received' + if log_enabled(ERROR): + log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + raise LDAPSocketReceiveError(self.connection.last_error) + # response = unprocessed + # if response: # if this statement is removed unprocessed data will be processed as another message + # self.connection.last_error = 'unprocessed substrate error' + # if log_enabled(ERROR): + # log(ERROR, '<%s> for <%s>', self.connection.last_error, self.connection) + # raise LDAPSocketReceiveError(self.connection.last_error) + else: + return SESSION_TERMINATED_BY_SERVER + ldap_responses.append(RESPONSE_COMPLETE) + + return ldap_responses + + def set_stream(self, value): + raise NotImplementedError + + def get_stream(self): + raise NotImplementedError diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/__init__.py b/plugins/ldap-user-sync/vendor/ldap3/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/asn1.py b/plugins/ldap-user-sync/vendor/ldap3/utils/asn1.py new file mode 100644 index 00000000..1dba765c --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/asn1.py @@ -0,0 +1,245 @@ +""" +""" + +# Created on 2015.08.19 +# +# 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 . + +from pyasn1 import __version__ as pyasn1_version +from pyasn1.codec.ber import decoder # for usage in other modules +from pyasn1.codec.ber.encoder import Encoder # for monkeypatching of boolean value +from ..core.results import RESULT_CODES +from ..utils.conv import to_unicode +from ..protocol.convert import referrals_to_list + +CLASSES = {(False, False): 0, # Universal + (False, True): 1, # Application + (True, False): 2, # Context + (True, True): 3} # Private + + +# Monkeypatching of pyasn1 for encoding Boolean with the value 0xFF for TRUE +# THIS IS NOT PART OF THE FAST BER DECODER +if pyasn1_version == 'xxx0.2.3': + from pyasn1.codec.ber.encoder import tagMap, BooleanEncoder, encode + from pyasn1.type.univ import Boolean + from pyasn1.compat.octets import ints2octs + class BooleanCEREncoder(BooleanEncoder): + _true = ints2octs((255,)) + + tagMap[Boolean.tagSet] = BooleanCEREncoder() +else: + from pyasn1.codec.ber.encoder import tagMap, typeMap, AbstractItemEncoder + from pyasn1.type.univ import Boolean + from copy import deepcopy + + class LDAPBooleanEncoder(AbstractItemEncoder): + supportIndefLenMode = False + if pyasn1_version <= '0.2.3': + from pyasn1.compat.octets import ints2octs + _true = ints2octs((255,)) + _false = ints2octs((0,)) + def encodeValue(self, encodeFun, value, defMode, maxChunkSize): + return value and self._true or self._false, 0 + elif pyasn1_version <= '0.3.1': + def encodeValue(self, encodeFun, value, defMode, maxChunkSize): + return value and (255,) or (0,), False, False + elif pyasn1_version <= '0.3.4': + def encodeValue(self, encodeFun, value, defMode, maxChunkSize, ifNotEmpty=False): + return value and (255,) or (0,), False, False + elif pyasn1_version <= '0.3.7': + def encodeValue(self, value, encodeFun, **options): + return value and (255,) or (0,), False, False + else: + def encodeValue(self, value, asn1Spec, encodeFun, **options): + return value and (255,) or (0,), False, False + + customTagMap = deepcopy(tagMap) + customTypeMap = deepcopy(typeMap) + customTagMap[Boolean.tagSet] = LDAPBooleanEncoder() + customTypeMap[Boolean.typeId] = LDAPBooleanEncoder() + + encode = Encoder(customTagMap, customTypeMap) +# end of monkey patching + +# a fast BER decoder for LDAP responses only +def compute_ber_size(data): + """ + Compute size according to BER definite length rules + Returns size of value and value offset + """ + + if data[1] <= 127: # BER definite length - short form. Highest bit of byte 1 is 0, message length is in the last 7 bits - Value can be up to 127 bytes long + return data[1], 2 + else: # BER definite length - long form. Highest bit of byte 1 is 1, last 7 bits counts the number of following octets containing the value length + bytes_length = data[1] - 128 + value_length = 0 + cont = bytes_length + for byte in data[2: 2 + bytes_length]: + cont -= 1 + value_length += byte * (256 ** cont) + return value_length, bytes_length + 2 + + +def decode_message_fast(message): + ber_len, ber_value_offset = compute_ber_size(get_bytes(message[:10])) # get start of sequence, at maximum 3 bytes for length + decoded = decode_sequence(message, ber_value_offset, ber_len + ber_value_offset, LDAP_MESSAGE_CONTEXT) + return { + 'messageID': decoded[0][3], + 'protocolOp': decoded[1][2], + 'payload': decoded[1][3], + 'controls': decoded[2][3] if len(decoded) == 3 else None + } + + +def decode_sequence(message, start, stop, context_decoders=None): + decoded = [] + while start < stop: + octet = get_byte(message[start]) + ber_class = CLASSES[(bool(octet & 0b10000000), bool(octet & 0b01000000))] + ber_constructed = bool(octet & 0b00100000) + ber_type = octet & 0b00011111 + ber_decoder = DECODERS[(ber_class, octet & 0b00011111)] if ber_class < 2 else None + ber_len, ber_value_offset = compute_ber_size(get_bytes(message[start: start + 10])) + start += ber_value_offset + if ber_decoder: + value = ber_decoder(message, start, start + ber_len, context_decoders) # call value decode function + else: + # try: + value = context_decoders[ber_type](message, start, start + ber_len) # call value decode function for context class + # except KeyError: + # if ber_type == 3: # Referral in result + # value = decode_sequence(message, start, start + ber_len) + # else: + # raise # re-raise, should never happen + decoded.append((ber_class, ber_constructed, ber_type, value)) + start += ber_len + + return decoded + + +def decode_integer(message, start, stop, context_decoders=None): + first = message[start] + value = -1 if get_byte(first) & 0x80 else 0 + for octet in message[start: stop]: + value = value << 8 | get_byte(octet) + + return value + + +def decode_octet_string(message, start, stop, context_decoders=None): + return message[start: stop] + + +def decode_boolean(message, start, stop, context_decoders=None): + return False if message[start: stop] == 0 else True + + +def decode_bind_response(message, start, stop, context_decoders=None): + return decode_sequence(message, start, stop, BIND_RESPONSE_CONTEXT) + + +def decode_extended_response(message, start, stop, context_decoders=None): + return decode_sequence(message, start, stop, EXTENDED_RESPONSE_CONTEXT) + + +def decode_intermediate_response(message, start, stop, context_decoders=None): + return decode_sequence(message, start, stop, INTERMEDIATE_RESPONSE_CONTEXT) + + +def decode_controls(message, start, stop, context_decoders=None): + return decode_sequence(message, start, stop, CONTROLS_CONTEXT) + + +def ldap_result_to_dict_fast(response): + response_dict = dict() + response_dict['result'] = int(response[0][3]) # resultCode + response_dict['description'] = RESULT_CODES[response_dict['result']] + response_dict['dn'] = to_unicode(response[1][3], from_server=True) # matchedDN + response_dict['message'] = to_unicode(response[2][3], from_server=True) # diagnosticMessage + if len(response) == 4: + response_dict['referrals'] = referrals_to_list([to_unicode(referral[3], from_server=True) for referral in response[3][3]]) # referrals + else: + response_dict['referrals'] = None + + return response_dict + + +###### + +if str is not bytes: # Python 3 + def get_byte(x): + return x + + def get_bytes(x): + return x +else: # Python 2 + def get_byte(x): + return ord(x) + + def get_bytes(x): + return bytearray(x) + +DECODERS = { + # Universal + (0, 1): decode_boolean, # Boolean + (0, 2): decode_integer, # Integer + (0, 4): decode_octet_string, # Octet String + (0, 10): decode_integer, # Enumerated + (0, 16): decode_sequence, # Sequence + (0, 17): decode_sequence, # Set + # Application + (1, 1): decode_bind_response, # Bind response + (1, 4): decode_sequence, # Search result entry + (1, 5): decode_sequence, # Search result done + (1, 7): decode_sequence, # Modify response + (1, 9): decode_sequence, # Add response + (1, 11): decode_sequence, # Delete response + (1, 13): decode_sequence, # ModifyDN response + (1, 15): decode_sequence, # Compare response + (1, 19): decode_sequence, # Search result reference + (1, 24): decode_extended_response, # Extended response + (1, 25): decode_intermediate_response, # intermediate response + (2, 3): decode_octet_string # +} + +BIND_RESPONSE_CONTEXT = { + 7: decode_octet_string # SaslCredentials +} + +EXTENDED_RESPONSE_CONTEXT = { + 10: decode_octet_string, # ResponseName + 11: decode_octet_string # Response Value +} + +INTERMEDIATE_RESPONSE_CONTEXT = { + 0: decode_octet_string, # IntermediateResponseName + 1: decode_octet_string # IntermediateResponseValue +} + +LDAP_MESSAGE_CONTEXT = { + 0: decode_controls, # Controls + 3: decode_sequence # Referral +} + +CONTROLS_CONTEXT = { + 0: decode_sequence # Control +} diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/ciDict.py b/plugins/ldap-user-sync/vendor/ldap3/utils/ciDict.py new file mode 100644 index 00000000..8450a1de --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/ciDict.py @@ -0,0 +1,199 @@ +""" +""" + +# Created on 2014.08.23 +# +# 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 . + +try: + from collections.abc import MutableMapping, Mapping +except ImportError: + from collections import MutableMapping, Mapping + +from .. import SEQUENCE_TYPES + + +class CaseInsensitiveDict(MutableMapping): + def __init__(self, other=None, **kwargs): + self._store = dict() # store use the original key + self._case_insensitive_keymap = dict() # is a mapping ci_key -> key + if other or kwargs: + if other is None: + other = dict() + self.update(other, **kwargs) + + def __contains__(self, item): + try: + self.__getitem__(item) + return True + except KeyError: + return False + + @staticmethod + def _ci_key(key): + return key.strip().lower() if hasattr(key, 'lower') else key + + def __delitem__(self, key): + ci_key = self._ci_key(key) + del self._store[self._case_insensitive_keymap[ci_key]] + del self._case_insensitive_keymap[ci_key] + + def __setitem__(self, key, item): + ci_key = self._ci_key(key) + if ci_key in self._case_insensitive_keymap: # updates existing value + self._store[self._case_insensitive_keymap[ci_key]] = item + else: # new key + self._store[key] = item + self._case_insensitive_keymap[ci_key] = key + + def __getitem__(self, key): + return self._store[self._case_insensitive_keymap[self._ci_key(key)]] + + def __iter__(self): + return self._store.__iter__() + + def __len__(self): # if len is 0 then the cidict appears as False in IF statement + return len(self._store) + + def __repr__(self): + return repr(self._store) + + def __str__(self): + return str(self._store) + + def keys(self): + return self._store.keys() + + def values(self): + return self._store.values() + + def items(self): + return self._store.items() + + def __eq__(self, other): + if not isinstance(other, (Mapping, dict)): + return NotImplemented + + if isinstance(other, CaseInsensitiveDict): + if len(self.items()) != len(other.items()): + return False + else: + for key, value in self.items(): + if not (key in other and other[key] == value): + return False + return True + + return self == CaseInsensitiveDict(other) + + def copy(self): + return CaseInsensitiveDict(self._store) + + +class CaseInsensitiveWithAliasDict(CaseInsensitiveDict): + def __init__(self, other=None, **kwargs): + self._aliases = dict() + self._alias_keymap = dict() # is a mapping key -> [alias1, alias2, ...] + CaseInsensitiveDict.__init__(self, other, **kwargs) + + def aliases(self): + return self._aliases.keys() + + def __setitem__(self, key, value): + if isinstance(key, SEQUENCE_TYPES): + ci_key = self._ci_key(key[0]) + if ci_key not in self._aliases: + CaseInsensitiveDict.__setitem__(self, key[0], value) + self.set_alias(ci_key, key[1:]) + else: + raise KeyError('\'' + str(key[0] + ' already used as alias')) + else: + ci_key = self._ci_key(key) + if ci_key not in self._aliases: + CaseInsensitiveDict.__setitem__(self, key, value) + else: + self[self._aliases[ci_key]] = value + + def __delitem__(self, key): + ci_key = self._ci_key(key) + try: + CaseInsensitiveDict.__delitem__(self, ci_key) + if ci_key in self._alias_keymap: + for alias in self._alias_keymap[ci_key][:]: # removes aliases, uses a copy of _alias_keymap because iterator gets confused when aliases are removed from _alias_keymap + self.remove_alias(alias) + return + except KeyError: # try to remove alias + if ci_key in self._aliases: + self.remove_alias(ci_key) + + def set_alias(self, key, alias, ignore_duplicates=False): + if not isinstance(alias, SEQUENCE_TYPES): + alias = [alias] + for alias_to_add in alias: + ci_key = self._ci_key(key) + if ci_key in self._case_insensitive_keymap: + ci_alias = self._ci_key(alias_to_add) + if ci_alias not in self._case_insensitive_keymap: # checks if alias is used a key + if ci_alias not in self._aliases: # checks if alias is used as another alias + self._aliases[ci_alias] = ci_key + if ci_key in self._alias_keymap: # extends alias keymap + self._alias_keymap[ci_key].append(self._ci_key(ci_alias)) + else: + self._alias_keymap[ci_key] = list() + self._alias_keymap[ci_key].append(self._ci_key(ci_alias)) + else: + if ci_key in self._alias_keymap and ci_alias in self._alias_keymap[ci_key]: # passes if alias is already defined to the same key + pass + elif not ignore_duplicates: + raise KeyError('\'' + str(alias_to_add) + '\' already used as alias') + else: + if ci_key == self._ci_key(self._case_insensitive_keymap[ci_alias]): # passes if alias is already defined to the same key + pass + elif not ignore_duplicates: + raise KeyError('\'' + str(alias_to_add) + '\' already used as key') + else: + for keymap in self._alias_keymap: + if ci_key in self._alias_keymap[keymap]: # kye is already aliased + self.set_alias(keymap, alias + [ci_key], ignore_duplicates=ignore_duplicates) + break + else: + raise KeyError('\'' + str(ci_key) + '\' is not an existing alias or key') + + def remove_alias(self, alias): + if not isinstance(alias, SEQUENCE_TYPES): + alias = [alias] + for alias_to_remove in alias: + ci_alias = self._ci_key(alias_to_remove) + self._alias_keymap[self._aliases[ci_alias]].remove(ci_alias) + if not self._alias_keymap[self._aliases[ci_alias]]: # remove keymap if empty + del self._alias_keymap[self._aliases[ci_alias]] + del self._aliases[ci_alias] + + def __getitem__(self, key): + try: + return CaseInsensitiveDict.__getitem__(self, key) + except KeyError: + return CaseInsensitiveDict.__getitem__(self, self._aliases[self._ci_key(key)]) + + def copy(self): + new = CaseInsensitiveWithAliasDict(self._store) + new._aliases = self._aliases.copy() + new._alias_keymap = self._alias_keymap + return new diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/config.py b/plugins/ldap-user-sync/vendor/ldap3/utils/config.py new file mode 100644 index 00000000..e4b8a926 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/config.py @@ -0,0 +1,299 @@ +""" +""" + +# Created on 2016.08.31 +# +# 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 . + +from sys import stdin, getdefaultencoding + +from .. import ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, NO_ATTRIBUTES, SEQUENCE_TYPES +from ..core.exceptions import LDAPConfigurationParameterError + +# checks +_CLASSES_EXCLUDED_FROM_CHECK = ['subschema'] +_ATTRIBUTES_EXCLUDED_FROM_CHECK = [ALL_ATTRIBUTES, + ALL_OPERATIONAL_ATTRIBUTES, + NO_ATTRIBUTES, + 'ldapSyntaxes', + 'matchingRules', + 'matchingRuleUse', + 'dITContentRules', + 'dITStructureRules', + 'nameForms', + 'altServer', + 'namingContexts', + 'supportedControl', + 'supportedExtension', + 'supportedFeatures', + 'supportedCapabilities', + 'supportedLdapVersion', + 'supportedSASLMechanisms', + 'vendorName', + 'vendorVersion', + 'subschemaSubentry', + 'ACL'] +_UTF8_ENCODED_SYNTAXES = ['1.2.840.113556.1.4.904', # DN String [MICROSOFT] + '1.2.840.113556.1.4.1362', # String (Case) [MICROSOFT] + '1.3.6.1.4.1.1466.115.121.1.12', # DN String [RFC4517] + '1.3.6.1.4.1.1466.115.121.1.15', # Directory String [RFC4517] + '1.3.6.1.4.1.1466.115.121.1.41', # Postal Address) [RFC4517] + '1.3.6.1.4.1.1466.115.121.1.58', # Substring Assertion [RFC4517] + '2.16.840.1.113719.1.1.5.1.6', # Case Ignore List [NOVELL] + '2.16.840.1.113719.1.1.5.1.14', # Tagged String [NOVELL] + '2.16.840.1.113719.1.1.5.1.15', # Tagged Name and String [NOVELL] + '2.16.840.1.113719.1.1.5.1.23', # Tagged Name [NOVELL] + '2.16.840.1.113719.1.1.5.1.25'] # Typed Name [NOVELL] + +_UTF8_ENCODED_TYPES = [] + +_ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF = ['msds-memberOfTransitive', 'msds-memberTransitive', 'entryDN'] +_IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF = ['instanceType', 'nTSecurityDescriptor', 'objectCategory'] + +_CASE_INSENSITIVE_ATTRIBUTE_NAMES = True +_CASE_INSENSITIVE_SCHEMA_NAMES = True + +# abstraction layer +_ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX = 'OA_' + +# communication +_POOLING_LOOP_TIMEOUT = 10 # number of seconds to wait before restarting a cycle to find an active server in the pool +_RESPONSE_SLEEPTIME = 0.05 # seconds to wait while waiting for a response in asynchronous strategies +_RESPONSE_WAITING_TIMEOUT = 20 # waiting timeout for receiving a response in asynchronous strategies +_SOCKET_SIZE = 4096 # socket byte size +_CHECK_AVAILABILITY_TIMEOUT = 2.5 # default timeout for socket connect when checking availability +_RESET_AVAILABILITY_TIMEOUT = 5 # default timeout for resetting the availability status when checking candidate addresses +_RESTARTABLE_SLEEPTIME = 2 # time to wait in a restartable strategy before retrying the request +_RESTARTABLE_TRIES = 30 # number of times to retry in a restartable strategy before giving up. Set to True for unlimited retries +_REUSABLE_THREADED_POOL_SIZE = 5 +_REUSABLE_THREADED_LIFETIME = 3600 # 1 hour +_DEFAULT_THREADED_POOL_NAME = 'REUSABLE_DEFAULT_POOL' +_ADDRESS_INFO_REFRESH_TIME = 300 # seconds to wait before refreshing address info from dns +_ADDITIONAL_SERVER_ENCODINGS = ['latin-1', 'koi8-r'] # some broken LDAP implementation may have different encoding than those expected by RFCs +_ADDITIONAL_CLIENT_ENCODINGS = ['utf-8'] +_IGNORE_MALFORMED_SCHEMA = False # some flaky LDAP servers returns malformed schema. If True no expection is raised and schema is thrown away +_DEFAULT_SERVER_ENCODING = 'utf-8' # should always be utf-8 +_LDIF_LINE_LENGTH = 78 # as stated in RFC 2849 + +if stdin and hasattr(stdin, 'encoding') and stdin.encoding: + _DEFAULT_CLIENT_ENCODING = stdin.encoding +elif getdefaultencoding(): + _DEFAULT_CLIENT_ENCODING = getdefaultencoding() +else: + _DEFAULT_CLIENT_ENCODING = 'utf-8' + +PARAMETERS = ['CASE_INSENSITIVE_ATTRIBUTE_NAMES', + 'CASE_INSENSITIVE_SCHEMA_NAMES', + 'ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX', + 'POOLING_LOOP_TIMEOUT', + 'RESPONSE_SLEEPTIME', + 'RESPONSE_WAITING_TIMEOUT', + 'SOCKET_SIZE', + 'CHECK_AVAILABILITY_TIMEOUT', + 'RESTARTABLE_SLEEPTIME', + 'RESTARTABLE_TRIES', + 'REUSABLE_THREADED_POOL_SIZE', + 'REUSABLE_THREADED_LIFETIME', + 'DEFAULT_THREADED_POOL_NAME', + 'ADDRESS_INFO_REFRESH_TIME', + 'RESET_AVAILABILITY_TIMEOUT', + 'DEFAULT_CLIENT_ENCODING', + 'DEFAULT_SERVER_ENCODING', + 'CLASSES_EXCLUDED_FROM_CHECK', + 'ATTRIBUTES_EXCLUDED_FROM_CHECK', + 'UTF8_ENCODED_SYNTAXES', + 'UTF8_ENCODED_TYPES', + 'ADDITIONAL_SERVER_ENCODINGS', + 'ADDITIONAL_CLIENT_ENCODINGS', + 'IGNORE_MALFORMED_SCHEMA', + 'ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF', + 'IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF', + 'LDIF_LINE_LENGTH' + ] + + +def get_config_parameter(parameter): + if parameter == 'CASE_INSENSITIVE_ATTRIBUTE_NAMES': # Boolean + return _CASE_INSENSITIVE_ATTRIBUTE_NAMES + elif parameter == 'CASE_INSENSITIVE_SCHEMA_NAMES': # Boolean + return _CASE_INSENSITIVE_SCHEMA_NAMES + elif parameter == 'ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX': # String + return _ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX + elif parameter == 'POOLING_LOOP_TIMEOUT': # Integer + return _POOLING_LOOP_TIMEOUT + elif parameter == 'RESPONSE_SLEEPTIME': # Integer + return _RESPONSE_SLEEPTIME + elif parameter == 'RESPONSE_WAITING_TIMEOUT': # Integer + return _RESPONSE_WAITING_TIMEOUT + elif parameter == 'SOCKET_SIZE': # Integer + return _SOCKET_SIZE + elif parameter == 'CHECK_AVAILABILITY_TIMEOUT': # Integer + return _CHECK_AVAILABILITY_TIMEOUT + elif parameter == 'RESTARTABLE_SLEEPTIME': # Integer + return _RESTARTABLE_SLEEPTIME + elif parameter == 'RESTARTABLE_TRIES': # Integer + return _RESTARTABLE_TRIES + elif parameter == 'REUSABLE_THREADED_POOL_SIZE': # Integer + return _REUSABLE_THREADED_POOL_SIZE + elif parameter == 'REUSABLE_THREADED_LIFETIME': # Integer + return _REUSABLE_THREADED_LIFETIME + elif parameter == 'DEFAULT_THREADED_POOL_NAME': # String + return _DEFAULT_THREADED_POOL_NAME + elif parameter == 'ADDRESS_INFO_REFRESH_TIME': # Integer + return _ADDRESS_INFO_REFRESH_TIME + elif parameter == 'RESET_AVAILABILITY_TIMEOUT': # Integer + return _RESET_AVAILABILITY_TIMEOUT + elif parameter in ['DEFAULT_CLIENT_ENCODING', 'DEFAULT_ENCODING']: # String - DEFAULT_ENCODING for backward compatibility + return _DEFAULT_CLIENT_ENCODING + elif parameter == 'DEFAULT_SERVER_ENCODING': # String + return _DEFAULT_SERVER_ENCODING + elif parameter == 'CLASSES_EXCLUDED_FROM_CHECK': # Sequence + if isinstance(_CLASSES_EXCLUDED_FROM_CHECK, SEQUENCE_TYPES): + return _CLASSES_EXCLUDED_FROM_CHECK + else: + return [_CLASSES_EXCLUDED_FROM_CHECK] + elif parameter == 'ATTRIBUTES_EXCLUDED_FROM_CHECK': # Sequence + if isinstance(_ATTRIBUTES_EXCLUDED_FROM_CHECK, SEQUENCE_TYPES): + return _ATTRIBUTES_EXCLUDED_FROM_CHECK + else: + return [_ATTRIBUTES_EXCLUDED_FROM_CHECK] + elif parameter == 'UTF8_ENCODED_SYNTAXES': # Sequence + if isinstance(_UTF8_ENCODED_SYNTAXES, SEQUENCE_TYPES): + return _UTF8_ENCODED_SYNTAXES + else: + return [_UTF8_ENCODED_SYNTAXES] + elif parameter == 'UTF8_ENCODED_TYPES': # Sequence + if isinstance(_UTF8_ENCODED_TYPES, SEQUENCE_TYPES): + return _UTF8_ENCODED_TYPES + else: + return [_UTF8_ENCODED_TYPES] + elif parameter in ['ADDITIONAL_SERVER_ENCODINGS', 'ADDITIONAL_ENCODINGS']: # Sequence - ADDITIONAL_ENCODINGS for backward compatibility + if isinstance(_ADDITIONAL_SERVER_ENCODINGS, SEQUENCE_TYPES): + return _ADDITIONAL_SERVER_ENCODINGS + else: + return [_ADDITIONAL_SERVER_ENCODINGS] + elif parameter in ['ADDITIONAL_CLIENT_ENCODINGS']: # Sequence + if isinstance(_ADDITIONAL_CLIENT_ENCODINGS, SEQUENCE_TYPES): + return _ADDITIONAL_CLIENT_ENCODINGS + else: + return [_ADDITIONAL_CLIENT_ENCODINGS] + elif parameter == 'IGNORE_MALFORMED_SCHEMA': # Boolean + return _IGNORE_MALFORMED_SCHEMA + elif parameter == 'ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF': # Sequence + if isinstance(_ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF, SEQUENCE_TYPES): + return _ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF + else: + return [_ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF] + elif parameter == 'IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF': # Sequence + if isinstance(_IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF, SEQUENCE_TYPES): + return _IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF + else: + return [_IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF] + elif parameter == 'LDIF_LINE_LENGTH': # Integer + return _LDIF_LINE_LENGTH + + raise LDAPConfigurationParameterError('configuration parameter %s not valid' % parameter) + + +def set_config_parameter(parameter, value): + if parameter == 'CASE_INSENSITIVE_ATTRIBUTE_NAMES': + global _CASE_INSENSITIVE_ATTRIBUTE_NAMES + _CASE_INSENSITIVE_ATTRIBUTE_NAMES = value + elif parameter == 'CASE_INSENSITIVE_SCHEMA_NAMES': + global _CASE_INSENSITIVE_SCHEMA_NAMES + _CASE_INSENSITIVE_SCHEMA_NAMES = value + elif parameter == 'ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX': + global _ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX + _ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX = value + elif parameter == 'POOLING_LOOP_TIMEOUT': + global _POOLING_LOOP_TIMEOUT + _POOLING_LOOP_TIMEOUT = value + elif parameter == 'RESPONSE_SLEEPTIME': + global _RESPONSE_SLEEPTIME + _RESPONSE_SLEEPTIME = value + elif parameter == 'RESPONSE_WAITING_TIMEOUT': + global _RESPONSE_WAITING_TIMEOUT + _RESPONSE_WAITING_TIMEOUT = value + elif parameter == 'SOCKET_SIZE': + global _SOCKET_SIZE + _SOCKET_SIZE = value + elif parameter == 'CHECK_AVAILABILITY_TIMEOUT': + global _CHECK_AVAILABILITY_TIMEOUT + _CHECK_AVAILABILITY_TIMEOUT = value + elif parameter == 'RESTARTABLE_SLEEPTIME': + global _RESTARTABLE_SLEEPTIME + _RESTARTABLE_SLEEPTIME = value + elif parameter == 'RESTARTABLE_TRIES': + global _RESTARTABLE_TRIES + _RESTARTABLE_TRIES = value + elif parameter == 'REUSABLE_THREADED_POOL_SIZE': + global _REUSABLE_THREADED_POOL_SIZE + _REUSABLE_THREADED_POOL_SIZE = value + elif parameter == 'REUSABLE_THREADED_LIFETIME': + global _REUSABLE_THREADED_LIFETIME + _REUSABLE_THREADED_LIFETIME = value + elif parameter == 'DEFAULT_THREADED_POOL_NAME': + global _DEFAULT_THREADED_POOL_NAME + _DEFAULT_THREADED_POOL_NAME = value + elif parameter == 'ADDRESS_INFO_REFRESH_TIME': + global _ADDRESS_INFO_REFRESH_TIME + _ADDRESS_INFO_REFRESH_TIME = value + elif parameter == 'RESET_AVAILABILITY_TIMEOUT': + global _RESET_AVAILABILITY_TIMEOUT + _RESET_AVAILABILITY_TIMEOUT = value + elif parameter in ['DEFAULT_CLIENT_ENCODING', 'DEFAULT_ENCODING']: + global _DEFAULT_CLIENT_ENCODING + _DEFAULT_CLIENT_ENCODING = value + elif parameter == 'DEFAULT_SERVER_ENCODING': + global _DEFAULT_SERVER_ENCODING + _DEFAULT_SERVER_ENCODING = value + elif parameter == 'CLASSES_EXCLUDED_FROM_CHECK': + global _CLASSES_EXCLUDED_FROM_CHECK + _CLASSES_EXCLUDED_FROM_CHECK = value + elif parameter == 'ATTRIBUTES_EXCLUDED_FROM_CHECK': + global _ATTRIBUTES_EXCLUDED_FROM_CHECK + _ATTRIBUTES_EXCLUDED_FROM_CHECK = value + elif parameter == 'UTF8_ENCODED_SYNTAXES': + global _UTF8_ENCODED_SYNTAXES + _UTF8_ENCODED_SYNTAXES = value + elif parameter == 'UTF8_ENCODED_TYPES': + global _UTF8_ENCODED_TYPES + _UTF8_ENCODED_TYPES = value + elif parameter in ['ADDITIONAL_SERVER_ENCODINGS', 'ADDITIONAL_ENCODINGS']: + global _ADDITIONAL_SERVER_ENCODINGS + _ADDITIONAL_SERVER_ENCODINGS = value if isinstance(value, SEQUENCE_TYPES) else [value] + elif parameter in ['ADDITIONAL_CLIENT_ENCODINGS']: + global _ADDITIONAL_CLIENT_ENCODINGS + _ADDITIONAL_CLIENT_ENCODINGS = value if isinstance(value, SEQUENCE_TYPES) else [value] + elif parameter == 'IGNORE_MALFORMED_SCHEMA': + global _IGNORE_MALFORMED_SCHEMA + _IGNORE_MALFORMED_SCHEMA = value + elif parameter == 'ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF': + global _ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF + _ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF = value + elif parameter == 'IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF': + global _IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF + _IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF = value + elif parameter == 'LDIF_LINE_LENGTH': + global _LDIF_LINE_LENGTH + _LDIF_LINE_LENGTH = value + else: + raise LDAPConfigurationParameterError('unable to set configuration parameter %s' % parameter) diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/conv.py b/plugins/ldap-user-sync/vendor/ldap3/utils/conv.py new file mode 100644 index 00000000..514faadf --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/conv.py @@ -0,0 +1,272 @@ +""" +""" + +# Created on 2014.04.26 +# +# 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 . + +from base64 import b64encode, b64decode +import datetime +import re + +from .. import SEQUENCE_TYPES, STRING_TYPES, NUMERIC_TYPES, get_config_parameter +from ..utils.ciDict import CaseInsensitiveDict +from ..core.exceptions import LDAPDefinitionError + + +def to_unicode(obj, encoding=None, from_server=False): + """Try to convert bytes (and str in python2) to unicode. + Return object unmodified if python3 string, else raise an exception + """ + conf_default_client_encoding = get_config_parameter('DEFAULT_CLIENT_ENCODING') + conf_default_server_encoding = get_config_parameter('DEFAULT_SERVER_ENCODING') + conf_additional_server_encodings = get_config_parameter('ADDITIONAL_SERVER_ENCODINGS') + conf_additional_client_encodings = get_config_parameter('ADDITIONAL_CLIENT_ENCODINGS') + if isinstance(obj, NUMERIC_TYPES): + obj = str(obj) + + if isinstance(obj, (bytes, bytearray)): + if from_server: # data from server + if encoding is None: + encoding = conf_default_server_encoding + try: + return obj.decode(encoding) + except UnicodeDecodeError: + for encoding in conf_additional_server_encodings: # AD could have DN not encoded in utf-8 (even if this is not allowed by RFC4510) + try: + return obj.decode(encoding) + except UnicodeDecodeError: + pass + raise UnicodeError("Unable to convert server data to unicode: %r" % obj) + else: # data from client + if encoding is None: + encoding = conf_default_client_encoding + try: + return obj.decode(encoding) + except UnicodeDecodeError: + for encoding in conf_additional_client_encodings: # tries additional encodings + try: + return obj.decode(encoding) + except UnicodeDecodeError: + pass + raise UnicodeError("Unable to convert client data to unicode: %r" % obj) + + if isinstance(obj, STRING_TYPES): # python3 strings, python 2 unicode + return obj + + raise UnicodeError("Unable to convert type %s to unicode: %r" % (obj.__class__.__name__, obj)) + + +def to_raw(obj, encoding='utf-8'): + """Tries to convert to raw bytes from unicode""" + if isinstance(obj, NUMERIC_TYPES): + obj = str(obj) + + if not (isinstance(obj, bytes)): + if isinstance(obj, SEQUENCE_TYPES): + return [to_raw(element) for element in obj] + elif isinstance(obj, STRING_TYPES): + return obj.encode(encoding) + return obj + + +def escape_filter_chars(text, encoding=None): + """ Escape chars mentioned in RFC4515. """ + if encoding is None: + encoding = get_config_parameter('DEFAULT_ENCODING') + + try: + text = to_unicode(text, encoding) + escaped = text.replace('\\', '\\5c') + escaped = escaped.replace('*', '\\2a') + escaped = escaped.replace('(', '\\28') + escaped = escaped.replace(')', '\\29') + escaped = escaped.replace('\x00', '\\00') + except Exception: # probably raw bytes values, return escaped bytes value + escaped = to_unicode(escape_bytes(text)) + # escape all octets greater than 0x7F that are not part of a valid UTF-8 + # escaped = ''.join(c if c <= ord(b'\x7f') else escape_bytes(to_raw(to_unicode(c, encoding))) for c in escaped) + return escaped + + +def unescape_filter_chars(text, encoding=None): + """ unescape chars mentioned in RFC4515. """ + if encoding is None: + encoding = get_config_parameter('DEFAULT_ENCODING') + + unescaped = to_raw(text, encoding) + unescaped = unescaped.replace(b'\\5c', b'\\') + unescaped = unescaped.replace(b'\\5C', b'\\') + unescaped = unescaped.replace(b'\\2a', b'*') + unescaped = unescaped.replace(b'\\2A', b'*') + unescaped = unescaped.replace(b'\\28', b'(') + unescaped = unescaped.replace(b'\\29', b')') + unescaped = unescaped.replace(b'\\00', b'\x00') + return unescaped + + +def escape_bytes(bytes_value): + """ Convert a byte sequence to a properly escaped for LDAP (format BACKSLASH HEX HEX) string""" + if bytes_value: + if str is not bytes: # Python 3 + if isinstance(bytes_value, str): + bytes_value = bytearray(bytes_value, encoding='utf-8') + escaped = '\\'.join([('%02x' % int(b)) for b in bytes_value]) + else: # Python 2 + if isinstance(bytes_value, unicode): + bytes_value = bytes_value.encode('utf-8') + escaped = '\\'.join([('%02x' % ord(b)) for b in bytes_value]) + else: + escaped = '' + + return ('\\' + escaped) if escaped else '' + + +def prepare_for_stream(value): + if str is not bytes: # Python 3 + return value + else: # Python 2 + return value.decode() + + +def json_encode_b64(obj): + try: + return dict(encoding='base64', encoded=b64encode(obj)) + except Exception as e: + raise LDAPDefinitionError('unable to encode ' + str(obj) + ' - ' + str(e)) + + +# noinspection PyProtectedMember +def check_json_dict(json_dict): + # needed for python 2 + + for k, v in json_dict.items(): + if isinstance(v, dict): + check_json_dict(v) + elif isinstance(v, CaseInsensitiveDict): + check_json_dict(v._store) + elif isinstance(v, SEQUENCE_TYPES): + for i, e in enumerate(v): + if isinstance(e, dict): + check_json_dict(e) + elif isinstance(e, CaseInsensitiveDict): + check_json_dict(e._store) + else: + v[i] = format_json(e) + else: + json_dict[k] = format_json(v) + + +def json_hook(obj): + if hasattr(obj, 'keys') and len(list(obj.keys())) == 2 and 'encoding' in obj.keys() and 'encoded' in obj.keys(): + return b64decode(obj['encoded']) + + return obj + + +# noinspection PyProtectedMember +def format_json(obj, iso_format=False): + if isinstance(obj, CaseInsensitiveDict): + return obj._store + + if isinstance(obj, datetime.datetime): + return str(obj) + + if isinstance(obj, int): + return obj + + if isinstance(obj, datetime.timedelta): + if iso_format: + return obj.isoformat() + return str(obj) + + if str is bytes: # Python 2 + if isinstance(obj, long): # long exists only in python2 + return obj + + try: + if str is not bytes: # Python 3 + if isinstance(obj, bytes): + # return check_escape(str(obj, 'utf-8', errors='strict')) + return str(obj, 'utf-8', errors='strict') + raise LDAPDefinitionError('unable to serialize ' + str(obj)) + else: # Python 2 + if isinstance(obj, unicode): + return obj + else: + # return unicode(check_escape(obj)) + return unicode(obj) + except (TypeError, UnicodeDecodeError): + pass + + try: + return json_encode_b64(bytes(obj)) + except Exception: + pass + + raise LDAPDefinitionError('unable to serialize ' + str(obj)) + + +def is_filter_escaped(text): + if not type(text) == ((str is not bytes) and str or unicode): # requires str for Python 3 and unicode for Python 2 + raise ValueError('unicode input expected') + + return all(c not in text for c in '()*\0') and not re.search('\\\\([^0-9a-fA-F]|(.[^0-9a-fA-F]))', text) + + +def ldap_escape_to_bytes(text): + bytesequence = bytearray() + i = 0 + try: + if isinstance(text, STRING_TYPES): + while i < len(text): + if text[i] == '\\': + if len(text) > i + 2: + try: + bytesequence.append(int(text[i+1:i+3], 16)) + i += 3 + continue + except ValueError: + pass + bytesequence.append(92) # "\" ASCII code + else: + raw = to_raw(text[i]) + for c in raw: + bytesequence.append(c) + i += 1 + elif isinstance(text, (bytes, bytearray)): + while i < len(text): + if text[i] == 92: # "\" ASCII code + if len(text) > i + 2: + try: + bytesequence.append(int(text[i + 1:i + 3], 16)) + i += 3 + continue + except ValueError: + pass + bytesequence.append(92) # "\" ASCII code + else: + bytesequence.append(text[i]) + i += 1 + except Exception: + raise LDAPDefinitionError('badly formatted LDAP byte escaped sequence') + + return bytes(bytesequence) diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/dn.py b/plugins/ldap-user-sync/vendor/ldap3/utils/dn.py new file mode 100644 index 00000000..c2a1e66a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/dn.py @@ -0,0 +1,405 @@ +""" +""" + +# Created on 2014.09.08 +# +# 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 . + +from string import hexdigits, ascii_letters, digits + +from .. import SEQUENCE_TYPES +from ..core.exceptions import LDAPInvalidDnError + + +STATE_ANY = 0 +STATE_ESCAPE = 1 +STATE_ESCAPE_HEX = 2 + + +def _add_ava(ava, decompose, remove_space, space_around_equal): + if not ava: + return '' + + space = ' ' if space_around_equal else '' + attr_name, _, value = ava.partition('=') + if decompose: + if remove_space: + component = (attr_name.strip(), value.strip()) + else: + component = (attr_name, value) + else: + if remove_space: + component = attr_name.strip() + space + '=' + space + value.strip() + else: + component = attr_name + space + '=' + space + value + + return component + + +def to_dn(iterator, decompose=False, remove_space=False, space_around_equal=False, separate_rdn=False): + """ + Convert an iterator to a list of dn parts + if decompose=True return a list of tuple (one for each dn component) else return a list of strings + if remove_space=True removes unneeded spaces + if space_around_equal=True add spaces around equal in returned strings + if separate_rdn=True consider multiple RDNs as different component of DN + """ + dn = [] + component = '' + escape_sequence = False + for c in iterator: + if c == '\\': # escape sequence + escape_sequence = True + elif escape_sequence and c != ' ': + escape_sequence = False + elif c == '+' and separate_rdn: + dn.append(_add_ava(component, decompose, remove_space, space_around_equal)) + component = '' + continue + elif c == ',': + if '=' in component: + dn.append(_add_ava(component, decompose, remove_space, space_around_equal)) + component = '' + continue + + component += c + + dn.append(_add_ava(component, decompose, remove_space, space_around_equal)) + return dn + + +def _find_first_unescaped(dn, char, pos): + while True: + pos = dn.find(char, pos) + if pos == -1: + break # no char found + if pos > 0 and dn[pos - 1] != '\\': # unescaped char + break + elif pos > 1 and dn[pos - 1] == '\\': # may be unescaped + escaped = True + for c in dn[pos - 2:0:-1]: + if c == '\\': + escaped = not escaped + else: + break + if not escaped: + break + pos += 1 + + return pos + + +def _find_last_unescaped(dn, char, start, stop=0): + while True: + stop = dn.rfind(char, start, stop) + if stop == -1: + break + if stop >= 0 and dn[stop - 1] != '\\': + break + elif stop > 1 and dn[stop - 1] == '\\': # may be unescaped + escaped = True + for c in dn[stop - 2:0:-1]: + if c == '\\': + escaped = not escaped + else: + break + if not escaped: + break + if stop < start: + stop = -1 + break + + return stop + + +def _get_next_ava(dn): + comma = _find_first_unescaped(dn, ',', 0) + plus = _find_first_unescaped(dn, '+', 0) + + if plus > 0 and (plus < comma or comma == -1): + equal = _find_first_unescaped(dn, '=', plus + 1) + if equal > plus + 1: + plus = _find_last_unescaped(dn, '+', plus, equal) + return dn[:plus], '+' + + if comma > 0: + equal = _find_first_unescaped(dn, '=', comma + 1) + if equal > comma + 1: + comma = _find_last_unescaped(dn, ',', comma, equal) + return dn[:comma], ',' + + return dn, '' + + +def _split_ava(ava, escape=False, strip=True): + equal = ava.find('=') + while equal > 0: # not first character + if ava[equal - 1] != '\\': # not an escaped equal so it must be an ava separator + # attribute_type1 = ava[0:equal].strip() if strip else ava[0:equal] + if strip: + attribute_type = ava[0:equal].strip() + attribute_value = _escape_attribute_value(ava[equal + 1:].strip()) if escape else ava[equal + 1:].strip() + else: + attribute_type = ava[0:equal] + attribute_value = _escape_attribute_value(ava[equal + 1:]) if escape else ava[equal + 1:] + + return attribute_type, attribute_value + equal = ava.find('=', equal + 1) + + return '', (ava.strip if strip else ava) # if no equal found return only value + + +def _validate_attribute_type(attribute_type): + if not attribute_type: + raise LDAPInvalidDnError('attribute type not present') + + if attribute_type == ' pairs') + if attribute_value[0] == ' ': # unescaped space cannot be used as leading or last character + raise LDAPInvalidDnError('SPACE must be escaped as leading character of attribute value') + if attribute_value.endswith(' ') and not attribute_value.endswith('\\ '): + raise LDAPInvalidDnError('SPACE must be escaped as trailing character of attribute value') + + state = STATE_ANY + for c in attribute_value: + if state == STATE_ANY: + if c == '\\': + state = STATE_ESCAPE + elif c in '"#+,;<=>\00': + raise LDAPInvalidDnError('special character ' + c + ' must be escaped') + elif state == STATE_ESCAPE: + if c in hexdigits: + state = STATE_ESCAPE_HEX + elif c in ' "#+,;<=>\\\00': + state = STATE_ANY + else: + raise LDAPInvalidDnError('invalid escaped character ' + c) + elif state == STATE_ESCAPE_HEX: + if c in hexdigits: + state = STATE_ANY + else: + raise LDAPInvalidDnError('invalid escaped character ' + c) + + # final state + if state != STATE_ANY: + raise LDAPInvalidDnError('invalid final character') + + return True + + +def _escape_attribute_value(attribute_value): + if not attribute_value: + return '' + + if attribute_value[0] == '#': # with leading SHARP only pairs of hex characters are valid + valid_hex = True + if len(attribute_value) % 2 == 0: # string must be # + HEX HEX (an odd number of chars) + valid_hex = False + + if valid_hex: + for c in attribute_value: + if c not in hexdigits: # allowed only hex digits as per RFC 4514 + valid_hex = False + break + + if valid_hex: + return attribute_value + + state = STATE_ANY + escaped = '' + tmp_buffer = '' + for c in attribute_value: + if state == STATE_ANY: + if c == '\\': + state = STATE_ESCAPE + elif c in '"#+,;<=>\00': + escaped += '\\' + c + else: + escaped += c + elif state == STATE_ESCAPE: + if c in hexdigits: + tmp_buffer = c + state = STATE_ESCAPE_HEX + elif c in ' "#+,;<=>\\\00': + escaped += '\\' + c + state = STATE_ANY + else: + escaped += '\\\\' + c + elif state == STATE_ESCAPE_HEX: + if c in hexdigits: + escaped += '\\' + tmp_buffer + c + else: + escaped += '\\\\' + tmp_buffer + c + tmp_buffer = '' + state = STATE_ANY + + # final state + if state == STATE_ESCAPE: + escaped += '\\\\' + elif state == STATE_ESCAPE_HEX: + escaped += '\\\\' + tmp_buffer + + if escaped[0] == ' ': # leading SPACE must be escaped + escaped = '\\' + escaped + + if escaped[-1] == ' ' and len(escaped) > 1 and escaped[-2] != '\\': # trailing SPACE must be escaped + escaped = escaped[:-1] + '\\ ' + + return escaped + + +def parse_dn(dn, escape=False, strip=False): + """ + Parses a DN into syntactic components + :param dn: + :param escape: + :param strip: + :return: + a list of tripels representing `attributeTypeAndValue` elements + containing `attributeType`, `attributeValue` and the following separator (`COMMA` or `PLUS`) if given, else an empty `str`. + in their original representation, still containing escapes or encoded as hex. + """ + rdns = [] + avas = [] + while dn: + ava, separator = _get_next_ava(dn) # if returned ava doesn't containg any unescaped equal it'a appended to last ava in avas + + dn = dn[len(ava) + 1:] + if _find_first_unescaped(ava, '=', 0) > 0 or len(avas) == 0: + avas.append((ava, separator)) + else: + avas[len(avas) - 1] = (avas[len(avas) - 1][0] + avas[len(avas) - 1][1] + ava, separator) + + for ava, separator in avas: + attribute_type, attribute_value = _split_ava(ava, escape, strip) + + if not _validate_attribute_type(attribute_type): + raise LDAPInvalidDnError('unable to validate attribute type in ' + ava) + + if not _validate_attribute_value(attribute_value): + raise LDAPInvalidDnError('unable to validate attribute value in ' + ava) + + rdns.append((attribute_type, attribute_value, separator)) + dn = dn[len(ava) + 1:] + + if not rdns: + raise LDAPInvalidDnError('empty dn') + + return rdns + + +def safe_dn(dn, decompose=False, reverse=False): + """ + normalize and escape a dn, if dn is a sequence it is joined. + the reverse parameter changes the join direction of the sequence + """ + if isinstance(dn, SEQUENCE_TYPES): + components = [rdn for rdn in dn] + if reverse: + dn = ','.join(reversed(components)) + else: + dn = ','.join(components) + if decompose: + escaped_dn = [] + else: + escaped_dn = '' + + if dn.startswith(''): # Active Directory allows looking up objects by putting its GUID in a specially-formatted DN (e.g. '') + escaped_dn = dn + elif dn.startswith(''): # Active Directory allows Binding to Well-Known Objects Using WKGUID in a specially-formatted DN (e.g. ) + escaped_dn = dn + elif dn.startswith(''): # Active Directory allows looking up objects by putting its security identifier (SID) in a specially-formatted DN (e.g. '') + escaped_dn = dn + elif '@' not in dn: # active directory UPN (User Principal Name) consist of an account, the at sign (@) and a domain, or the domain level logn name domain\username + for component in parse_dn(dn, escape=True): + if decompose: + escaped_dn.append((component[0], component[1], component[2])) + else: + escaped_dn += component[0] + '=' + component[1] + component[2] + elif '@' in dn and '=' not in dn and len(dn.split('@')) != 2: + raise LDAPInvalidDnError('Active Directory User Principal Name must consist of name@domain') + elif '\\' in dn and '=' not in dn and len(dn.split('\\')) != 2: + raise LDAPInvalidDnError('Active Directory Domain Level Logon Name must consist of name\\domain') + else: + escaped_dn = dn + + return escaped_dn + + +def safe_rdn(dn, decompose=False): + """Returns a list of rdn for the dn, usually there is only one rdn, but it can be more than one when the + sign is used""" + escaped_rdn = [] + one_more = True + for component in parse_dn(dn, escape=True): + if component[2] == '+' or one_more: + if decompose: + escaped_rdn.append((component[0], component[1])) + else: + escaped_rdn.append(component[0] + '=' + component[1]) + if component[2] == '+': + one_more = True + else: + one_more = False + break + + if one_more: + raise LDAPInvalidDnError('bad dn ' + str(dn)) + + return escaped_rdn + + +def escape_rdn(rdn): + """ + Escape rdn characters to prevent injection according to RFC 4514. + """ + + # '/' must be handled first or the escape slashes will be escaped! + for char in ['\\', ',', '+', '"', '<', '>', ';', '=', '\x00']: + rdn = rdn.replace(char, '\\' + char) + + if rdn[0] == '#' or rdn[0] == ' ': + rdn = ''.join(('\\', rdn)) + + if rdn[-1] == ' ': + rdn = ''.join((rdn[:-1], '\\ ')) + + return rdn diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/hashed.py b/plugins/ldap-user-sync/vendor/ldap3/utils/hashed.py new file mode 100644 index 00000000..b80a27ab --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/hashed.py @@ -0,0 +1,94 @@ +""" +""" + +# Created on 2015.07.16 +# +# 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 . + +from .. import HASHED_NONE, HASHED_MD5, HASHED_SALTED_MD5, HASHED_SALTED_SHA, HASHED_SALTED_SHA256, \ + HASHED_SALTED_SHA384, HASHED_SALTED_SHA512, HASHED_SHA, HASHED_SHA256, HASHED_SHA384, HASHED_SHA512 + +import hashlib +from os import urandom +from base64 import b64encode + +from ..core.exceptions import LDAPInvalidHashAlgorithmError + +# each tuple: (the string to include between braces in the digest, the name of the algorithm to invoke with the new() function) + +algorithms_table = { + HASHED_MD5: ('md5', 'MD5'), + HASHED_SHA: ('sha', 'SHA1'), + HASHED_SHA256: ('sha256', 'SHA256'), + HASHED_SHA384: ('sha384', 'SHA384'), + HASHED_SHA512: ('sha512', 'SHA512') +} + + +salted_table = { + HASHED_SALTED_MD5: ('smd5', HASHED_MD5), + HASHED_SALTED_SHA: ('ssha', HASHED_SHA), + HASHED_SALTED_SHA256: ('ssha256', HASHED_SHA256), + HASHED_SALTED_SHA384: ('ssha384', HASHED_SHA384), + HASHED_SALTED_SHA512: ('ssha512', HASHED_SHA512) +} + + +def hashed(algorithm, value, salt=None, raw=False, encoding='utf-8'): + if str is not bytes and not isinstance(value, bytes): # Python 3 + value = value.encode(encoding) + + if algorithm is None or algorithm == HASHED_NONE: + return value + + # algorithm name can be already coded in the ldap3 constants or can be any value passed in the 'algorithm' parameter + + if algorithm in algorithms_table: + try: + digest = hashlib.new(algorithms_table[algorithm][1], value).digest() + except ValueError: + raise LDAPInvalidHashAlgorithmError('Hash algorithm ' + str(algorithm) + ' not available') + + if raw: + return digest + return ('{%s}' % algorithms_table[algorithm][0]) + b64encode(digest).decode('ascii') + elif algorithm in salted_table: + if not salt: + salt = urandom(8) + digest = hashed(salted_table[algorithm][1], value + salt, raw=True) + salt + if raw: + return digest + return ('{%s}' % salted_table[algorithm][0]) + b64encode(digest).decode('ascii') + else: + # if an unknown (to the library) algorithm is requested passes the name as the string in braces and as the algorithm name + # if salt is present uses it to salt the digest + try: + if not salt: + digest = hashlib.new(algorithm, value).digest() + else: + digest = hashlib.new(algorithm, value + salt).digest() + salt + except ValueError: + raise LDAPInvalidHashAlgorithmError('Hash algorithm ' + str(algorithm) + ' not available') + + if raw: + return digest + return ('{%s}' % algorithm) + b64encode(digest).decode('ascii') + diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/log.py b/plugins/ldap-user-sync/vendor/ldap3/utils/log.py new file mode 100644 index 00000000..d7f89e22 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/log.py @@ -0,0 +1,216 @@ +""" +""" + +# Created on 2015.05.01 +# +# 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 . + +from logging import getLogger, DEBUG +from copy import deepcopy +from pprint import pformat +from ..protocol.rfc4511 import LDAPMessage + +# logging levels +OFF = 0 +ERROR = 10 +BASIC = 20 +PROTOCOL = 30 +NETWORK = 40 +EXTENDED = 50 + +_sensitive_lines = ('simple', 'credentials', 'serversaslcreds') # must be a tuple, not a list, lowercase +_sensitive_args = ('simple', 'password', 'sasl_credentials', 'saslcreds', 'server_creds') +_sensitive_attrs = ('userpassword', 'unicodepwd') + +_hide_sensitive_data = None + +DETAIL_LEVELS = [OFF, ERROR, BASIC, PROTOCOL, NETWORK, EXTENDED] + +_max_line_length = 4096 +_logging_level = 0 +_detail_level = 0 +_logging_encoding = 'ascii' + +try: + from logging import NullHandler +except ImportError: # NullHandler not present in Python < 2.7 + from logging import Handler + + class NullHandler(Handler): + def handle(self, record): + pass + + def emit(self, record): + pass + + def createLock(self): + self.lock = None + + +def _strip_sensitive_data_from_dict(d): + if not isinstance(d, dict): + return d + + try: + d = deepcopy(d) + except Exception: # if deepcopy goes wrong gives up and returns the dict unchanged + return d + for k in d.keys(): + if isinstance(d[k], dict): + d[k] = _strip_sensitive_data_from_dict(d[k]) + elif k.lower() in _sensitive_args and d[k]: + d[k] = '' % len(d[k]) + + return d + + +def get_detail_level_name(level_name): + if level_name == OFF: + return 'OFF' + elif level_name == ERROR: + return 'ERROR' + elif level_name == BASIC: + return 'BASIC' + elif level_name == PROTOCOL: + return 'PROTOCOL' + elif level_name == NETWORK: + return 'NETWORK' + elif level_name == EXTENDED: + return 'EXTENDED' + raise ValueError('unknown detail level') + + +def log(detail, message, *args): + if detail <= _detail_level: + if _hide_sensitive_data: + args = tuple([_strip_sensitive_data_from_dict(arg) if isinstance(arg, dict) else arg for arg in args]) + + if str is not bytes: # Python 3 + encoded_message = (get_detail_level_name(detail) + ':' + message % args).encode(_logging_encoding, 'backslashreplace') + encoded_message = encoded_message.decode() + else: + try: + encoded_message = (get_detail_level_name(detail) + ':' + message % args).encode(_logging_encoding, 'replace') + except Exception: + encoded_message = (get_detail_level_name(detail) + ':' + message % args).decode(_logging_encoding, 'replace') + + if len(encoded_message) > _max_line_length: + logger.log(_logging_level, encoded_message[:_max_line_length] + ' ' % (len(encoded_message) - _max_line_length, )) + else: + logger.log(_logging_level, encoded_message) + + +def log_enabled(detail): + if detail <= _detail_level: + if logger.isEnabledFor(_logging_level): + return True + + return False + + +def set_library_log_hide_sensitive_data(hide=True): + global _hide_sensitive_data + if hide: + _hide_sensitive_data = True + else: + _hide_sensitive_data = False + if log_enabled(ERROR): + log(ERROR, 'hide sensitive data set to ' + str(_hide_sensitive_data)) + + +def get_library_log_hide_sensitive_data(): + return True if _hide_sensitive_data else False + + +def set_library_log_activation_level(logging_level): + if isinstance(logging_level, int): + global _logging_level + _logging_level = logging_level + else: + if log_enabled(ERROR): + log(ERROR, 'invalid library log activation level <%s> ', logging_level) + raise ValueError('invalid library log activation level') + + +def get_library_log_activation_lavel(): + return _logging_level + + +def set_library_log_max_line_length(length): + if isinstance(length, int): + global _max_line_length + _max_line_length = length + else: + if log_enabled(ERROR): + log(ERROR, 'invalid log max line length <%s> ', length) + raise ValueError('invalid library log max line length') + + +def get_library_log_max_line_length(): + return _max_line_length + + +def set_library_log_detail_level(detail): + if detail in DETAIL_LEVELS: + global _detail_level + _detail_level = detail + if log_enabled(ERROR): + log(ERROR, 'detail level set to ' + get_detail_level_name(_detail_level)) + else: + if log_enabled(ERROR): + log(ERROR, 'unable to set log detail level to <%s>', detail) + raise ValueError('invalid library log detail level') + + +def get_library_log_detail_level(): + return _detail_level + + +def format_ldap_message(message, prefix): + if isinstance(message, LDAPMessage): + try: # pyasn1 prettyprint raises exception in version 0.4.3 + formatted = message.prettyPrint().split('\n') # pyasn1 pretty print + except Exception as e: + formatted = ['pyasn1 exception', str(e)] + else: + formatted = pformat(message).split('\n') + + prefixed = '' + for line in formatted: + if line: + if _hide_sensitive_data and line.strip().lower().startswith(_sensitive_lines): # _sensitive_lines is a tuple. startswith() method checks each tuple element + tag, _, data = line.partition('=') + if data.startswith("b'") and data.endswith("'") or data.startswith('b"') and data.endswith('"'): + prefixed += '\n' + prefix + tag + '=' % (len(data) - 3, ) + else: + prefixed += '\n' + prefix + tag + '=' % len(data) + else: + prefixed += '\n' + prefix + line + return prefixed + +# sets a logger for the library with NullHandler. It can be used by the application with its own logging configuration +logger = getLogger('ldap3') +logger.addHandler(NullHandler()) + +# sets defaults for the library logging +set_library_log_activation_level(DEBUG) +set_library_log_detail_level(OFF) +set_library_log_hide_sensitive_data(True) diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py b/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py new file mode 100644 index 00000000..78a4c19b --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py @@ -0,0 +1,505 @@ +""" +""" + +# Created on 2015.04.02 +# +# 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 . + +# NTLMv2 authentication as per [MS-NLMP] (https://msdn.microsoft.com/en-us/library/cc236621.aspx) + +from struct import pack, unpack +from platform import system, version +from socket import gethostname +from time import time +import hmac +import hashlib +import binascii +from os import urandom + +try: + from locale import getpreferredencoding + oem_encoding = getpreferredencoding() +except Exception: + oem_encoding = 'utf-8' + +from ..protocol.formatters.formatters import format_ad_timestamp + +NTLM_SIGNATURE = b'NTLMSSP\x00' +NTLM_MESSAGE_TYPE_NTLM_NEGOTIATE = 1 +NTLM_MESSAGE_TYPE_NTLM_CHALLENGE = 2 +NTLM_MESSAGE_TYPE_NTLM_AUTHENTICATE = 3 + +FLAG_NEGOTIATE_56 = 31 # W +FLAG_NEGOTIATE_KEY_EXCH = 30 # V +FLAG_NEGOTIATE_128 = 29 # U +FLAG_NEGOTIATE_VERSION = 25 # T +FLAG_NEGOTIATE_TARGET_INFO = 23 # S +FLAG_REQUEST_NOT_NT_SESSION_KEY = 22 # R +FLAG_NEGOTIATE_IDENTIFY = 20 # Q +FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY = 19 # P +FLAG_TARGET_TYPE_SERVER = 17 # O +FLAG_TARGET_TYPE_DOMAIN = 16 # N +FLAG_NEGOTIATE_ALWAYS_SIGN = 15 # M +FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 13 # L +FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 12 # K +FLAG_NEGOTIATE_ANONYMOUS = 11 # J +FLAG_NEGOTIATE_NTLM = 9 # H +FLAG_NEGOTIATE_LM_KEY = 7 # G +FLAG_NEGOTIATE_DATAGRAM = 6 # F +FLAG_NEGOTIATE_SEAL = 5 # E +FLAG_NEGOTIATE_SIGN = 4 # D +FLAG_REQUEST_TARGET = 2 # C +FLAG_NEGOTIATE_OEM = 1 # B +FLAG_NEGOTIATE_UNICODE = 0 # A + +FLAG_TYPES = [FLAG_NEGOTIATE_56, + FLAG_NEGOTIATE_KEY_EXCH, + FLAG_NEGOTIATE_128, + FLAG_NEGOTIATE_VERSION, + FLAG_NEGOTIATE_TARGET_INFO, + FLAG_REQUEST_NOT_NT_SESSION_KEY, + FLAG_NEGOTIATE_IDENTIFY, + FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY, + FLAG_TARGET_TYPE_SERVER, + FLAG_TARGET_TYPE_DOMAIN, + FLAG_NEGOTIATE_ALWAYS_SIGN, + FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, + FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED, + FLAG_NEGOTIATE_ANONYMOUS, + FLAG_NEGOTIATE_NTLM, + FLAG_NEGOTIATE_LM_KEY, + FLAG_NEGOTIATE_DATAGRAM, + FLAG_NEGOTIATE_SEAL, + FLAG_NEGOTIATE_SIGN, + FLAG_REQUEST_TARGET, + FLAG_NEGOTIATE_OEM, + FLAG_NEGOTIATE_UNICODE] + +AV_END_OF_LIST = 0 +AV_NETBIOS_COMPUTER_NAME = 1 +AV_NETBIOS_DOMAIN_NAME = 2 +AV_DNS_COMPUTER_NAME = 3 +AV_DNS_DOMAIN_NAME = 4 +AV_DNS_TREE_NAME = 5 +AV_FLAGS = 6 +AV_TIMESTAMP = 7 +AV_SINGLE_HOST_DATA = 8 +AV_TARGET_NAME = 9 +AV_CHANNEL_BINDINGS = 10 + +AV_TYPES = [AV_END_OF_LIST, + AV_NETBIOS_COMPUTER_NAME, + AV_NETBIOS_DOMAIN_NAME, + AV_DNS_COMPUTER_NAME, + AV_DNS_DOMAIN_NAME, + AV_DNS_TREE_NAME, + AV_FLAGS, + AV_TIMESTAMP, + AV_SINGLE_HOST_DATA, + AV_TARGET_NAME, + AV_CHANNEL_BINDINGS] + +AV_FLAG_CONSTRAINED = 0 +AV_FLAG_INTEGRITY = 1 +AV_FLAG_TARGET_SPN_UNTRUSTED = 2 + +AV_FLAG_TYPES = [AV_FLAG_CONSTRAINED, + AV_FLAG_INTEGRITY, + AV_FLAG_TARGET_SPN_UNTRUSTED] + + +def pack_windows_version(debug=False): + if debug: + if system().lower() == 'windows': + try: + major_release, minor_release, build = version().split('.') + major_release = int(major_release) + minor_release = int(minor_release) + build = int(build) + except Exception: + major_release = 5 + minor_release = 1 + build = 2600 + else: + major_release = 5 + minor_release = 1 + build = 2600 + else: + major_release = 0 + minor_release = 0 + build = 0 + + return pack(' 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__end + except AttributeError: + self.clear() + self.update(*args, **kwds) + + def clear(self): + self.__end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.__map = {} # key --> [key, prev, next] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + end = self.__end + curr = end[1] + curr[2] = end[1] = self.__map[key] = [key, curr, end] + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + key, prev, next = self.__map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.__end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.__end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def popitem(self, last=True): + if not self: + raise KeyError('dictionary is empty') + if last: + key = reversed(self).next() + else: + key = iter(self).next() + value = self.pop(key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__end + del self.__map, self.__end + inst_dict = vars(self).copy() + self.__map, self.__end = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def keys(self): + return list(self) + + setdefault = DictMixin.setdefault + update = DictMixin.update + pop = DictMixin.pop + values = DictMixin.values + items = DictMixin.items + iterkeys = DictMixin.iterkeys + itervalues = DictMixin.itervalues + iteritems = DictMixin.iteritems + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + if len(self) != len(other): + return False + for p, q in zip(self.items(), other.items()): + if p != q: + return False + return True + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/port_validators.py b/plugins/ldap-user-sync/vendor/ldap3/utils/port_validators.py new file mode 100644 index 00000000..c46b752c --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/port_validators.py @@ -0,0 +1,37 @@ +""" Some helper functions for validation of ports and lists of ports. """ + + +def check_port(port): + """ Check if a port is valid. Return an error message indicating what is invalid if something isn't valid. """ + if isinstance(port, int): + if port not in range(0, 65535): + return 'Source port must in range from 0 to 65535' + else: + return 'Source port must be an integer' + return None + + +def check_port_and_port_list(port, port_list): + """ Take in a port and a port list and check that at most one is non-null. Additionally check that if either + is non-null, it is valid. + Return an error message indicating what is invalid if something isn't valid. + """ + if port is not None and port_list is not None: + return 'Cannot specify both a source port and a source port list' + elif port is not None: + if isinstance(port, int): + if port not in range(0, 65535): + return 'Source port must in range from 0 to 65535' + else: + return 'Source port must be an integer' + elif port_list is not None: + try: + _ = iter(port_list) + except TypeError: + return 'Source port list must be an iterable {}'.format(port_list) + + for candidate_port in port_list: + err = check_port(candidate_port) + if err: + return err + return None diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/repr.py b/plugins/ldap-user-sync/vendor/ldap3/utils/repr.py new file mode 100644 index 00000000..19e1a64e --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/repr.py @@ -0,0 +1,51 @@ +""" +""" + +# Created on 2015.07.09 +# +# 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 . +from binascii import hexlify + +from .. import STRING_TYPES + +try: + from sys import stdout + repr_encoding = stdout.encoding # get the encoding of the stdout for printing (repr) + if not repr_encoding: + repr_encoding = 'ascii' # default +except Exception: + repr_encoding = 'ascii' # default + + +def to_stdout_encoding(value): + if not isinstance(value, STRING_TYPES): + value = str(value) + + if str is bytes: # Python 2 + try: + return value.encode(repr_encoding, 'backslashreplace') + except UnicodeDecodeError: # Python 2.6 + return hexlify(value) + else: # Python 3 + try: + return value.encode(repr_encoding, errors='backslashreplace').decode(repr_encoding, errors='backslashreplace') + except UnicodeDecodeError: + return hexlify(value) diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/tls_backport.py b/plugins/ldap-user-sync/vendor/ldap3/utils/tls_backport.py new file mode 100644 index 00000000..dcd1ed71 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/tls_backport.py @@ -0,0 +1,133 @@ +""" +""" + +# Created on 2014.10.05 +# +# 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 . +import re +from ..utils.log import log, log_enabled, NETWORK + +try: + from backports.ssl_match_hostname import match_hostname, CertificateError +except ImportError: + class CertificateError(ValueError): # fix for Python 2, code from Python 3.5 standard library + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Backported from Python 3.4.3 standard library + + Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + if log_enabled(NETWORK): + log(NETWORK, "matching dn %s with hostname %s", dn, hostname) + pats = [] + if not dn: + return False + + pieces = dn.split(r'.') + leftmost = pieces[0] + remainder = pieces[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Backported from Python 3.4.3 standard library. + + Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/uri.py b/plugins/ldap-user-sync/vendor/ldap3/utils/uri.py new file mode 100644 index 00000000..3e566744 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/uri.py @@ -0,0 +1,118 @@ +""" +""" + +# Created on 2014.09.08 +# +# 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 . + +try: + from urllib.parse import unquote # Python3 +except ImportError: + from urllib import unquote # Python 2 + +from .. import SUBTREE, BASE, LEVEL + + +def parse_uri(uri): + """ + Decode LDAP URI as specified in RFC 4516 relaxing specifications + permitting 'ldaps' as scheme for ssl-ldap + """ + + # ldapurl = scheme COLON SLASH SLASH [host [COLON port]] + # [SLASH dn [QUESTION [attributes] + # [QUESTION [scope] [QUESTION [filter] + # [QUESTION extensions]]]]] + # ; and are defined + # ; in Sections 3.2.2 and 3.2.3 + # ; of [RFC3986]. + # ; is from Section 3 of + # ; [RFC4515], subject to the + # ; provisions of the + # ; "Percent-Encoding" section + # ; below. + # + # scheme = "ldap" / "ldaps" <== not RFC4516 compliant (original is 'scheme = "ldap"') + # dn = distinguishedName ; From Section 3 of [RFC4514], + # ; subject to the provisions of + # ; the "Percent-Encoding" + # ; section below. + # + # attributes = attrdesc *(COMMA attrdesc) + # attrdesc = selector *(COMMA selector) + # selector = attributeSelector ; From Section 4.5.1 of + # ; [RFC4511], subject to the + # ; provisions of the + # ; "Percent-Encoding" section + # ; below. + # + # scope = "base" / "one" / "sub" + # extensions = extension *(COMMA extension) + # extension = [EXCLAMATION] extype [EQUALS exvalue] + # extype = oid ; From section 1.4 of [RFC4512]. + # + # exvalue = LDAPString ; From section 4.1.2 of + # ; [RFC4511], subject to the + # ; provisions of the + # ; "Percent-Encoding" section + # ; below. + # + # EXCLAMATION = %x21 ; exclamation mark ("!") + # SLASH = %x2F ; forward slash ("/") + # COLON = %x3A ; colon (":") + # QUESTION = %x3F ; question mark ("?") + + uri_components = dict() + parts = unquote(uri).split('?') # encoding defaults to utf-8 in Python 3 + scheme, sep, remain = parts[0].partition('://') + if sep != '://' or scheme not in ['ldap', 'ldaps']: + return None + + address, _, uri_components['base'] = remain.partition('/') + + uri_components['ssl'] = True if scheme == 'ldaps' else False + uri_components['host'], sep, uri_components['port'] = address.partition(':') + if sep != ':': + if uri_components['ssl']: + uri_components['port'] = 636 + else: + uri_components['port'] = None + else: + if not uri_components['port'].isdigit() or not (0 < int(uri_components['port']) < 65536): + return None + else: + uri_components['port'] = int(uri_components['port']) + + uri_components['attributes'] = parts[1].split(',') if len(parts) > 1 and parts[1] else None + uri_components['scope'] = parts[2] if len(parts) > 2 else None + if uri_components['scope'] == 'base': + uri_components['scope'] = BASE + elif uri_components['scope'] == 'sub': + uri_components['scope'] = SUBTREE + elif uri_components['scope'] == 'one': + uri_components['scope'] = LEVEL + elif uri_components['scope']: + return None + + uri_components['filter'] = parts[3] if len(parts) > 3 else None + uri_components['extensions'] = parts[4].split(',') if len(parts) > 4 else None + + return uri_components diff --git a/plugins/ldap-user-sync/vendor/ldap3/version.py b/plugins/ldap-user-sync/vendor/ldap3/version.py new file mode 100644 index 00000000..d904208f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/version.py @@ -0,0 +1,13 @@ +# THIS FILE IS AUTO-GENERATED. PLEASE DO NOT MODIFY +# version file for ldap3 +# generated on 2021-07-18 08:33:22.864195 +# on system uname_result(system='Windows', node='ELITE10GC', release='10', version='10.0.19041', machine='AMD64') +# with Python 3.9.4 - ('tags/v3.9.4:1f2e308', 'Apr 6 2021 13:40:21') - MSC v.1928 64 bit (AMD64) +# +__version__ = '2.9.1' +__author__ = 'Giovanni Cannata' +__email__ = 'cannatag@gmail.com' +__url__ = 'https://github.com/cannatag/ldap3' +__description__ = 'A strictly RFC 4510 conforming LDAP V3 pure Python client library' +__status__ = '5 - Production/Stable' +__license__ = 'LGPL v3' diff --git a/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.LESSER.txt b/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.LESSER.txt new file mode 100644 index 00000000..02bbb60b --- /dev/null +++ b/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.LESSER.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.txt b/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.txt new file mode 100644 index 00000000..b71395ec --- /dev/null +++ b/plugins/ldap-user-sync/vendor/licenses/ldap3/COPYING.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + _clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/plugins/ldap-user-sync/vendor/licenses/ldap3/LICENSE.txt b/plugins/ldap-user-sync/vendor/licenses/ldap3/LICENSE.txt new file mode 100644 index 00000000..ace144d7 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/licenses/ldap3/LICENSE.txt @@ -0,0 +1,13 @@ +This program 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. + +This program 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 this program in the COPYING and COPYING.LESSER files. +If not, see . \ No newline at end of file diff --git a/plugins/ldap-user-sync/vendor/licenses/pyasn1/LICENSE.rst b/plugins/ldap-user-sync/vendor/licenses/pyasn1/LICENSE.rst new file mode 100644 index 00000000..598b8430 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/licenses/pyasn1/LICENSE.rst @@ -0,0 +1,24 @@ +Copyright (c) 2005-2020, Ilya Etingof +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/__init__.py new file mode 100644 index 00000000..b252b99d --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/__init__.py @@ -0,0 +1,2 @@ +# https://www.python.org/dev/peps/pep-0396/ +__version__ = '0.6.4' diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/decoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/decoder.py new file mode 100644 index 00000000..e1b74e11 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/decoder.py @@ -0,0 +1,2236 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import io +import os +import sys +import warnings + +from pyasn1 import debug +from pyasn1 import error +from pyasn1.codec.ber import eoo +from pyasn1.codec.streaming import asSeekableStream +from pyasn1.codec.streaming import isEndOfStream +from pyasn1.codec.streaming import peekIntoStream +from pyasn1.codec.streaming import readFromStream +from pyasn1.compat import _MISSING +from pyasn1.error import PyAsn1Error +from pyasn1.type import base +from pyasn1.type import char +from pyasn1.type import tag +from pyasn1.type import tagmap +from pyasn1.type import univ +from pyasn1.type import useful + +__all__ = ['StreamingDecoder', 'Decoder', 'decode'] + +LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER) + +noValue = base.noValue + +SubstrateUnderrunError = error.SubstrateUnderrunError + +# Maximum number of continuation octets (high-bit set) allowed per OID arc. +# 20 octets allows up to 140-bit integers, supporting UUID-based OIDs +MAX_OID_ARC_CONTINUATION_OCTETS = 20 + +# Maximum number of octets in a long-form tag ID (20 octets = up to +# 140-bit tag IDs, matching the OID arc limit) +MAX_TAG_OCTETS = 20 +MAX_NESTING_DEPTH = 100 + +# Maximum number of bytes in a BER length field (8 bytes = up to 2^64-1) +MAX_LENGTH_OCTETS = 8 + + +class AbstractPayloadDecoder(object): + protoComponent = None + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + """Decode value with fixed byte length. + + The decoder is allowed to consume as many bytes as necessary. + """ + raise error.PyAsn1Error('SingleItemDecoder not implemented for %s' % (tagSet,)) # TODO: Seems more like an NotImplementedError? + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + """Decode value with undefined length. + + The decoder is allowed to consume as many bytes as necessary. + """ + raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,)) # TODO: Seems more like an NotImplementedError? + + @staticmethod + def _passAsn1Object(asn1Object, options): + if 'asn1Object' not in options: + options['asn1Object'] = asn1Object + + return options + + +class AbstractSimplePayloadDecoder(AbstractPayloadDecoder): + @staticmethod + def substrateCollector(asn1Object, substrate, length, options): + for chunk in readFromStream(substrate, length, options): + yield chunk + + def _createComponent(self, asn1Spec, tagSet, value, **options): + if options.get('native'): + return value + elif asn1Spec is None: + return self.protoComponent.clone(value, tagSet=tagSet) + elif value is noValue: + return asn1Spec + else: + return asn1Spec.clone(value) + + +class RawPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.Any('') + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if substrateFun: + asn1Object = self._createComponent(asn1Spec, tagSet, '', **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + for value in decodeFun(substrate, asn1Spec, tagSet, length, **options): + yield value + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if substrateFun: + asn1Object = self._createComponent(asn1Spec, tagSet, '', **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + while True: + for value in decodeFun( + substrate, asn1Spec, tagSet, length, + allowEoo=True, **options): + + if value is eoo.endOfOctets: + return + + yield value + + +rawPayloadDecoder = RawPayloadDecoder() + + +class IntegerPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.Integer(0) + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + + if tagSet[0].tagFormat != tag.tagFormatSimple: + raise error.PyAsn1Error('Simple tag format expected') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if chunk: + value = int.from_bytes(bytes(chunk), 'big', signed=True) + + else: + value = 0 + + yield self._createComponent(asn1Spec, tagSet, value, **options) + + +class BooleanPayloadDecoder(IntegerPayloadDecoder): + protoComponent = univ.Boolean(0) + + def _createComponent(self, asn1Spec, tagSet, value, **options): + return IntegerPayloadDecoder._createComponent( + self, asn1Spec, tagSet, value and 1 or 0, **options) + + +class BitStringPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.BitString(()) + supportConstructedForm = True + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + + if substrateFun: + asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + if not length: + raise error.PyAsn1Error('Empty BIT STRING substrate') + + for chunk in isEndOfStream(substrate): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if chunk: + raise error.PyAsn1Error('Empty BIT STRING substrate') + + if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check? + + for trailingBits in readFromStream(substrate, 1, options): + if isinstance(trailingBits, SubstrateUnderrunError): + yield trailingBits + + trailingBits = ord(trailingBits) + if trailingBits > 7: + raise error.PyAsn1Error( + 'Trailing bits overflow %s' % trailingBits + ) + + for chunk in readFromStream(substrate, length - 1, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + value = self.protoComponent.fromOctetString( + chunk, internalFormat=True, padding=trailingBits) + + yield self._createComponent(asn1Spec, tagSet, value, **options) + + return + + if not self.supportConstructedForm: + raise error.PyAsn1Error('Constructed encoding form prohibited ' + 'at %s' % self.__class__.__name__) + + if LOG: + LOG('assembling constructed serialization') + + # All inner fragments are of the same type, treat them as octet string + substrateFun = self.substrateCollector + + bitString = self.protoComponent.fromOctetString(b'', internalFormat=True) + + current_position = substrate.tell() + + while substrate.tell() - current_position < length: + for component in decodeFun( + substrate, self.protoComponent, substrateFun=substrateFun, + **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + trailingBits = component[0] + if trailingBits > 7: + raise error.PyAsn1Error( + 'Trailing bits overflow %s' % trailingBits + ) + + bitString = self.protoComponent.fromOctetString( + component[1:], internalFormat=True, + prepend=bitString, padding=trailingBits + ) + + yield self._createComponent(asn1Spec, tagSet, bitString, **options) + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + + if substrateFun: + asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + # All inner fragments are of the same type, treat them as octet string + substrateFun = self.substrateCollector + + bitString = self.protoComponent.fromOctetString(b'', internalFormat=True) + + while True: # loop over fragments + + for component in decodeFun( + substrate, self.protoComponent, substrateFun=substrateFun, + allowEoo=True, **options): + + if component is eoo.endOfOctets: + break + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + trailingBits = component[0] + if trailingBits > 7: + raise error.PyAsn1Error( + 'Trailing bits overflow %s' % trailingBits + ) + + bitString = self.protoComponent.fromOctetString( + component[1:], internalFormat=True, + prepend=bitString, padding=trailingBits + ) + + yield self._createComponent(asn1Spec, tagSet, bitString, **options) + + +class OctetStringPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.OctetString('') + supportConstructedForm = True + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if substrateFun: + asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check? + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + yield self._createComponent(asn1Spec, tagSet, chunk, **options) + + return + + if not self.supportConstructedForm: + raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__) + + if LOG: + LOG('assembling constructed serialization') + + # All inner fragments are of the same type, treat them as octet string + substrateFun = self.substrateCollector + + header = b'' + + original_position = substrate.tell() + # head = popSubstream(substrate, length) + while substrate.tell() - original_position < length: + for component in decodeFun( + substrate, self.protoComponent, substrateFun=substrateFun, + **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + header += component + + yield self._createComponent(asn1Spec, tagSet, header, **options) + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if substrateFun and substrateFun is not self.substrateCollector: + asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options) + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + # All inner fragments are of the same type, treat them as octet string + substrateFun = self.substrateCollector + + header = b'' + + while True: # loop over fragments + + for component in decodeFun( + substrate, self.protoComponent, substrateFun=substrateFun, + allowEoo=True, **options): + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + if component is eoo.endOfOctets: + break + + header += component + + yield self._createComponent(asn1Spec, tagSet, header, **options) + + +class NullPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.Null('') + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + + if tagSet[0].tagFormat != tag.tagFormatSimple: + raise error.PyAsn1Error('Simple tag format expected') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + component = self._createComponent(asn1Spec, tagSet, '', **options) + + if chunk: + raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length) + + yield component + + +class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.ObjectIdentifier(()) + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if tagSet[0].tagFormat != tag.tagFormatSimple: + raise error.PyAsn1Error('Simple tag format expected') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if not chunk: + raise error.PyAsn1Error('Empty substrate') + + oid = [] + index = 0 + substrateLen = len(chunk) + while index < substrateLen: + subId = chunk[index] + index += 1 + if subId < 128: + oid.append(subId) + elif subId > 128: + # Construct subid from a number of octets + nextSubId = subId + subId = 0 + continuationOctetCount = 0 + while nextSubId >= 128: + continuationOctetCount += 1 + if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS: + raise error.PyAsn1Error( + 'OID arc exceeds maximum continuation octets limit (%d) ' + 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index) + ) + subId = (subId << 7) + (nextSubId & 0x7F) + if index >= substrateLen: + raise error.SubstrateUnderrunError( + 'Short substrate for sub-OID past %s' % (tuple(oid),) + ) + nextSubId = chunk[index] + index += 1 + oid.append((subId << 7) + nextSubId) + elif subId == 128: + # ASN.1 spec forbids leading zeros (0x80) in OID + # encoding, tolerating it opens a vulnerability. See + # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf + # page 7 + raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding') + + # Decode two leading arcs + if 0 <= oid[0] <= 39: + oid.insert(0, 0) + elif 40 <= oid[0] <= 79: + oid[0] -= 40 + oid.insert(0, 1) + elif oid[0] >= 80: + oid[0] -= 80 + oid.insert(0, 2) + else: + raise error.PyAsn1Error('Malformed first OID octet: %s' % chunk[0]) + + yield self._createComponent(asn1Spec, tagSet, tuple(oid), **options) + + +class RelativeOIDPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.RelativeOID(()) + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if tagSet[0].tagFormat != tag.tagFormatSimple: + raise error.PyAsn1Error('Simple tag format expected') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if not chunk: + raise error.PyAsn1Error('Empty substrate') + + reloid = [] + index = 0 + substrateLen = len(chunk) + while index < substrateLen: + subId = chunk[index] + index += 1 + if subId < 128: + reloid.append(subId) + elif subId > 128: + # Construct subid from a number of octets + nextSubId = subId + subId = 0 + continuationOctetCount = 0 + while nextSubId >= 128: + continuationOctetCount += 1 + if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS: + raise error.PyAsn1Error( + 'RELATIVE-OID arc exceeds maximum continuation octets limit (%d) ' + 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index) + ) + subId = (subId << 7) + (nextSubId & 0x7F) + if index >= substrateLen: + raise error.SubstrateUnderrunError( + 'Short substrate for sub-OID past %s' % (tuple(reloid),) + ) + nextSubId = chunk[index] + index += 1 + reloid.append((subId << 7) + nextSubId) + elif subId == 128: + # ASN.1 spec forbids leading zeros (0x80) in OID + # encoding, tolerating it opens a vulnerability. See + # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf + # page 7 + raise error.PyAsn1Error('Invalid octet 0x80 in RELATIVE-OID encoding') + + yield self._createComponent(asn1Spec, tagSet, tuple(reloid), **options) + + +class RealPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.Real() + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if tagSet[0].tagFormat != tag.tagFormatSimple: + raise error.PyAsn1Error('Simple tag format expected') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if not chunk: + yield self._createComponent(asn1Spec, tagSet, 0.0, **options) + return + + fo = chunk[0] + chunk = chunk[1:] + if fo & 0x80: # binary encoding + if not chunk: + raise error.PyAsn1Error("Incomplete floating-point value") + + if LOG: + LOG('decoding binary encoded REAL') + + n = (fo & 0x03) + 1 + + if n == 4: + n = chunk[0] + chunk = chunk[1:] + + eo, chunk = chunk[:n], chunk[n:] + + if not eo or not chunk: + raise error.PyAsn1Error('Real exponent screwed') + + e = eo[0] & 0x80 and -1 or 0 + + while eo: # exponent + e <<= 8 + e |= eo[0] + eo = eo[1:] + + b = fo >> 4 & 0x03 # base bits + + if b > 2: + raise error.PyAsn1Error('Illegal Real base') + + if b == 1: # encbase = 8 + e *= 3 + + elif b == 2: # encbase = 16 + e *= 4 + p = 0 + + while chunk: # value + p <<= 8 + p |= chunk[0] + chunk = chunk[1:] + + if fo & 0x40: # sign bit + p = -p + + sf = fo >> 2 & 0x03 # scale bits + p *= 2 ** sf + value = (p, 2, e) + + elif fo & 0x40: # infinite value + if LOG: + LOG('decoding infinite REAL') + + value = fo & 0x01 and '-inf' or 'inf' + + elif fo & 0xc0 == 0: # character encoding + if not chunk: + raise error.PyAsn1Error("Incomplete floating-point value") + + if LOG: + LOG('decoding character encoded REAL') + + try: + if fo & 0x3 == 0x1: # NR1 + value = (int(chunk), 10, 0) + + elif fo & 0x3 == 0x2: # NR2 + value = float(chunk) + + elif fo & 0x3 == 0x3: # NR3 + value = float(chunk) + + else: + raise error.SubstrateUnderrunError( + 'Unknown NR (tag %s)' % fo + ) + + except ValueError: + raise error.SubstrateUnderrunError( + 'Bad character Real syntax' + ) + + else: + raise error.SubstrateUnderrunError( + 'Unknown encoding (tag %s)' % fo + ) + + yield self._createComponent(asn1Spec, tagSet, value, **options) + + +class AbstractConstructedPayloadDecoder(AbstractPayloadDecoder): + protoComponent = None + + +class ConstructedPayloadDecoderBase(AbstractConstructedPayloadDecoder): + protoRecordComponent = None + protoSequenceComponent = None + + def _getComponentTagMap(self, asn1Object, idx): + raise NotImplementedError + + def _getComponentPositionByType(self, asn1Object, tagSet, idx): + raise NotImplementedError + + def _decodeComponentsSchemaless( + self, substrate, tagSet=None, decodeFun=None, + length=None, **options): + + asn1Object = None + + components = [] + componentTypes = set() + + original_position = substrate.tell() + + while length == -1 or substrate.tell() < original_position + length: + for component in decodeFun(substrate, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + if length == -1 and component is eoo.endOfOctets: + break + + components.append(component) + componentTypes.add(component.tagSet) + + # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF + # The heuristics is: + # * 1+ components of different types -> likely SEQUENCE/SET + # * otherwise -> likely SEQUENCE OF/SET OF + if len(componentTypes) > 1: + protoComponent = self.protoRecordComponent + + else: + protoComponent = self.protoSequenceComponent + + asn1Object = protoComponent.clone( + # construct tagSet from base tag from prototype ASN.1 object + # and additional tags recovered from the substrate + tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags) + ) + + if LOG: + LOG('guessed %r container type (pass `asn1Spec` to guide the ' + 'decoder)' % asn1Object) + + for idx, component in enumerate(components): + asn1Object.setComponentByPosition( + idx, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False + ) + + yield asn1Object + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if tagSet[0].tagFormat != tag.tagFormatConstructed: + raise error.PyAsn1Error('Constructed tag format expected') + + original_position = substrate.tell() + + if substrateFun: + if asn1Spec is not None: + asn1Object = asn1Spec.clone() + + elif self.protoComponent is not None: + asn1Object = self.protoComponent.clone(tagSet=tagSet) + + else: + asn1Object = self.protoRecordComponent, self.protoSequenceComponent + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + if asn1Spec is None: + for asn1Object in self._decodeComponentsSchemaless( + substrate, tagSet=tagSet, decodeFun=decodeFun, + length=length, **options): + if isinstance(asn1Object, SubstrateUnderrunError): + yield asn1Object + + if substrate.tell() < original_position + length: + if LOG: + for trailing in readFromStream(substrate, context=options): + if isinstance(trailing, SubstrateUnderrunError): + yield trailing + + LOG('Unused trailing %d octets encountered: %s' % ( + len(trailing), debug.hexdump(trailing))) + + yield asn1Object + + return + + asn1Object = asn1Spec.clone() + asn1Object.clear() + + options = self._passAsn1Object(asn1Object, options) + + if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): + + namedTypes = asn1Spec.componentType + + isSetType = asn1Spec.typeId == univ.Set.typeId + isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault + + if LOG: + LOG('decoding %sdeterministic %s type %r chosen by type ID' % ( + not isDeterministic and 'non-' or '', isSetType and 'SET' or '', + asn1Spec)) + + seenIndices = set() + idx = 0 + while substrate.tell() - original_position < length: + if not namedTypes: + componentType = None + + elif isSetType: + componentType = namedTypes.tagMapUnique + + else: + try: + if isDeterministic: + componentType = namedTypes[idx].asn1Object + + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: + componentType = namedTypes.getTagMapNearPosition(idx) + + else: + componentType = namedTypes[idx].asn1Object + + except IndexError: + raise error.PyAsn1Error( + 'Excessive components decoded at %r' % (asn1Spec,) + ) + + for component in decodeFun(substrate, componentType, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + if not isDeterministic and namedTypes: + if isSetType: + idx = namedTypes.getPositionByType(component.effectiveTagSet) + + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: + idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx) + + asn1Object.setComponentByPosition( + idx, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False + ) + + seenIndices.add(idx) + idx += 1 + + if LOG: + LOG('seen component indices %s' % seenIndices) + + if namedTypes: + if not namedTypes.requiredComponents.issubset(seenIndices): + raise error.PyAsn1Error( + 'ASN.1 object %s has uninitialized ' + 'components' % asn1Object.__class__.__name__) + + if namedTypes.hasOpenTypes: + + openTypes = options.get('openTypes', {}) + + if LOG: + LOG('user-specified open types map:') + + for k, v in openTypes.items(): + LOG('%s -> %r' % (k, v)) + + if openTypes or options.get('decodeOpenTypes', False): + + for idx, namedType in enumerate(namedTypes.namedTypes): + if not namedType.openType: + continue + + if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue: + continue + + governingValue = asn1Object.getComponentByName( + namedType.openType.name + ) + + try: + openType = openTypes[governingValue] + + except KeyError: + + if LOG: + LOG('default open types map of component ' + '"%s.%s" governed by component "%s.%s"' + ':' % (asn1Object.__class__.__name__, + namedType.name, + asn1Object.__class__.__name__, + namedType.openType.name)) + + for k, v in namedType.openType.items(): + LOG('%s -> %r' % (k, v)) + + try: + openType = namedType.openType[governingValue] + + except KeyError: + if LOG: + LOG('failed to resolve open type by governing ' + 'value %r' % (governingValue,)) + continue + + if LOG: + LOG('resolved open type %r by governing ' + 'value %r' % (openType, governingValue)) + + containerValue = asn1Object.getComponentByPosition(idx) + + if containerValue.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + for pos, containerElement in enumerate( + containerValue): + + stream = asSeekableStream(containerValue[pos].asOctets()) + + for component in decodeFun(stream, asn1Spec=openType, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + containerValue[pos] = component + + else: + stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets()) + + for component in decodeFun(stream, asn1Spec=openType, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + asn1Object.setComponentByPosition(idx, component) + + else: + inconsistency = asn1Object.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent") + + else: + componentType = asn1Spec.componentType + + if LOG: + LOG('decoding type %r chosen by given `asn1Spec`' % componentType) + + idx = 0 + + while substrate.tell() - original_position < length: + for component in decodeFun(substrate, componentType, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + asn1Object.setComponentByPosition( + idx, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False + ) + + idx += 1 + + yield asn1Object + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if tagSet[0].tagFormat != tag.tagFormatConstructed: + raise error.PyAsn1Error('Constructed tag format expected') + + if substrateFun is not None: + if asn1Spec is not None: + asn1Object = asn1Spec.clone() + + elif self.protoComponent is not None: + asn1Object = self.protoComponent.clone(tagSet=tagSet) + + else: + asn1Object = self.protoRecordComponent, self.protoSequenceComponent + + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + if asn1Spec is None: + for asn1Object in self._decodeComponentsSchemaless( + substrate, tagSet=tagSet, decodeFun=decodeFun, + length=length, **dict(options, allowEoo=True)): + if isinstance(asn1Object, SubstrateUnderrunError): + yield asn1Object + + yield asn1Object + + return + + asn1Object = asn1Spec.clone() + asn1Object.clear() + + options = self._passAsn1Object(asn1Object, options) + + if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): + + namedTypes = asn1Object.componentType + + isSetType = asn1Object.typeId == univ.Set.typeId + isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault + + if LOG: + LOG('decoding %sdeterministic %s type %r chosen by type ID' % ( + not isDeterministic and 'non-' or '', isSetType and 'SET' or '', + asn1Spec)) + + seenIndices = set() + + idx = 0 + + while True: # loop over components + if len(namedTypes) <= idx: + asn1Spec = None + + elif isSetType: + asn1Spec = namedTypes.tagMapUnique + + else: + try: + if isDeterministic: + asn1Spec = namedTypes[idx].asn1Object + + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: + asn1Spec = namedTypes.getTagMapNearPosition(idx) + + else: + asn1Spec = namedTypes[idx].asn1Object + + except IndexError: + raise error.PyAsn1Error( + 'Excessive components decoded at %r' % (asn1Object,) + ) + + for component in decodeFun(substrate, asn1Spec, allowEoo=True, **options): + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + if component is eoo.endOfOctets: + break + + if not isDeterministic and namedTypes: + if isSetType: + idx = namedTypes.getPositionByType(component.effectiveTagSet) + + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: + idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx) + + asn1Object.setComponentByPosition( + idx, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False + ) + + seenIndices.add(idx) + idx += 1 + + if LOG: + LOG('seen component indices %s' % seenIndices) + + if namedTypes: + if not namedTypes.requiredComponents.issubset(seenIndices): + raise error.PyAsn1Error( + 'ASN.1 object %s has uninitialized ' + 'components' % asn1Object.__class__.__name__) + + if namedTypes.hasOpenTypes: + + openTypes = options.get('openTypes', {}) + + if LOG: + LOG('user-specified open types map:') + + for k, v in openTypes.items(): + LOG('%s -> %r' % (k, v)) + + if openTypes or options.get('decodeOpenTypes', False): + + for idx, namedType in enumerate(namedTypes.namedTypes): + if not namedType.openType: + continue + + if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue: + continue + + governingValue = asn1Object.getComponentByName( + namedType.openType.name + ) + + try: + openType = openTypes[governingValue] + + except KeyError: + + if LOG: + LOG('default open types map of component ' + '"%s.%s" governed by component "%s.%s"' + ':' % (asn1Object.__class__.__name__, + namedType.name, + asn1Object.__class__.__name__, + namedType.openType.name)) + + for k, v in namedType.openType.items(): + LOG('%s -> %r' % (k, v)) + + try: + openType = namedType.openType[governingValue] + + except KeyError: + if LOG: + LOG('failed to resolve open type by governing ' + 'value %r' % (governingValue,)) + continue + + if LOG: + LOG('resolved open type %r by governing ' + 'value %r' % (openType, governingValue)) + + containerValue = asn1Object.getComponentByPosition(idx) + + if containerValue.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + for pos, containerElement in enumerate( + containerValue): + + stream = asSeekableStream(containerValue[pos].asOctets()) + + for component in decodeFun(stream, asn1Spec=openType, + **dict(options, allowEoo=True)): + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + containerValue[pos] = component + + else: + stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets()) + for component in decodeFun(stream, asn1Spec=openType, + **dict(options, allowEoo=True)): + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + asn1Object.setComponentByPosition(idx, component) + + else: + inconsistency = asn1Object.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent") + + else: + componentType = asn1Spec.componentType + + if LOG: + LOG('decoding type %r chosen by given `asn1Spec`' % componentType) + + idx = 0 + + while True: + + for component in decodeFun( + substrate, componentType, allowEoo=True, **options): + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + if component is eoo.endOfOctets: + break + + asn1Object.setComponentByPosition( + idx, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False + ) + + idx += 1 + + yield asn1Object + + +class SequenceOrSequenceOfPayloadDecoder(ConstructedPayloadDecoderBase): + protoRecordComponent = univ.Sequence() + protoSequenceComponent = univ.SequenceOf() + + +class SequencePayloadDecoder(SequenceOrSequenceOfPayloadDecoder): + protoComponent = univ.Sequence() + + +class SequenceOfPayloadDecoder(SequenceOrSequenceOfPayloadDecoder): + protoComponent = univ.SequenceOf() + + +class SetOrSetOfPayloadDecoder(ConstructedPayloadDecoderBase): + protoRecordComponent = univ.Set() + protoSequenceComponent = univ.SetOf() + + +class SetPayloadDecoder(SetOrSetOfPayloadDecoder): + protoComponent = univ.Set() + + +class SetOfPayloadDecoder(SetOrSetOfPayloadDecoder): + protoComponent = univ.SetOf() + + +class ChoicePayloadDecoder(ConstructedPayloadDecoderBase): + protoComponent = univ.Choice() + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if asn1Spec is None: + asn1Object = self.protoComponent.clone(tagSet=tagSet) + + else: + asn1Object = asn1Spec.clone() + + if substrateFun: + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + options = self._passAsn1Object(asn1Object, options) + + if asn1Object.tagSet == tagSet: + if LOG: + LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,)) + + for component in decodeFun( + substrate, asn1Object.componentTagMap, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + else: + if LOG: + LOG('decoding %s as untagged CHOICE' % (tagSet,)) + + for component in decodeFun( + substrate, asn1Object.componentTagMap, tagSet, length, + state, **options): + if isinstance(component, SubstrateUnderrunError): + yield component + + effectiveTagSet = component.effectiveTagSet + + if LOG: + LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet)) + + asn1Object.setComponentByType( + effectiveTagSet, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False, + innerFlag=False + ) + + yield asn1Object + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if asn1Spec is None: + asn1Object = self.protoComponent.clone(tagSet=tagSet) + + else: + asn1Object = asn1Spec.clone() + + if substrateFun: + for chunk in substrateFun(asn1Object, substrate, length, options): + yield chunk + + return + + options = self._passAsn1Object(asn1Object, options) + + isTagged = asn1Object.tagSet == tagSet + + if LOG: + LOG('decoding %s as %stagged CHOICE' % ( + tagSet, isTagged and 'explicitly ' or 'un')) + + while True: + + if isTagged: + iterator = decodeFun( + substrate, asn1Object.componentType.tagMapUnique, + **dict(options, allowEoo=True)) + + else: + iterator = decodeFun( + substrate, asn1Object.componentType.tagMapUnique, + tagSet, length, state, **dict(options, allowEoo=True)) + + for component in iterator: + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + effectiveTagSet = component.effectiveTagSet + + if LOG: + LOG('decoded component %s, effective tag set ' + '%s' % (component, effectiveTagSet)) + + asn1Object.setComponentByType( + effectiveTagSet, component, + verifyConstraints=False, + matchTags=False, matchConstraints=False, + innerFlag=False + ) + + if not isTagged: + break + + if not isTagged or component is eoo.endOfOctets: + break + + yield asn1Object + + +class AnyPayloadDecoder(AbstractSimplePayloadDecoder): + protoComponent = univ.Any() + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if asn1Spec is None: + isUntagged = True + + elif asn1Spec.__class__ is tagmap.TagMap: + isUntagged = tagSet not in asn1Spec.tagMap + + else: + isUntagged = tagSet != asn1Spec.tagSet + + if isUntagged: + fullPosition = substrate.markedPosition + currentPosition = substrate.tell() + + substrate.seek(fullPosition, os.SEEK_SET) + length += currentPosition - fullPosition + + if LOG: + for chunk in peekIntoStream(substrate, length): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + LOG('decoding as untagged ANY, substrate ' + '%s' % debug.hexdump(chunk)) + + if substrateFun: + for chunk in substrateFun( + self._createComponent(asn1Spec, tagSet, noValue, **options), + substrate, length, options): + yield chunk + + return + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + yield self._createComponent(asn1Spec, tagSet, chunk, **options) + + def indefLenValueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + if asn1Spec is None: + isTagged = False + + elif asn1Spec.__class__ is tagmap.TagMap: + isTagged = tagSet in asn1Spec.tagMap + + else: + isTagged = tagSet == asn1Spec.tagSet + + if isTagged: + # tagged Any type -- consume header substrate + chunk = b'' + + if LOG: + LOG('decoding as tagged ANY') + + else: + # TODO: Seems not to be tested + fullPosition = substrate.markedPosition + currentPosition = substrate.tell() + + substrate.seek(fullPosition, os.SEEK_SET) + for chunk in readFromStream(substrate, currentPosition - fullPosition, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + if LOG: + LOG('decoding as untagged ANY, header substrate %s' % debug.hexdump(chunk)) + + # Any components do not inherit initial tag + asn1Spec = self.protoComponent + + if substrateFun and substrateFun is not self.substrateCollector: + asn1Object = self._createComponent( + asn1Spec, tagSet, noValue, **options) + + for chunk in substrateFun( + asn1Object, chunk + substrate, length + len(chunk), options): + yield chunk + + return + + if LOG: + LOG('assembling constructed serialization') + + # All inner fragments are of the same type, treat them as octet string + substrateFun = self.substrateCollector + + while True: # loop over fragments + + for component in decodeFun( + substrate, asn1Spec, substrateFun=substrateFun, + allowEoo=True, **options): + + if isinstance(component, SubstrateUnderrunError): + yield component + + if component is eoo.endOfOctets: + break + + if component is eoo.endOfOctets: + break + + chunk += component + + if substrateFun: + yield chunk # TODO: Weird + + else: + yield self._createComponent(asn1Spec, tagSet, chunk, **options) + + +# character string types +class UTF8StringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.UTF8String() + + +class NumericStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.NumericString() + + +class PrintableStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.PrintableString() + + +class TeletexStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.TeletexString() + + +class VideotexStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.VideotexString() + + +class IA5StringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.IA5String() + + +class GraphicStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.GraphicString() + + +class VisibleStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.VisibleString() + + +class GeneralStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.GeneralString() + + +class UniversalStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.UniversalString() + + +class BMPStringPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = char.BMPString() + + +# "useful" types +class ObjectDescriptorPayloadDecoder(OctetStringPayloadDecoder): + protoComponent = useful.ObjectDescriptor() + + +class GeneralizedTimePayloadDecoder(OctetStringPayloadDecoder): + protoComponent = useful.GeneralizedTime() + + +class UTCTimePayloadDecoder(OctetStringPayloadDecoder): + protoComponent = useful.UTCTime() + + +TAG_MAP = { + univ.Integer.tagSet: IntegerPayloadDecoder(), + univ.Boolean.tagSet: BooleanPayloadDecoder(), + univ.BitString.tagSet: BitStringPayloadDecoder(), + univ.OctetString.tagSet: OctetStringPayloadDecoder(), + univ.Null.tagSet: NullPayloadDecoder(), + univ.ObjectIdentifier.tagSet: ObjectIdentifierPayloadDecoder(), + univ.RelativeOID.tagSet: RelativeOIDPayloadDecoder(), + univ.Enumerated.tagSet: IntegerPayloadDecoder(), + univ.Real.tagSet: RealPayloadDecoder(), + univ.Sequence.tagSet: SequenceOrSequenceOfPayloadDecoder(), # conflicts with SequenceOf + univ.Set.tagSet: SetOrSetOfPayloadDecoder(), # conflicts with SetOf + univ.Choice.tagSet: ChoicePayloadDecoder(), # conflicts with Any + # character string types + char.UTF8String.tagSet: UTF8StringPayloadDecoder(), + char.NumericString.tagSet: NumericStringPayloadDecoder(), + char.PrintableString.tagSet: PrintableStringPayloadDecoder(), + char.TeletexString.tagSet: TeletexStringPayloadDecoder(), + char.VideotexString.tagSet: VideotexStringPayloadDecoder(), + char.IA5String.tagSet: IA5StringPayloadDecoder(), + char.GraphicString.tagSet: GraphicStringPayloadDecoder(), + char.VisibleString.tagSet: VisibleStringPayloadDecoder(), + char.GeneralString.tagSet: GeneralStringPayloadDecoder(), + char.UniversalString.tagSet: UniversalStringPayloadDecoder(), + char.BMPString.tagSet: BMPStringPayloadDecoder(), + # useful types + useful.ObjectDescriptor.tagSet: ObjectDescriptorPayloadDecoder(), + useful.GeneralizedTime.tagSet: GeneralizedTimePayloadDecoder(), + useful.UTCTime.tagSet: UTCTimePayloadDecoder() +} + +# Type-to-codec map for ambiguous ASN.1 types +TYPE_MAP = { + univ.Set.typeId: SetPayloadDecoder(), + univ.SetOf.typeId: SetOfPayloadDecoder(), + univ.Sequence.typeId: SequencePayloadDecoder(), + univ.SequenceOf.typeId: SequenceOfPayloadDecoder(), + univ.Choice.typeId: ChoicePayloadDecoder(), + univ.Any.typeId: AnyPayloadDecoder() +} + +# Put in non-ambiguous types for faster codec lookup +for typeDecoder in TAG_MAP.values(): + if typeDecoder.protoComponent is not None: + typeId = typeDecoder.protoComponent.__class__.typeId + if typeId is not None and typeId not in TYPE_MAP: + TYPE_MAP[typeId] = typeDecoder + + +(stDecodeTag, + stDecodeLength, + stGetValueDecoder, + stGetValueDecoderByAsn1Spec, + stGetValueDecoderByTag, + stTryAsExplicitTag, + stDecodeValue, + stDumpRawValue, + stErrorCondition, + stStop) = [x for x in range(10)] + + +EOO_SENTINEL = bytes((0, 0)) + + +class SingleItemDecoder(object): + defaultErrorState = stErrorCondition + #defaultErrorState = stDumpRawValue + defaultRawDecoder = AnyPayloadDecoder() + + supportIndefLength = True + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **ignored): + self._tagMap = tagMap if tagMap is not _MISSING else self.TAG_MAP + self._typeMap = typeMap if typeMap is not _MISSING else self.TYPE_MAP + + # Tag & TagSet objects caches + self._tagCache = {} + self._tagSetCache = {} + + def __call__(self, substrate, asn1Spec=None, + tagSet=None, length=None, state=stDecodeTag, + decodeFun=None, substrateFun=None, + **options): + + _nestingLevel = options.get('_nestingLevel', 0) + + if _nestingLevel > MAX_NESTING_DEPTH: + raise error.PyAsn1Error( + 'ASN.1 structure nesting depth exceeds limit (%d)' % MAX_NESTING_DEPTH + ) + + options['_nestingLevel'] = _nestingLevel + 1 + + allowEoo = options.pop('allowEoo', False) + + if LOG: + LOG('decoder called at scope %s with state %d, working with up ' + 'to %s octets of substrate: ' + '%s' % (debug.scope, state, length, substrate)) + + # Look for end-of-octets sentinel + if allowEoo and self.supportIndefLength: + + for eoo_candidate in readFromStream(substrate, 2, options): + if isinstance(eoo_candidate, SubstrateUnderrunError): + yield eoo_candidate + + if eoo_candidate == EOO_SENTINEL: + if LOG: + LOG('end-of-octets sentinel found') + yield eoo.endOfOctets + return + + else: + substrate.seek(-2, os.SEEK_CUR) + + tagMap = self._tagMap + typeMap = self._typeMap + tagCache = self._tagCache + tagSetCache = self._tagSetCache + + value = noValue + + substrate.markedPosition = substrate.tell() + + while state is not stStop: + + if state is stDecodeTag: + # Decode tag + isShortTag = True + + for firstByte in readFromStream(substrate, 1, options): + if isinstance(firstByte, SubstrateUnderrunError): + yield firstByte + + firstOctet = ord(firstByte) + + try: + lastTag = tagCache[firstOctet] + + except KeyError: + integerTag = firstOctet + tagClass = integerTag & 0xC0 + tagFormat = integerTag & 0x20 + tagId = integerTag & 0x1F + + if tagId == 0x1F: + isShortTag = False + tagOctetCount = 0 + tagId = 0 + + while True: + for integerByte in readFromStream(substrate, 1, options): + if isinstance(integerByte, SubstrateUnderrunError): + yield integerByte + + if not integerByte: + raise error.SubstrateUnderrunError( + 'Short octet stream on long tag decoding' + ) + + integerTag = ord(integerByte) + tagOctetCount += 1 + if tagOctetCount > MAX_TAG_OCTETS: + raise error.PyAsn1Error( + 'Tag ID octet count exceeds limit (%d)' % ( + MAX_TAG_OCTETS,) + ) + tagId <<= 7 + tagId |= (integerTag & 0x7F) + + if not integerTag & 0x80: + break + + lastTag = tag.Tag( + tagClass=tagClass, tagFormat=tagFormat, tagId=tagId + ) + + if isShortTag: + # cache short tags + tagCache[firstOctet] = lastTag + + if tagSet is None: + if isShortTag: + try: + tagSet = tagSetCache[firstOctet] + + except KeyError: + # base tag not recovered + tagSet = tag.TagSet((), lastTag) + tagSetCache[firstOctet] = tagSet + else: + tagSet = tag.TagSet((), lastTag) + + else: + tagSet = lastTag + tagSet + + state = stDecodeLength + + if LOG: + LOG('tag decoded into %s, decoding length' % tagSet) + + if state is stDecodeLength: + # Decode length + for firstOctet in readFromStream(substrate, 1, options): + if isinstance(firstOctet, SubstrateUnderrunError): + yield firstOctet + + firstOctet = ord(firstOctet) + + if firstOctet < 128: + length = firstOctet + + elif firstOctet > 128: + size = firstOctet & 0x7F + + if size > MAX_LENGTH_OCTETS: + raise error.PyAsn1Error( + 'BER length field size %d exceeds limit (%d)' % ( + size, MAX_LENGTH_OCTETS) + ) + + # encoded in size bytes + for encodedLength in readFromStream(substrate, size, options): + if isinstance(encodedLength, SubstrateUnderrunError): + yield encodedLength + encodedLength = list(encodedLength) + if len(encodedLength) != size: + raise error.SubstrateUnderrunError( + '%s<%s at %s' % (size, len(encodedLength), tagSet) + ) + + length = 0 + for lengthOctet in encodedLength: + length <<= 8 + length |= lengthOctet + size += 1 + + else: # 128 means indefinite + length = -1 + + if length == -1 and not self.supportIndefLength: + raise error.PyAsn1Error('Indefinite length encoding not supported by this codec') + + state = stGetValueDecoder + + if LOG: + LOG('value length decoded into %d' % length) + + if state is stGetValueDecoder: + if asn1Spec is None: + state = stGetValueDecoderByTag + + else: + state = stGetValueDecoderByAsn1Spec + # + # There're two ways of creating subtypes in ASN.1 what influences + # decoder operation. These methods are: + # 1) Either base types used in or no IMPLICIT tagging has been + # applied on subtyping. + # 2) Subtype syntax drops base type information (by means of + # IMPLICIT tagging. + # The first case allows for complete tag recovery from substrate + # while the second one requires original ASN.1 type spec for + # decoding. + # + # In either case a set of tags (tagSet) is coming from substrate + # in an incremental, tag-by-tag fashion (this is the case of + # EXPLICIT tag which is most basic). Outermost tag comes first + # from the wire. + # + if state is stGetValueDecoderByTag: + try: + concreteDecoder = tagMap[tagSet] + + except KeyError: + concreteDecoder = None + + if concreteDecoder: + state = stDecodeValue + + else: + try: + concreteDecoder = tagMap[tagSet[:1]] + + except KeyError: + concreteDecoder = None + + if concreteDecoder: + state = stDecodeValue + else: + state = stTryAsExplicitTag + + if LOG: + LOG('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as explicit tag')) + debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__) + + if state is stGetValueDecoderByAsn1Spec: + + if asn1Spec.__class__ is tagmap.TagMap: + try: + chosenSpec = asn1Spec[tagSet] + + except KeyError: + chosenSpec = None + + if LOG: + LOG('candidate ASN.1 spec is a map of:') + + for firstOctet, v in asn1Spec.presentTypes.items(): + LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) + + if asn1Spec.skipTypes: + LOG('but neither of: ') + for firstOctet, v in asn1Spec.skipTypes.items(): + LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) + LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '' or chosenSpec.prettyPrintType(), tagSet)) + + elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap: + chosenSpec = asn1Spec + if LOG: + LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__) + + else: + chosenSpec = None + + if chosenSpec is not None: + try: + # ambiguous type or just faster codec lookup + concreteDecoder = typeMap[chosenSpec.typeId] + + if LOG: + LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,)) + + except KeyError: + # use base type for codec lookup to recover untagged types + baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag) + try: + # base type or tagged subtype + concreteDecoder = tagMap[baseTagSet] + + if LOG: + LOG('value decoder chosen by base %s' % (baseTagSet,)) + + except KeyError: + concreteDecoder = None + + if concreteDecoder: + asn1Spec = chosenSpec + state = stDecodeValue + + else: + state = stTryAsExplicitTag + + else: + concreteDecoder = None + state = stTryAsExplicitTag + + if LOG: + LOG('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as explicit tag')) + debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__) + + if state is stDecodeValue: + if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this + def substrateFun(asn1Object, _substrate, _length, _options): + """Legacy hack to keep the recursiveFlag=False option supported. + + The decode(..., substrateFun=userCallback) option was introduced in 0.1.4 as a generalization + of the old recursiveFlag=False option. Users should pass their callback instead of using + recursiveFlag. + """ + yield asn1Object + + original_position = substrate.tell() + + if length == -1: # indef length + for value in concreteDecoder.indefLenValueDecoder( + substrate, asn1Spec, + tagSet, length, stGetValueDecoder, + self, substrateFun, **options): + if isinstance(value, SubstrateUnderrunError): + yield value + + else: + for value in concreteDecoder.valueDecoder( + substrate, asn1Spec, + tagSet, length, stGetValueDecoder, + self, substrateFun, **options): + if isinstance(value, SubstrateUnderrunError): + yield value + + bytesRead = substrate.tell() - original_position + if not substrateFun and bytesRead != length: + raise PyAsn1Error( + "Read %s bytes instead of expected %s." % (bytesRead, length)) + elif substrateFun and bytesRead > length: + # custom substrateFun may be used for partial decoding, reading less is expected there + raise PyAsn1Error( + "Read %s bytes are more than expected %s." % (bytesRead, length)) + + if LOG: + LOG('codec %s yields type %s, value:\n%s\n...' % ( + concreteDecoder.__class__.__name__, value.__class__.__name__, + isinstance(value, base.Asn1Item) and value.prettyPrint() or value)) + + state = stStop + break + + if state is stTryAsExplicitTag: + if (tagSet and + tagSet[0].tagFormat == tag.tagFormatConstructed and + tagSet[0].tagClass != tag.tagClassUniversal): + # Assume explicit tagging + concreteDecoder = rawPayloadDecoder + state = stDecodeValue + + else: + concreteDecoder = None + state = self.defaultErrorState + + if LOG: + LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as failure')) + + if state is stDumpRawValue: + concreteDecoder = self.defaultRawDecoder + + if LOG: + LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__) + + state = stDecodeValue + + if state is stErrorCondition: + raise error.PyAsn1Error( + '%s not in asn1Spec: %r' % (tagSet, asn1Spec) + ) + + if LOG: + debug.scope.pop() + LOG('decoder left scope %s, call completed' % debug.scope) + + yield value + + +class StreamingDecoder(object): + """Create an iterator that turns BER/CER/DER byte stream into ASN.1 objects. + + On each iteration, consume whatever BER/CER/DER serialization is + available in the `substrate` stream-like object and turns it into + one or more, possibly nested, ASN.1 objects. + + Parameters + ---------- + substrate: :py:class:`file`, :py:class:`io.BytesIO` + BER/CER/DER serialization in form of a byte stream + + Keyword Args + ------------ + asn1Spec: :py:class:`~pyasn1.type.base.PyAsn1Item` + A pyasn1 type object to act as a template guiding the decoder. + Depending on the ASN.1 structure being decoded, `asn1Spec` may + or may not be required. One of the reasons why `asn1Spec` may + me required is that ASN.1 structure is encoded in the *IMPLICIT* + tagging mode. + + Yields + ------ + : :py:class:`~pyasn1.type.base.PyAsn1Item`, :py:class:`~pyasn1.error.SubstrateUnderrunError` + Decoded ASN.1 object (possibly, nested) or + :py:class:`~pyasn1.error.SubstrateUnderrunError` object indicating + insufficient BER/CER/DER serialization on input to fully recover ASN.1 + objects from it. + + In the latter case the caller is advised to ensure some more data in + the input stream, then call the iterator again. The decoder will resume + the decoding process using the newly arrived data. + + The `context` property of :py:class:`~pyasn1.error.SubstrateUnderrunError` + object might hold a reference to the partially populated ASN.1 object + being reconstructed. + + Raises + ------ + ~pyasn1.error.PyAsn1Error, ~pyasn1.error.EndOfStreamError + `PyAsn1Error` on deserialization error, `EndOfStreamError` on + premature stream closure. + + Examples + -------- + Decode BER serialisation without ASN.1 schema + + .. code-block:: pycon + + >>> stream = io.BytesIO( + ... b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03') + >>> + >>> for asn1Object in StreamingDecoder(stream): + ... print(asn1Object) + >>> + SequenceOf: + 1 2 3 + + Decode BER serialisation with ASN.1 schema + + .. code-block:: pycon + + >>> stream = io.BytesIO( + ... b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03') + >>> + >>> schema = SequenceOf(componentType=Integer()) + >>> + >>> decoder = StreamingDecoder(stream, asn1Spec=schema) + >>> for asn1Object in decoder: + ... print(asn1Object) + >>> + SequenceOf: + 1 2 3 + """ + + SINGLE_ITEM_DECODER = SingleItemDecoder + + def __init__(self, substrate, asn1Spec=None, **options): + self._singleItemDecoder = self.SINGLE_ITEM_DECODER(**options) + self._substrate = asSeekableStream(substrate) + self._asn1Spec = asn1Spec + self._options = options + + def __iter__(self): + while True: + for asn1Object in self._singleItemDecoder( + self._substrate, self._asn1Spec, **self._options): + yield asn1Object + + for chunk in isEndOfStream(self._substrate): + if isinstance(chunk, SubstrateUnderrunError): + yield + + break + + if chunk: + break + + +class Decoder(object): + """Create a BER decoder object. + + Parse BER/CER/DER octet-stream into one, possibly nested, ASN.1 object. + """ + STREAMING_DECODER = StreamingDecoder + + @classmethod + def __call__(cls, substrate, asn1Spec=None, **options): + """Turns BER/CER/DER octet stream into an ASN.1 object. + + Takes BER/CER/DER octet-stream in form of :py:class:`bytes` + and decode it into an ASN.1 object + (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which + may be a scalar or an arbitrary nested structure. + + Parameters + ---------- + substrate: :py:class:`bytes` + BER/CER/DER octet-stream to parse + + Keyword Args + ------------ + asn1Spec: :py:class:`~pyasn1.type.base.PyAsn1Item` + A pyasn1 type object (:py:class:`~pyasn1.type.base.PyAsn1Item` + derivative) to act as a template guiding the decoder. + Depending on the ASN.1 structure being decoded, `asn1Spec` may or + may not be required. Most common reason for it to require is that + ASN.1 structure is encoded in *IMPLICIT* tagging mode. + + substrateFun: :py:class:`Union[ + Callable[[pyasn1.type.base.PyAsn1Item, bytes, int], + Tuple[pyasn1.type.base.PyAsn1Item, bytes]], + Callable[[pyasn1.type.base.PyAsn1Item, io.BytesIO, int, dict], + Generator[Union[pyasn1.type.base.PyAsn1Item, + pyasn1.error.SubstrateUnderrunError], + None, None]] + ]` + User callback meant to generalize special use cases like non-recursive or + partial decoding. A 3-arg non-streaming variant is supported for backwards + compatiblilty in addition to the newer 4-arg streaming variant. + The callback will receive the uninitialized object recovered from substrate + as 1st argument, the uninterpreted payload as 2nd argument, and the length + of the uninterpreted payload as 3rd argument. The streaming variant will + additionally receive the decode(..., **options) kwargs as 4th argument. + The non-streaming variant shall return an object that will be propagated + as decode() return value as 1st item, and the remainig payload for further + decode passes as 2nd item. + The streaming variant shall yield an object that will be propagated as + decode() return value, and leave the remaining payload in the stream. + + Returns + ------- + : :py:class:`tuple` + A tuple of :py:class:`~pyasn1.type.base.PyAsn1Item` object + recovered from BER/CER/DER substrate and the unprocessed trailing + portion of the `substrate` (may be empty) + + Raises + ------ + : :py:class:`~pyasn1.error.PyAsn1Error` + :py:class:`~pyasn1.error.SubstrateUnderrunError` on insufficient + input or :py:class:`~pyasn1.error.PyAsn1Error` on decoding error. + + Examples + -------- + Decode BER/CER/DER serialisation without ASN.1 schema + + .. code-block:: pycon + + >>> s, unprocessed = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03') + >>> str(s) + SequenceOf: + 1 2 3 + + Decode BER/CER/DER serialisation with ASN.1 schema + + .. code-block:: pycon + + >>> seq = SequenceOf(componentType=Integer()) + >>> s, unprocessed = decode( + b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq) + >>> str(s) + SequenceOf: + 1 2 3 + + """ + substrate = asSeekableStream(substrate) + + if "substrateFun" in options: + origSubstrateFun = options["substrateFun"] + + def substrateFunWrapper(asn1Object, substrate, length, options=None): + """Support both 0.4 and 0.5 style APIs. + + substrateFun API has changed in 0.5 for use with streaming decoders. To stay backwards compatible, + we first try if we received a streaming user callback. If that fails,we assume we've received a + non-streaming v0.4 user callback and convert it for streaming on the fly + """ + try: + substrate_gen = origSubstrateFun(asn1Object, substrate, length, options) + except TypeError as _value: + if _value.__traceback__.tb_next: + # Traceback depth > 1 means TypeError from inside user provided function + raise + # invariant maintained at Decoder.__call__ entry + assert isinstance(substrate, io.BytesIO) # nosec assert_used + substrate_gen = Decoder._callSubstrateFunV4asV5(origSubstrateFun, asn1Object, substrate, length) + for value in substrate_gen: + yield value + + options["substrateFun"] = substrateFunWrapper + + streamingDecoder = cls.STREAMING_DECODER( + substrate, asn1Spec, **options) + + for asn1Object in streamingDecoder: + if isinstance(asn1Object, SubstrateUnderrunError): + raise error.SubstrateUnderrunError('Short substrate on input') + + try: + tail = next(readFromStream(substrate)) + + except error.EndOfStreamError: + tail = b'' + + return asn1Object, tail + + @staticmethod + def _callSubstrateFunV4asV5(substrateFunV4, asn1Object, substrate, length): + substrate_bytes = substrate.read() + if length == -1: + length = len(substrate_bytes) + value, nextSubstrate = substrateFunV4(asn1Object, substrate_bytes, length) + nbytes = substrate.write(nextSubstrate) + substrate.truncate() + substrate.seek(-nbytes, os.SEEK_CUR) + yield value + +#: Turns BER octet stream into an ASN.1 object. +#: +#: Takes BER octet-stream and decode it into an ASN.1 object +#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which +#: may be a scalar or an arbitrary nested structure. +#: +#: Parameters +#: ---------- +#: substrate: :py:class:`bytes` +#: BER octet-stream +#: +#: Keyword Args +#: ------------ +#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure +#: being decoded, *asn1Spec* may or may not be required. Most common reason for +#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode. +#: +#: Returns +#: ------- +#: : :py:class:`tuple` +#: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: and the unprocessed trailing portion of the *substrate* (may be empty) +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError +#: On decoding errors +#: +#: Notes +#: ----- +#: This function is deprecated. Please use :py:class:`Decoder` or +#: :py:class:`StreamingDecoder` class instance. +#: +#: Examples +#: -------- +#: Decode BER serialisation without ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03') +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +#: Decode BER serialisation with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq) +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +decode = Decoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/encoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/encoder.py new file mode 100644 index 00000000..f06b19e8 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/encoder.py @@ -0,0 +1,954 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import sys +import warnings + +from pyasn1 import debug +from pyasn1 import error +from pyasn1.codec.ber import eoo +from pyasn1.compat import _MISSING +from pyasn1.compat.integer import to_bytes +from pyasn1.type import char +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +__all__ = ['Encoder', 'encode'] + +LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_ENCODER) + + +class AbstractItemEncoder(object): + supportIndefLenMode = True + + # An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)` + eooIntegerSubstrate = (0, 0) + eooOctetsSubstrate = bytes(eooIntegerSubstrate) + + # noinspection PyMethodMayBeStatic + def encodeTag(self, singleTag, isConstructed): + tagClass, tagFormat, tagId = singleTag + encodedTag = tagClass | tagFormat + if isConstructed: + encodedTag |= tag.tagFormatConstructed + + if tagId < 31: + return encodedTag | tagId, + + else: + substrate = tagId & 0x7f, + + tagId >>= 7 + + while tagId: + substrate = (0x80 | (tagId & 0x7f),) + substrate + tagId >>= 7 + + return (encodedTag | 0x1F,) + substrate + + def encodeLength(self, length, defMode): + if not defMode and self.supportIndefLenMode: + return (0x80,) + + if length < 0x80: + return length, + + else: + substrate = () + while length: + substrate = (length & 0xff,) + substrate + length >>= 8 + + substrateLen = len(substrate) + + if substrateLen > 126: + raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen) + + return (0x80 | substrateLen,) + substrate + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + raise error.PyAsn1Error('Not implemented') + + def encode(self, value, asn1Spec=None, encodeFun=None, **options): + + if asn1Spec is None: + tagSet = value.tagSet + else: + tagSet = asn1Spec.tagSet + + # untagged item? + if not tagSet: + substrate, isConstructed, isOctets = self.encodeValue( + value, asn1Spec, encodeFun, **options + ) + return substrate + + defMode = options.get('defMode', True) + + substrate = b'' + + for idx, singleTag in enumerate(tagSet.superTags): + + defModeOverride = defMode + + # base tag? + if not idx: + try: + substrate, isConstructed, isOctets = self.encodeValue( + value, asn1Spec, encodeFun, **options + ) + + except error.PyAsn1Error as exc: + raise error.PyAsn1Error( + 'Error encoding %r: %s' % (value, exc)) + + if LOG: + LOG('encoded %svalue %s into %s' % ( + isConstructed and 'constructed ' or '', value, substrate + )) + + if not substrate and isConstructed and options.get('ifNotEmpty', False): + return substrate + + if not isConstructed: + defModeOverride = True + + if LOG: + LOG('overridden encoding mode into definitive for primitive type') + + header = self.encodeTag(singleTag, isConstructed) + + if LOG: + LOG('encoded %stag %s into %s' % ( + isConstructed and 'constructed ' or '', + singleTag, debug.hexdump(bytes(header)))) + + header += self.encodeLength(len(substrate), defModeOverride) + + if LOG: + LOG('encoded %s octets (tag + payload) into %s' % ( + len(substrate), debug.hexdump(bytes(header)))) + + if isOctets: + substrate = bytes(header) + substrate + + if not defModeOverride: + substrate += self.eooOctetsSubstrate + + else: + substrate = header + substrate + + if not defModeOverride: + substrate += self.eooIntegerSubstrate + + if not isOctets: + substrate = bytes(substrate) + + return substrate + + +class EndOfOctetsEncoder(AbstractItemEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + return b'', False, True + + +class BooleanEncoder(AbstractItemEncoder): + supportIndefLenMode = False + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + return value and (1,) or (0,), False, False + + +class IntegerEncoder(AbstractItemEncoder): + supportIndefLenMode = False + supportCompactZero = False + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if value == 0: + if LOG: + LOG('encoding %spayload for zero INTEGER' % ( + self.supportCompactZero and 'no ' or '' + )) + + # de-facto way to encode zero + if self.supportCompactZero: + return (), False, False + else: + return (0,), False, False + + return to_bytes(int(value), signed=True), False, True + + +class BitStringEncoder(AbstractItemEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is not None: + # TODO: try to avoid ASN.1 schema instantiation + value = asn1Spec.clone(value) + + valueLength = len(value) + if valueLength % 8: + alignedValue = value << (8 - valueLength % 8) + else: + alignedValue = value + + maxChunkSize = options.get('maxChunkSize', 0) + if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8: + substrate = alignedValue.asOctets() + return bytes((len(substrate) * 8 - valueLength,)) + substrate, False, True + + if LOG: + LOG('encoding into up to %s-octet chunks' % maxChunkSize) + + baseTag = value.tagSet.baseTag + + # strip off explicit tags + if baseTag: + tagSet = tag.TagSet(baseTag, baseTag) + + else: + tagSet = tag.TagSet() + + alignedValue = alignedValue.clone(tagSet=tagSet) + + stop = 0 + substrate = b'' + while stop < valueLength: + start = stop + stop = min(start + maxChunkSize * 8, valueLength) + substrate += encodeFun(alignedValue[start:stop], asn1Spec, **options) + + return substrate, True, True + + +class OctetStringEncoder(AbstractItemEncoder): + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + + if asn1Spec is None: + substrate = value.asOctets() + + elif not isinstance(value, bytes): + substrate = asn1Spec.clone(value).asOctets() + + else: + substrate = value + + maxChunkSize = options.get('maxChunkSize', 0) + + if not maxChunkSize or len(substrate) <= maxChunkSize: + return substrate, False, True + + if LOG: + LOG('encoding into up to %s-octet chunks' % maxChunkSize) + + # strip off explicit tags for inner chunks + + if asn1Spec is None: + baseTag = value.tagSet.baseTag + + # strip off explicit tags + if baseTag: + tagSet = tag.TagSet(baseTag, baseTag) + + else: + tagSet = tag.TagSet() + + asn1Spec = value.clone(tagSet=tagSet) + + elif not isinstance(value, bytes): + baseTag = asn1Spec.tagSet.baseTag + + # strip off explicit tags + if baseTag: + tagSet = tag.TagSet(baseTag, baseTag) + + else: + tagSet = tag.TagSet() + + asn1Spec = asn1Spec.clone(tagSet=tagSet) + + pos = 0 + substrate = b'' + + while True: + chunk = value[pos:pos + maxChunkSize] + if not chunk: + break + + substrate += encodeFun(chunk, asn1Spec, **options) + pos += maxChunkSize + + return substrate, True, True + + +class NullEncoder(AbstractItemEncoder): + supportIndefLenMode = False + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + return b'', False, True + + +class ObjectIdentifierEncoder(AbstractItemEncoder): + supportIndefLenMode = False + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is not None: + value = asn1Spec.clone(value) + + oid = value.asTuple() + + # Build the first pair + try: + first = oid[0] + second = oid[1] + + except IndexError: + raise error.PyAsn1Error('Short OID %s' % (value,)) + + if 0 <= second <= 39: + if first == 1: + oid = (second + 40,) + oid[2:] + elif first == 0: + oid = (second,) + oid[2:] + elif first == 2: + oid = (second + 80,) + oid[2:] + else: + raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) + + elif first == 2: + oid = (second + 80,) + oid[2:] + + else: + raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) + + octets = [] + + # Cycle through subIds + for subOid in oid: + if 0 <= subOid <= 127: + # Optimize for the common case + octets.append(subOid) + + elif subOid > 127: + # Pack large Sub-Object IDs + res = [subOid & 0x7f] + subOid >>= 7 + + while subOid: + res.append(0x80 | (subOid & 0x7f)) + subOid >>= 7 + + # Add packed Sub-Object ID to resulted Object ID + octets.extend(reversed(res)) + + else: + raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value)) + + return tuple(octets), False, False + + +class RelativeOIDEncoder(AbstractItemEncoder): + supportIndefLenMode = False + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is not None: + value = asn1Spec.clone(value) + + octets = [] + + # Cycle through subIds + for subOid in value.asTuple(): + if 0 <= subOid <= 127: + # Optimize for the common case + octets.append(subOid) + + elif subOid > 127: + # Pack large Sub-Object IDs + res = [subOid & 0x7f] + subOid >>= 7 + + while subOid: + res.append(0x80 | (subOid & 0x7f)) + subOid >>= 7 + + # Add packed Sub-Object ID to resulted RELATIVE-OID + octets.extend(reversed(res)) + + else: + raise error.PyAsn1Error('Negative RELATIVE-OID arc %s at %s' % (subOid, value)) + + return tuple(octets), False, False + + +class RealEncoder(AbstractItemEncoder): + supportIndefLenMode = False + binEncBase = 2 # set to None to choose encoding base automatically + + @staticmethod + def _dropFloatingPoint(m, encbase, e): + ms, es = 1, 1 + if m < 0: + ms = -1 # mantissa sign + + if e < 0: + es = -1 # exponent sign + + m *= ms + + if encbase == 8: + m *= 2 ** (abs(e) % 3 * es) + e = abs(e) // 3 * es + + elif encbase == 16: + m *= 2 ** (abs(e) % 4 * es) + e = abs(e) // 4 * es + + while True: + if int(m) != m: + m *= encbase + e -= 1 + continue + break + + return ms, int(m), encbase, e + + def _chooseEncBase(self, value): + m, b, e = value + encBase = [2, 8, 16] + if value.binEncBase in encBase: + return self._dropFloatingPoint(m, value.binEncBase, e) + + elif self.binEncBase in encBase: + return self._dropFloatingPoint(m, self.binEncBase, e) + + # auto choosing base 2/8/16 + mantissa = [m, m, m] + exponent = [e, e, e] + sign = 1 + encbase = 2 + e = float('inf') + + for i in range(3): + (sign, + mantissa[i], + encBase[i], + exponent[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponent[i]) + + if abs(exponent[i]) < abs(e) or (abs(exponent[i]) == abs(e) and mantissa[i] < m): + e = exponent[i] + m = int(mantissa[i]) + encbase = encBase[i] + + if LOG: + LOG('automatically chosen REAL encoding base %s, sign %s, mantissa %s, ' + 'exponent %s' % (encbase, sign, m, e)) + + return sign, m, encbase, e + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is not None: + value = asn1Spec.clone(value) + + if value.isPlusInf: + return (0x40,), False, False + + if value.isMinusInf: + return (0x41,), False, False + + m, b, e = value + + if not m: + return b'', False, True + + if b == 10: + if LOG: + LOG('encoding REAL into character form') + + return b'\x03%dE%s%d' % (m, e == 0 and b'+' or b'', e), False, True + + elif b == 2: + fo = 0x80 # binary encoding + ms, m, encbase, e = self._chooseEncBase(value) + + if ms < 0: # mantissa sign + fo |= 0x40 # sign bit + + # exponent & mantissa normalization + if encbase == 2: + while m & 0x1 == 0: + m >>= 1 + e += 1 + + elif encbase == 8: + while m & 0x7 == 0: + m >>= 3 + e += 1 + fo |= 0x10 + + else: # encbase = 16 + while m & 0xf == 0: + m >>= 4 + e += 1 + fo |= 0x20 + + sf = 0 # scale factor + + while m & 0x1 == 0: + m >>= 1 + sf += 1 + + if sf > 3: + raise error.PyAsn1Error('Scale factor overflow') # bug if raised + + fo |= sf << 2 + eo = b'' + if e == 0 or e == -1: + eo = bytes((e & 0xff,)) + + else: + while e not in (0, -1): + eo = bytes((e & 0xff,)) + eo + e >>= 8 + + if e == 0 and eo and eo[0] & 0x80: + eo = bytes((0,)) + eo + + if e == -1 and eo and not (eo[0] & 0x80): + eo = bytes((0xff,)) + eo + + n = len(eo) + if n > 0xff: + raise error.PyAsn1Error('Real exponent overflow') + + if n == 1: + pass + + elif n == 2: + fo |= 1 + + elif n == 3: + fo |= 2 + + else: + fo |= 3 + eo = bytes((n & 0xff,)) + eo + + po = b'' + + while m: + po = bytes((m & 0xff,)) + po + m >>= 8 + + substrate = bytes((fo,)) + eo + po + + return substrate, False, True + + else: + raise error.PyAsn1Error('Prohibited Real base %s' % b) + + +class SequenceEncoder(AbstractItemEncoder): + omitEmptyOptionals = False + + # TODO: handling three flavors of input is too much -- split over codecs + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + + substrate = b'' + + omitEmptyOptionals = options.get( + 'omitEmptyOptionals', self.omitEmptyOptionals) + + if LOG: + LOG('%sencoding empty OPTIONAL components' % ( + omitEmptyOptionals and 'not ' or '')) + + if asn1Spec is None: + # instance of ASN.1 schema + inconsistency = value.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {value.__class__.__name__} is inconsistent") + + namedTypes = value.componentType + + for idx, component in enumerate(value.values()): + if namedTypes: + namedType = namedTypes[idx] + + if namedType.isOptional and not component.isValue: + if LOG: + LOG('not encoding OPTIONAL component %r' % (namedType,)) + continue + + if namedType.isDefaulted and component == namedType.asn1Object: + if LOG: + LOG('not encoding DEFAULT component %r' % (namedType,)) + continue + + if omitEmptyOptionals: + options.update(ifNotEmpty=namedType.isOptional) + + # wrap open type blob if needed + if namedTypes and namedType.openType: + + wrapType = namedType.asn1Object + + if wrapType.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + substrate += encodeFun( + component, asn1Spec, + **dict(options, wrapType=wrapType.componentType)) + + else: + chunk = encodeFun(component, asn1Spec, **options) + + if wrapType.isSameTypeWith(component): + substrate += chunk + + else: + substrate += encodeFun(chunk, wrapType, **options) + + if LOG: + LOG('wrapped with wrap type %r' % (wrapType,)) + + else: + substrate += encodeFun(component, asn1Spec, **options) + + else: + # bare Python value + ASN.1 schema + for idx, namedType in enumerate(asn1Spec.componentType.namedTypes): + + try: + component = value[namedType.name] + + except KeyError: + raise error.PyAsn1Error('Component name "%s" not found in %r' % ( + namedType.name, value)) + + if namedType.isOptional and namedType.name not in value: + if LOG: + LOG('not encoding OPTIONAL component %r' % (namedType,)) + continue + + if namedType.isDefaulted and component == namedType.asn1Object: + if LOG: + LOG('not encoding DEFAULT component %r' % (namedType,)) + continue + + if omitEmptyOptionals: + options.update(ifNotEmpty=namedType.isOptional) + + componentSpec = namedType.asn1Object + + # wrap open type blob if needed + if namedType.openType: + + if componentSpec.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + substrate += encodeFun( + component, componentSpec, + **dict(options, wrapType=componentSpec.componentType)) + + else: + chunk = encodeFun(component, componentSpec, **options) + + if componentSpec.isSameTypeWith(component): + substrate += chunk + + else: + substrate += encodeFun(chunk, componentSpec, **options) + + if LOG: + LOG('wrapped with wrap type %r' % (componentSpec,)) + + else: + substrate += encodeFun(component, componentSpec, **options) + + return substrate, True, True + + +class SequenceOfEncoder(AbstractItemEncoder): + def _encodeComponents(self, value, asn1Spec, encodeFun, **options): + + if asn1Spec is None: + inconsistency = value.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {value.__class__.__name__} is inconsistent") + + else: + asn1Spec = asn1Spec.componentType + + chunks = [] + + wrapType = options.pop('wrapType', None) + + for idx, component in enumerate(value): + chunk = encodeFun(component, asn1Spec, **options) + + if (wrapType is not None and + not wrapType.isSameTypeWith(component)): + # wrap encoded value with wrapper container (e.g. ANY) + chunk = encodeFun(chunk, wrapType, **options) + + if LOG: + LOG('wrapped with wrap type %r' % (wrapType,)) + + chunks.append(chunk) + + return chunks + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + return b''.join(chunks), True, True + + +class ChoiceEncoder(AbstractItemEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is None: + component = value.getComponent() + else: + names = [namedType.name for namedType in asn1Spec.componentType.namedTypes + if namedType.name in value] + if len(names) != 1: + raise error.PyAsn1Error('%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', value)) + + name = names[0] + + component = value[name] + asn1Spec = asn1Spec[name] + + return encodeFun(component, asn1Spec, **options), True, True + + +class AnyEncoder(OctetStringEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is None: + value = value.asOctets() + elif not isinstance(value, bytes): + value = asn1Spec.clone(value).asOctets() + + return value, not options.get('defMode', True), True + + +TAG_MAP = { + eoo.endOfOctets.tagSet: EndOfOctetsEncoder(), + univ.Boolean.tagSet: BooleanEncoder(), + univ.Integer.tagSet: IntegerEncoder(), + univ.BitString.tagSet: BitStringEncoder(), + univ.OctetString.tagSet: OctetStringEncoder(), + univ.Null.tagSet: NullEncoder(), + univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(), + univ.RelativeOID.tagSet: RelativeOIDEncoder(), + univ.Enumerated.tagSet: IntegerEncoder(), + univ.Real.tagSet: RealEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.SequenceOf.tagSet: SequenceOfEncoder(), + univ.SetOf.tagSet: SequenceOfEncoder(), + univ.Choice.tagSet: ChoiceEncoder(), + # character string types + char.UTF8String.tagSet: OctetStringEncoder(), + char.NumericString.tagSet: OctetStringEncoder(), + char.PrintableString.tagSet: OctetStringEncoder(), + char.TeletexString.tagSet: OctetStringEncoder(), + char.VideotexString.tagSet: OctetStringEncoder(), + char.IA5String.tagSet: OctetStringEncoder(), + char.GraphicString.tagSet: OctetStringEncoder(), + char.VisibleString.tagSet: OctetStringEncoder(), + char.GeneralString.tagSet: OctetStringEncoder(), + char.UniversalString.tagSet: OctetStringEncoder(), + char.BMPString.tagSet: OctetStringEncoder(), + # useful types + useful.ObjectDescriptor.tagSet: OctetStringEncoder(), + useful.GeneralizedTime.tagSet: OctetStringEncoder(), + useful.UTCTime.tagSet: OctetStringEncoder() +} + +# Put in ambiguous & non-ambiguous types for faster codec lookup +TYPE_MAP = { + univ.Boolean.typeId: BooleanEncoder(), + univ.Integer.typeId: IntegerEncoder(), + univ.BitString.typeId: BitStringEncoder(), + univ.OctetString.typeId: OctetStringEncoder(), + univ.Null.typeId: NullEncoder(), + univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(), + univ.RelativeOID.typeId: RelativeOIDEncoder(), + univ.Enumerated.typeId: IntegerEncoder(), + univ.Real.typeId: RealEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.Set.typeId: SequenceEncoder(), + univ.SetOf.typeId: SequenceOfEncoder(), + univ.Sequence.typeId: SequenceEncoder(), + univ.SequenceOf.typeId: SequenceOfEncoder(), + univ.Choice.typeId: ChoiceEncoder(), + univ.Any.typeId: AnyEncoder(), + # character string types + char.UTF8String.typeId: OctetStringEncoder(), + char.NumericString.typeId: OctetStringEncoder(), + char.PrintableString.typeId: OctetStringEncoder(), + char.TeletexString.typeId: OctetStringEncoder(), + char.VideotexString.typeId: OctetStringEncoder(), + char.IA5String.typeId: OctetStringEncoder(), + char.GraphicString.typeId: OctetStringEncoder(), + char.VisibleString.typeId: OctetStringEncoder(), + char.GeneralString.typeId: OctetStringEncoder(), + char.UniversalString.typeId: OctetStringEncoder(), + char.BMPString.typeId: OctetStringEncoder(), + # useful types + useful.ObjectDescriptor.typeId: OctetStringEncoder(), + useful.GeneralizedTime.typeId: OctetStringEncoder(), + useful.UTCTime.typeId: OctetStringEncoder() +} + + +class SingleItemEncoder(object): + fixedDefLengthMode = None + fixedChunkSize = None + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **ignored): + self._tagMap = tagMap if tagMap is not _MISSING else self.TAG_MAP + self._typeMap = typeMap if typeMap is not _MISSING else self.TYPE_MAP + + def __call__(self, value, asn1Spec=None, **options): + try: + if asn1Spec is None: + typeId = value.typeId + else: + typeId = asn1Spec.typeId + + except AttributeError: + raise error.PyAsn1Error('Value %r is not ASN.1 type instance ' + 'and "asn1Spec" not given' % (value,)) + + if LOG: + LOG('encoder called in %sdef mode, chunk size %s for type %s, ' + 'value:\n%s' % (not options.get('defMode', True) and 'in' or '', + options.get('maxChunkSize', 0), + asn1Spec is None and value.prettyPrintType() or + asn1Spec.prettyPrintType(), value)) + + if self.fixedDefLengthMode is not None: + options.update(defMode=self.fixedDefLengthMode) + + if self.fixedChunkSize is not None: + options.update(maxChunkSize=self.fixedChunkSize) + + try: + concreteEncoder = self._typeMap[typeId] + + if LOG: + LOG('using value codec %s chosen by type ID ' + '%s' % (concreteEncoder.__class__.__name__, typeId)) + + except KeyError: + if asn1Spec is None: + tagSet = value.tagSet + else: + tagSet = asn1Spec.tagSet + + # use base type for codec lookup to recover untagged types + baseTagSet = tag.TagSet(tagSet.baseTag, tagSet.baseTag) + + try: + concreteEncoder = self._tagMap[baseTagSet] + + except KeyError: + raise error.PyAsn1Error('No encoder for %r (%s)' % (value, tagSet)) + + if LOG: + LOG('using value codec %s chosen by tagSet ' + '%s' % (concreteEncoder.__class__.__name__, tagSet)) + + substrate = concreteEncoder.encode(value, asn1Spec, self, **options) + + if LOG: + LOG('codec %s built %s octets of substrate: %s\nencoder ' + 'completed' % (concreteEncoder, len(substrate), + debug.hexdump(substrate))) + + return substrate + + +class Encoder(object): + SINGLE_ITEM_ENCODER = SingleItemEncoder + + def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **options): + self._singleItemEncoder = self.SINGLE_ITEM_ENCODER( + tagMap=tagMap, typeMap=typeMap, **options + ) + + def __call__(self, pyObject, asn1Spec=None, **options): + return self._singleItemEncoder( + pyObject, asn1Spec=asn1Spec, **options) + + +#: Turns ASN.1 object into BER octet stream. +#: +#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: walks all its components recursively and produces a BER octet stream. +#: +#: Parameters +#: ---------- +#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec` +#: parameter is required to guide the encoding process. +#: +#: Keyword Args +#: ------------ +#: asn1Spec: +#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: +#: defMode: :py:class:`bool` +#: If :obj:`False`, produces indefinite length encoding +#: +#: maxChunkSize: :py:class:`int` +#: Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size) +#: +#: Returns +#: ------- +#: : :py:class:`bytes` +#: Given ASN.1 object encoded into BER octetstream +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error +#: On encoding errors +#: +#: Examples +#: -------- +#: Encode Python value into BER with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> encode([1, 2, 3], asn1Spec=seq) +#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03' +#: +#: Encode ASN.1 value object into BER +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> seq.extend([1, 2, 3]) +#: >>> encode(seq) +#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03' +#: +encode = Encoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/eoo.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/eoo.py new file mode 100644 index 00000000..8c91a3d2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/ber/eoo.py @@ -0,0 +1,28 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +from pyasn1.type import base +from pyasn1.type import tag + +__all__ = ['endOfOctets'] + + +class EndOfOctets(base.SimpleAsn1Type): + defaultValue = 0 + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00) + ) + + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = object.__new__(cls, *args, **kwargs) + + return cls._instance + + +endOfOctets = EndOfOctets() diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/decoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/decoder.py new file mode 100644 index 00000000..46104468 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/decoder.py @@ -0,0 +1,149 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import warnings + +from pyasn1 import error +from pyasn1.codec.streaming import readFromStream +from pyasn1.codec.ber import decoder +from pyasn1.type import univ + +__all__ = ['decode', 'StreamingDecoder'] + +SubstrateUnderrunError = error.SubstrateUnderrunError + + +class BooleanPayloadDecoder(decoder.AbstractSimplePayloadDecoder): + protoComponent = univ.Boolean(0) + + def valueDecoder(self, substrate, asn1Spec, + tagSet=None, length=None, state=None, + decodeFun=None, substrateFun=None, + **options): + + if length != 1: + raise error.PyAsn1Error('Not single-octet Boolean payload') + + for chunk in readFromStream(substrate, length, options): + if isinstance(chunk, SubstrateUnderrunError): + yield chunk + + byte = chunk[0] + + # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while + # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1 + # in https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + if byte == 0xff: + value = 1 + + elif byte == 0x00: + value = 0 + + else: + raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte) + + yield self._createComponent(asn1Spec, tagSet, value, **options) + + +# TODO: prohibit non-canonical encoding +BitStringPayloadDecoder = decoder.BitStringPayloadDecoder +OctetStringPayloadDecoder = decoder.OctetStringPayloadDecoder +RealPayloadDecoder = decoder.RealPayloadDecoder + +TAG_MAP = decoder.TAG_MAP.copy() +TAG_MAP.update( + {univ.Boolean.tagSet: BooleanPayloadDecoder(), + univ.BitString.tagSet: BitStringPayloadDecoder(), + univ.OctetString.tagSet: OctetStringPayloadDecoder(), + univ.Real.tagSet: RealPayloadDecoder()} +) + +TYPE_MAP = decoder.TYPE_MAP.copy() + +# Put in non-ambiguous types for faster codec lookup +for typeDecoder in TAG_MAP.values(): + if typeDecoder.protoComponent is not None: + typeId = typeDecoder.protoComponent.__class__.typeId + if typeId is not None and typeId not in TYPE_MAP: + TYPE_MAP[typeId] = typeDecoder + + +class SingleItemDecoder(decoder.SingleItemDecoder): + __doc__ = decoder.SingleItemDecoder.__doc__ + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + +class StreamingDecoder(decoder.StreamingDecoder): + __doc__ = decoder.StreamingDecoder.__doc__ + + SINGLE_ITEM_DECODER = SingleItemDecoder + + +class Decoder(decoder.Decoder): + __doc__ = decoder.Decoder.__doc__ + + STREAMING_DECODER = StreamingDecoder + + +#: Turns CER octet stream into an ASN.1 object. +#: +#: Takes CER octet-stream and decode it into an ASN.1 object +#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which +#: may be a scalar or an arbitrary nested structure. +#: +#: Parameters +#: ---------- +#: substrate: :py:class:`bytes` +#: CER octet-stream +#: +#: Keyword Args +#: ------------ +#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure +#: being decoded, *asn1Spec* may or may not be required. Most common reason for +#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode. +#: +#: Returns +#: ------- +#: : :py:class:`tuple` +#: A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: and the unprocessed trailing portion of the *substrate* (may be empty) +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError +#: On decoding errors +#: +#: Examples +#: -------- +#: Decode CER serialisation without ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00') +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +#: Decode CER serialisation with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00', asn1Spec=seq) +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +decode = Decoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/encoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/encoder.py new file mode 100644 index 00000000..15a80645 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/cer/encoder.py @@ -0,0 +1,331 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import warnings + +from pyasn1 import error +from pyasn1.codec.ber import encoder +from pyasn1.type import univ +from pyasn1.type import useful + +__all__ = ['Encoder', 'encode'] + + +class BooleanEncoder(encoder.IntegerEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + if value == 0: + substrate = (0,) + else: + substrate = (255,) + return substrate, False, False + + +class RealEncoder(encoder.RealEncoder): + def _chooseEncBase(self, value): + m, b, e = value + return self._dropFloatingPoint(m, b, e) + + +# specialized GeneralStringEncoder here + +class TimeEncoderMixIn(object): + Z_CHAR = ord('Z') + PLUS_CHAR = ord('+') + MINUS_CHAR = ord('-') + COMMA_CHAR = ord(',') + DOT_CHAR = ord('.') + ZERO_CHAR = ord('0') + + MIN_LENGTH = 12 + MAX_LENGTH = 19 + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + # CER encoding constraints: + # - minutes are mandatory, seconds are optional + # - sub-seconds must NOT be zero / no meaningless zeros + # - no hanging fraction dot + # - time in UTC (Z) + # - only dot is allowed for fractions + + if asn1Spec is not None: + value = asn1Spec.clone(value) + + numbers = value.asNumbers() + + if self.PLUS_CHAR in numbers or self.MINUS_CHAR in numbers: + raise error.PyAsn1Error('Must be UTC time: %r' % value) + + if numbers[-1] != self.Z_CHAR: + raise error.PyAsn1Error('Missing "Z" time zone specifier: %r' % value) + + if self.COMMA_CHAR in numbers: + raise error.PyAsn1Error('Comma in fractions disallowed: %r' % value) + + if self.DOT_CHAR in numbers: + + isModified = False + + numbers = list(numbers) + + searchIndex = min(numbers.index(self.DOT_CHAR) + 4, len(numbers) - 1) + + while numbers[searchIndex] != self.DOT_CHAR: + if numbers[searchIndex] == self.ZERO_CHAR: + del numbers[searchIndex] + isModified = True + + searchIndex -= 1 + + searchIndex += 1 + + if searchIndex < len(numbers): + if numbers[searchIndex] == self.Z_CHAR: + # drop hanging comma + del numbers[searchIndex - 1] + isModified = True + + if isModified: + value = value.clone(numbers) + + if not self.MIN_LENGTH < len(numbers) < self.MAX_LENGTH: + raise error.PyAsn1Error('Length constraint violated: %r' % value) + + options.update(maxChunkSize=1000) + + return encoder.OctetStringEncoder.encodeValue( + self, value, asn1Spec, encodeFun, **options + ) + + +class GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder): + MIN_LENGTH = 12 + MAX_LENGTH = 20 + + +class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder): + MIN_LENGTH = 10 + MAX_LENGTH = 14 + + +class SetOfEncoder(encoder.SequenceOfEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + # sort by serialised and padded components + if len(chunks) > 1: + zero = b'\x00' + maxLen = max(map(len, chunks)) + paddedChunks = [ + (x.ljust(maxLen, zero), x) for x in chunks + ] + paddedChunks.sort(key=lambda x: x[0]) + + chunks = [x[1] for x in paddedChunks] + + return b''.join(chunks), True, True + + +class SequenceOfEncoder(encoder.SequenceOfEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + + if options.get('ifNotEmpty', False) and not len(value): + return b'', True, True + + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + return b''.join(chunks), True, True + + +class SetEncoder(encoder.SequenceEncoder): + @staticmethod + def _componentSortKey(componentAndType): + """Sort SET components by tag + + Sort regardless of the Choice value (static sort) + """ + component, asn1Spec = componentAndType + + if asn1Spec is None: + asn1Spec = component + + if asn1Spec.typeId == univ.Choice.typeId and not asn1Spec.tagSet: + if asn1Spec.tagSet: + return asn1Spec.tagSet + else: + return asn1Spec.componentType.minTagSet + else: + return asn1Spec.tagSet + + def encodeValue(self, value, asn1Spec, encodeFun, **options): + + substrate = b'' + + comps = [] + compsMap = {} + + if asn1Spec is None: + # instance of ASN.1 schema + inconsistency = value.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {value.__class__.__name__} is inconsistent") + + namedTypes = value.componentType + + for idx, component in enumerate(value.values()): + if namedTypes: + namedType = namedTypes[idx] + + if namedType.isOptional and not component.isValue: + continue + + if namedType.isDefaulted and component == namedType.asn1Object: + continue + + compsMap[id(component)] = namedType + + else: + compsMap[id(component)] = None + + comps.append((component, asn1Spec)) + + else: + # bare Python value + ASN.1 schema + for idx, namedType in enumerate(asn1Spec.componentType.namedTypes): + + try: + component = value[namedType.name] + + except KeyError: + raise error.PyAsn1Error('Component name "%s" not found in %r' % (namedType.name, value)) + + if namedType.isOptional and namedType.name not in value: + continue + + if namedType.isDefaulted and component == namedType.asn1Object: + continue + + compsMap[id(component)] = namedType + comps.append((component, asn1Spec[idx])) + + for comp, compType in sorted(comps, key=self._componentSortKey): + namedType = compsMap[id(comp)] + + if namedType: + options.update(ifNotEmpty=namedType.isOptional) + + chunk = encodeFun(comp, compType, **options) + + # wrap open type blob if needed + if namedType and namedType.openType: + wrapType = namedType.asn1Object + if wrapType.tagSet and not wrapType.isSameTypeWith(comp): + chunk = encodeFun(chunk, wrapType, **options) + + substrate += chunk + + return substrate, True, True + + +class SequenceEncoder(encoder.SequenceEncoder): + omitEmptyOptionals = True + + +TAG_MAP = encoder.TAG_MAP.copy() + +TAG_MAP.update({ + univ.Boolean.tagSet: BooleanEncoder(), + univ.Real.tagSet: RealEncoder(), + useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(), + useful.UTCTime.tagSet: UTCTimeEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.SetOf.tagSet: SetOfEncoder(), + univ.Sequence.typeId: SequenceEncoder() +}) + +TYPE_MAP = encoder.TYPE_MAP.copy() + +TYPE_MAP.update({ + univ.Boolean.typeId: BooleanEncoder(), + univ.Real.typeId: RealEncoder(), + useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(), + useful.UTCTime.typeId: UTCTimeEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.Set.typeId: SetEncoder(), + univ.SetOf.typeId: SetOfEncoder(), + univ.Sequence.typeId: SequenceEncoder(), + univ.SequenceOf.typeId: SequenceOfEncoder() +}) + + +class SingleItemEncoder(encoder.SingleItemEncoder): + fixedDefLengthMode = False + fixedChunkSize = 1000 + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + +class Encoder(encoder.Encoder): + SINGLE_ITEM_ENCODER = SingleItemEncoder + + +#: Turns ASN.1 object into CER octet stream. +#: +#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: walks all its components recursively and produces a CER octet stream. +#: +#: Parameters +#: ---------- +#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec` +#: parameter is required to guide the encoding process. +#: +#: Keyword Args +#: ------------ +#: asn1Spec: +#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: +#: Returns +#: ------- +#: : :py:class:`bytes` +#: Given ASN.1 object encoded into BER octet-stream +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error +#: On encoding errors +#: +#: Examples +#: -------- +#: Encode Python value into CER with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> encode([1, 2, 3], asn1Spec=seq) +#: b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00' +#: +#: Encode ASN.1 value object into CER +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> seq.extend([1, 2, 3]) +#: >>> encode(seq) +#: b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00' +#: +encode = Encoder() + +# EncoderFactory queries class instance and builds a map of tags -> encoders + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/der/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/der/decoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/decoder.py new file mode 100644 index 00000000..2bef454f --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/decoder.py @@ -0,0 +1,120 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import warnings + +from pyasn1.codec.cer import decoder +from pyasn1.type import univ + +__all__ = ['decode', 'StreamingDecoder'] + + +class BitStringPayloadDecoder(decoder.BitStringPayloadDecoder): + supportConstructedForm = False + + +class OctetStringPayloadDecoder(decoder.OctetStringPayloadDecoder): + supportConstructedForm = False + + +# TODO: prohibit non-canonical encoding +RealPayloadDecoder = decoder.RealPayloadDecoder + +TAG_MAP = decoder.TAG_MAP.copy() +TAG_MAP.update( + {univ.BitString.tagSet: BitStringPayloadDecoder(), + univ.OctetString.tagSet: OctetStringPayloadDecoder(), + univ.Real.tagSet: RealPayloadDecoder()} +) + +TYPE_MAP = decoder.TYPE_MAP.copy() + +# Put in non-ambiguous types for faster codec lookup +for typeDecoder in TAG_MAP.values(): + if typeDecoder.protoComponent is not None: + typeId = typeDecoder.protoComponent.__class__.typeId + if typeId is not None and typeId not in TYPE_MAP: + TYPE_MAP[typeId] = typeDecoder + + +class SingleItemDecoder(decoder.SingleItemDecoder): + __doc__ = decoder.SingleItemDecoder.__doc__ + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + supportIndefLength = False + + +class StreamingDecoder(decoder.StreamingDecoder): + __doc__ = decoder.StreamingDecoder.__doc__ + + SINGLE_ITEM_DECODER = SingleItemDecoder + + +class Decoder(decoder.Decoder): + __doc__ = decoder.Decoder.__doc__ + + STREAMING_DECODER = StreamingDecoder + + +#: Turns DER octet stream into an ASN.1 object. +#: +#: Takes DER octet-stream and decode it into an ASN.1 object +#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which +#: may be a scalar or an arbitrary nested structure. +#: +#: Parameters +#: ---------- +#: substrate: :py:class:`bytes` +#: DER octet-stream +#: +#: Keyword Args +#: ------------ +#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure +#: being decoded, *asn1Spec* may or may not be required. Most common reason for +#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode. +#: +#: Returns +#: ------- +#: : :py:class:`tuple` +#: A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: and the unprocessed trailing portion of the *substrate* (may be empty) +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError +#: On decoding errors +#: +#: Examples +#: -------- +#: Decode DER serialisation without ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03') +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +#: Decode DER serialisation with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq) +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +decode = Decoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/der/encoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/encoder.py new file mode 100644 index 00000000..8e00138d --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/der/encoder.py @@ -0,0 +1,126 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import warnings + +from pyasn1 import error +from pyasn1.codec.cer import encoder +from pyasn1.type import univ + +__all__ = ['Encoder', 'encode'] + + +class SetEncoder(encoder.SetEncoder): + @staticmethod + def _componentSortKey(componentAndType): + """Sort SET components by tag + + Sort depending on the actual Choice value (dynamic sort) + """ + component, asn1Spec = componentAndType + + if asn1Spec is None: + compType = component + else: + compType = asn1Spec + + if compType.typeId == univ.Choice.typeId and not compType.tagSet: + if asn1Spec is None: + return component.getComponent().tagSet + else: + # TODO: move out of sorting key function + names = [namedType.name for namedType in asn1Spec.componentType.namedTypes + if namedType.name in component] + if len(names) != 1: + raise error.PyAsn1Error( + '%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', component)) + + # TODO: support nested CHOICE ordering + return asn1Spec[names[0]].tagSet + + else: + return compType.tagSet + + +TAG_MAP = encoder.TAG_MAP.copy() + +TAG_MAP.update({ + # Set & SetOf have same tags + univ.Set.tagSet: SetEncoder() +}) + +TYPE_MAP = encoder.TYPE_MAP.copy() + +TYPE_MAP.update({ + # Set & SetOf have same tags + univ.Set.typeId: SetEncoder() +}) + + +class SingleItemEncoder(encoder.SingleItemEncoder): + fixedDefLengthMode = True + fixedChunkSize = 0 + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + +class Encoder(encoder.Encoder): + SINGLE_ITEM_ENCODER = SingleItemEncoder + + +#: Turns ASN.1 object into DER octet stream. +#: +#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: walks all its components recursively and produces a DER octet stream. +#: +#: Parameters +#: ---------- +#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec` +#: parameter is required to guide the encoding process. +#: +#: Keyword Args +#: ------------ +#: asn1Spec: +#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: +#: Returns +#: ------- +#: : :py:class:`bytes` +#: Given ASN.1 object encoded into BER octet-stream +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error +#: On encoding errors +#: +#: Examples +#: -------- +#: Encode Python value into DER with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> encode([1, 2, 3], asn1Spec=seq) +#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03' +#: +#: Encode ASN.1 value object into DER +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> seq.extend([1, 2, 3]) +#: >>> encode(seq) +#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03' +#: +encode = Encoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/native/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/native/decoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/decoder.py new file mode 100644 index 00000000..881ce19b --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/decoder.py @@ -0,0 +1,244 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import warnings + +from pyasn1 import debug +from pyasn1 import error +from pyasn1.compat import _MISSING +from pyasn1.type import base +from pyasn1.type import char +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +__all__ = ['decode'] + +LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER) + + +class AbstractScalarPayloadDecoder(object): + def __call__(self, pyObject, asn1Spec, decodeFun=None, **options): + return asn1Spec.clone(pyObject) + + +class BitStringPayloadDecoder(AbstractScalarPayloadDecoder): + def __call__(self, pyObject, asn1Spec, decodeFun=None, **options): + return asn1Spec.clone(univ.BitString.fromBinaryString(pyObject)) + + +class SequenceOrSetPayloadDecoder(object): + def __call__(self, pyObject, asn1Spec, decodeFun=None, **options): + asn1Value = asn1Spec.clone() + + componentsTypes = asn1Spec.componentType + + for field in asn1Value: + if field in pyObject: + asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options) + + return asn1Value + + +class SequenceOfOrSetOfPayloadDecoder(object): + def __call__(self, pyObject, asn1Spec, decodeFun=None, **options): + asn1Value = asn1Spec.clone() + + for pyValue in pyObject: + asn1Value.append(decodeFun(pyValue, asn1Spec.componentType), **options) + + return asn1Value + + +class ChoicePayloadDecoder(object): + def __call__(self, pyObject, asn1Spec, decodeFun=None, **options): + asn1Value = asn1Spec.clone() + + componentsTypes = asn1Spec.componentType + + for field in pyObject: + if field in componentsTypes: + asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options) + break + + return asn1Value + + +TAG_MAP = { + univ.Integer.tagSet: AbstractScalarPayloadDecoder(), + univ.Boolean.tagSet: AbstractScalarPayloadDecoder(), + univ.BitString.tagSet: BitStringPayloadDecoder(), + univ.OctetString.tagSet: AbstractScalarPayloadDecoder(), + univ.Null.tagSet: AbstractScalarPayloadDecoder(), + univ.ObjectIdentifier.tagSet: AbstractScalarPayloadDecoder(), + univ.RelativeOID.tagSet: AbstractScalarPayloadDecoder(), + univ.Enumerated.tagSet: AbstractScalarPayloadDecoder(), + univ.Real.tagSet: AbstractScalarPayloadDecoder(), + univ.Sequence.tagSet: SequenceOrSetPayloadDecoder(), # conflicts with SequenceOf + univ.Set.tagSet: SequenceOrSetPayloadDecoder(), # conflicts with SetOf + univ.Choice.tagSet: ChoicePayloadDecoder(), # conflicts with Any + # character string types + char.UTF8String.tagSet: AbstractScalarPayloadDecoder(), + char.NumericString.tagSet: AbstractScalarPayloadDecoder(), + char.PrintableString.tagSet: AbstractScalarPayloadDecoder(), + char.TeletexString.tagSet: AbstractScalarPayloadDecoder(), + char.VideotexString.tagSet: AbstractScalarPayloadDecoder(), + char.IA5String.tagSet: AbstractScalarPayloadDecoder(), + char.GraphicString.tagSet: AbstractScalarPayloadDecoder(), + char.VisibleString.tagSet: AbstractScalarPayloadDecoder(), + char.GeneralString.tagSet: AbstractScalarPayloadDecoder(), + char.UniversalString.tagSet: AbstractScalarPayloadDecoder(), + char.BMPString.tagSet: AbstractScalarPayloadDecoder(), + # useful types + useful.ObjectDescriptor.tagSet: AbstractScalarPayloadDecoder(), + useful.GeneralizedTime.tagSet: AbstractScalarPayloadDecoder(), + useful.UTCTime.tagSet: AbstractScalarPayloadDecoder() +} + +# Put in ambiguous & non-ambiguous types for faster codec lookup +TYPE_MAP = { + univ.Integer.typeId: AbstractScalarPayloadDecoder(), + univ.Boolean.typeId: AbstractScalarPayloadDecoder(), + univ.BitString.typeId: BitStringPayloadDecoder(), + univ.OctetString.typeId: AbstractScalarPayloadDecoder(), + univ.Null.typeId: AbstractScalarPayloadDecoder(), + univ.ObjectIdentifier.typeId: AbstractScalarPayloadDecoder(), + univ.RelativeOID.typeId: AbstractScalarPayloadDecoder(), + univ.Enumerated.typeId: AbstractScalarPayloadDecoder(), + univ.Real.typeId: AbstractScalarPayloadDecoder(), + # ambiguous base types + univ.Set.typeId: SequenceOrSetPayloadDecoder(), + univ.SetOf.typeId: SequenceOfOrSetOfPayloadDecoder(), + univ.Sequence.typeId: SequenceOrSetPayloadDecoder(), + univ.SequenceOf.typeId: SequenceOfOrSetOfPayloadDecoder(), + univ.Choice.typeId: ChoicePayloadDecoder(), + univ.Any.typeId: AbstractScalarPayloadDecoder(), + # character string types + char.UTF8String.typeId: AbstractScalarPayloadDecoder(), + char.NumericString.typeId: AbstractScalarPayloadDecoder(), + char.PrintableString.typeId: AbstractScalarPayloadDecoder(), + char.TeletexString.typeId: AbstractScalarPayloadDecoder(), + char.VideotexString.typeId: AbstractScalarPayloadDecoder(), + char.IA5String.typeId: AbstractScalarPayloadDecoder(), + char.GraphicString.typeId: AbstractScalarPayloadDecoder(), + char.VisibleString.typeId: AbstractScalarPayloadDecoder(), + char.GeneralString.typeId: AbstractScalarPayloadDecoder(), + char.UniversalString.typeId: AbstractScalarPayloadDecoder(), + char.BMPString.typeId: AbstractScalarPayloadDecoder(), + # useful types + useful.ObjectDescriptor.typeId: AbstractScalarPayloadDecoder(), + useful.GeneralizedTime.typeId: AbstractScalarPayloadDecoder(), + useful.UTCTime.typeId: AbstractScalarPayloadDecoder() +} + + +class SingleItemDecoder(object): + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **ignored): + self._tagMap = tagMap if tagMap is not _MISSING else self.TAG_MAP + self._typeMap = typeMap if typeMap is not _MISSING else self.TYPE_MAP + + def __call__(self, pyObject, asn1Spec, **options): + + if LOG: + debug.scope.push(type(pyObject).__name__) + LOG('decoder called at scope %s, working with ' + 'type %s' % (debug.scope, type(pyObject).__name__)) + + if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item): + raise error.PyAsn1Error( + 'asn1Spec is not valid (should be an instance of an ASN.1 ' + 'Item, not %s)' % asn1Spec.__class__.__name__) + + try: + valueDecoder = self._typeMap[asn1Spec.typeId] + + except KeyError: + # use base type for codec lookup to recover untagged types + baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag) + + try: + valueDecoder = self._tagMap[baseTagSet] + + except KeyError: + raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet) + + if LOG: + LOG('calling decoder %s on Python type %s ' + '<%s>' % (type(valueDecoder).__name__, + type(pyObject).__name__, repr(pyObject))) + + value = valueDecoder(pyObject, asn1Spec, self, **options) + + if LOG: + LOG('decoder %s produced ASN.1 type %s ' + '<%s>' % (type(valueDecoder).__name__, + type(value).__name__, repr(value))) + debug.scope.pop() + + return value + + +class Decoder(object): + SINGLE_ITEM_DECODER = SingleItemDecoder + + def __init__(self, **options): + self._singleItemDecoder = self.SINGLE_ITEM_DECODER(**options) + + def __call__(self, pyObject, asn1Spec=None, **kwargs): + return self._singleItemDecoder(pyObject, asn1Spec=asn1Spec, **kwargs) + + +#: Turns Python objects of built-in types into ASN.1 objects. +#: +#: Takes Python objects of built-in types and turns them into a tree of +#: ASN.1 objects (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which +#: may be a scalar or an arbitrary nested structure. +#: +#: Parameters +#: ---------- +#: pyObject: :py:class:`object` +#: A scalar or nested Python objects +#: +#: Keyword Args +#: ------------ +#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: A pyasn1 type object to act as a template guiding the decoder. It is required +#: for successful interpretation of Python objects mapping into their ASN.1 +#: representations. +#: +#: Returns +#: ------- +#: : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative +#: A scalar or constructed pyasn1 object +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error +#: On decoding errors +#: +#: Examples +#: -------- +#: Decode native Python object into ASN.1 objects with ASN.1 schema +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> s, _ = decode([1, 2, 3], asn1Spec=seq) +#: >>> str(s) +#: SequenceOf: +#: 1 2 3 +#: +decode = Decoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/native/encoder.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/encoder.py new file mode 100644 index 00000000..ed5446bf --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/native/encoder.py @@ -0,0 +1,285 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +from collections import OrderedDict +import warnings + +from pyasn1 import debug +from pyasn1 import error +from pyasn1.compat import _MISSING +from pyasn1.type import base +from pyasn1.type import char +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +__all__ = ['encode'] + +LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_ENCODER) + + +class AbstractItemEncoder(object): + def encode(self, value, encodeFun, **options): + raise error.PyAsn1Error('Not implemented') + + +class BooleanEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return bool(value) + + +class IntegerEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return int(value) + + +class BitStringEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return str(value) + + +class OctetStringEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return value.asOctets() + + +class TextStringEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return str(value) + + +class NullEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return None + + +class ObjectIdentifierEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return str(value) + + +class RelativeOIDEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return str(value) + + +class RealEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return float(value) + + +class SetEncoder(AbstractItemEncoder): + protoDict = dict + + def encode(self, value, encodeFun, **options): + inconsistency = value.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {value.__class__.__name__} is inconsistent") + + namedTypes = value.componentType + substrate = self.protoDict() + + for idx, (key, subValue) in enumerate(value.items()): + if namedTypes and namedTypes[idx].isOptional and not value[idx].isValue: + continue + substrate[key] = encodeFun(subValue, **options) + return substrate + + +class SequenceEncoder(SetEncoder): + protoDict = OrderedDict + + +class SequenceOfEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + inconsistency = value.isInconsistent + if inconsistency: + raise error.PyAsn1Error( + f"ASN.1 object {value.__class__.__name__} is inconsistent") + return [encodeFun(x, **options) for x in value] + + +class ChoiceEncoder(SequenceEncoder): + pass + + +class AnyEncoder(AbstractItemEncoder): + def encode(self, value, encodeFun, **options): + return value.asOctets() + + +TAG_MAP = { + univ.Boolean.tagSet: BooleanEncoder(), + univ.Integer.tagSet: IntegerEncoder(), + univ.BitString.tagSet: BitStringEncoder(), + univ.OctetString.tagSet: OctetStringEncoder(), + univ.Null.tagSet: NullEncoder(), + univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(), + univ.RelativeOID.tagSet: RelativeOIDEncoder(), + univ.Enumerated.tagSet: IntegerEncoder(), + univ.Real.tagSet: RealEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.SequenceOf.tagSet: SequenceOfEncoder(), + univ.SetOf.tagSet: SequenceOfEncoder(), + univ.Choice.tagSet: ChoiceEncoder(), + # character string types + char.UTF8String.tagSet: TextStringEncoder(), + char.NumericString.tagSet: TextStringEncoder(), + char.PrintableString.tagSet: TextStringEncoder(), + char.TeletexString.tagSet: TextStringEncoder(), + char.VideotexString.tagSet: TextStringEncoder(), + char.IA5String.tagSet: TextStringEncoder(), + char.GraphicString.tagSet: TextStringEncoder(), + char.VisibleString.tagSet: TextStringEncoder(), + char.GeneralString.tagSet: TextStringEncoder(), + char.UniversalString.tagSet: TextStringEncoder(), + char.BMPString.tagSet: TextStringEncoder(), + # useful types + useful.ObjectDescriptor.tagSet: OctetStringEncoder(), + useful.GeneralizedTime.tagSet: OctetStringEncoder(), + useful.UTCTime.tagSet: OctetStringEncoder() +} + +# Put in ambiguous & non-ambiguous types for faster codec lookup +TYPE_MAP = { + univ.Boolean.typeId: BooleanEncoder(), + univ.Integer.typeId: IntegerEncoder(), + univ.BitString.typeId: BitStringEncoder(), + univ.OctetString.typeId: OctetStringEncoder(), + univ.Null.typeId: NullEncoder(), + univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(), + univ.RelativeOID.typeId: RelativeOIDEncoder(), + univ.Enumerated.typeId: IntegerEncoder(), + univ.Real.typeId: RealEncoder(), + # Sequence & Set have same tags as SequenceOf & SetOf + univ.Set.typeId: SetEncoder(), + univ.SetOf.typeId: SequenceOfEncoder(), + univ.Sequence.typeId: SequenceEncoder(), + univ.SequenceOf.typeId: SequenceOfEncoder(), + univ.Choice.typeId: ChoiceEncoder(), + univ.Any.typeId: AnyEncoder(), + # character string types + char.UTF8String.typeId: OctetStringEncoder(), + char.NumericString.typeId: OctetStringEncoder(), + char.PrintableString.typeId: OctetStringEncoder(), + char.TeletexString.typeId: OctetStringEncoder(), + char.VideotexString.typeId: OctetStringEncoder(), + char.IA5String.typeId: OctetStringEncoder(), + char.GraphicString.typeId: OctetStringEncoder(), + char.VisibleString.typeId: OctetStringEncoder(), + char.GeneralString.typeId: OctetStringEncoder(), + char.UniversalString.typeId: OctetStringEncoder(), + char.BMPString.typeId: OctetStringEncoder(), + # useful types + useful.ObjectDescriptor.typeId: OctetStringEncoder(), + useful.GeneralizedTime.typeId: OctetStringEncoder(), + useful.UTCTime.typeId: OctetStringEncoder() +} + + +class SingleItemEncoder(object): + + TAG_MAP = TAG_MAP + TYPE_MAP = TYPE_MAP + + def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **ignored): + self._tagMap = tagMap if tagMap is not _MISSING else self.TAG_MAP + self._typeMap = typeMap if typeMap is not _MISSING else self.TYPE_MAP + + def __call__(self, value, **options): + if not isinstance(value, base.Asn1Item): + raise error.PyAsn1Error( + 'value is not valid (should be an instance of an ASN.1 Item)') + + if LOG: + debug.scope.push(type(value).__name__) + LOG('encoder called for type %s ' + '<%s>' % (type(value).__name__, value.prettyPrint())) + + tagSet = value.tagSet + + try: + concreteEncoder = self._typeMap[value.typeId] + + except KeyError: + # use base type for codec lookup to recover untagged types + baseTagSet = tag.TagSet( + value.tagSet.baseTag, value.tagSet.baseTag) + + try: + concreteEncoder = self._tagMap[baseTagSet] + + except KeyError: + raise error.PyAsn1Error('No encoder for %s' % (value,)) + + if LOG: + LOG('using value codec %s chosen by ' + '%s' % (concreteEncoder.__class__.__name__, tagSet)) + + pyObject = concreteEncoder.encode(value, self, **options) + + if LOG: + LOG('encoder %s produced: ' + '%s' % (type(concreteEncoder).__name__, repr(pyObject))) + debug.scope.pop() + + return pyObject + + +class Encoder(object): + SINGLE_ITEM_ENCODER = SingleItemEncoder + + def __init__(self, **options): + self._singleItemEncoder = self.SINGLE_ITEM_ENCODER(**options) + + def __call__(self, pyObject, asn1Spec=None, **options): + return self._singleItemEncoder( + pyObject, asn1Spec=asn1Spec, **options) + + +#: Turns ASN.1 object into a Python built-in type object(s). +#: +#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: walks all its components recursively and produces a Python built-in type or a tree +#: of those. +#: +#: One exception is that instead of :py:class:`dict`, the :py:class:`OrderedDict` +#: is used to preserve ordering of the components in ASN.1 SEQUENCE. +#: +#: Parameters +#: ---------- +# asn1Value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) +#: pyasn1 object to encode (or a tree of them) +#: +#: Returns +#: ------- +#: : :py:class:`object` +#: Python built-in type instance (or a tree of them) +#: +#: Raises +#: ------ +#: ~pyasn1.error.PyAsn1Error +#: On encoding errors +#: +#: Examples +#: -------- +#: Encode ASN.1 value object into native Python types +#: +#: .. code-block:: pycon +#: +#: >>> seq = SequenceOf(componentType=Integer()) +#: >>> seq.extend([1, 2, 3]) +#: >>> encode(seq) +#: [1, 2, 3] +#: +encode = SingleItemEncoder() + +def __getattr__(attr: str): + if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr): + warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2) + return globals()[newAttr] + raise AttributeError(attr) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/codec/streaming.py b/plugins/ldap-user-sync/vendor/pyasn1/codec/streaming.py new file mode 100644 index 00000000..c35f2489 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/codec/streaming.py @@ -0,0 +1,234 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2019, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import io +import os + +from pyasn1 import error +from pyasn1.type import univ + +class CachingStreamWrapper(io.IOBase): + """Wrapper around non-seekable streams. + + Note that the implementation is tied to the decoder, + not checking for dangerous arguments for the sake + of performance. + + The read bytes are kept in an internal cache until + setting _markedPosition which may reset the cache. + """ + def __init__(self, raw): + self._raw = raw + self._cache = io.BytesIO() + self._markedPosition = 0 + + def peek(self, n): + result = self.read(n) + self._cache.seek(-len(result), os.SEEK_CUR) + return result + + def seekable(self): + return True + + def seek(self, n=-1, whence=os.SEEK_SET): + # Note that this not safe for seeking forward. + return self._cache.seek(n, whence) + + def read(self, n=-1): + read_from_cache = self._cache.read(n) + if n != -1: + n -= len(read_from_cache) + if not n: # 0 bytes left to read + return read_from_cache + + read_from_raw = self._raw.read(n) + + self._cache.write(read_from_raw) + + return read_from_cache + read_from_raw + + @property + def markedPosition(self): + """Position where the currently processed element starts. + + This is used for back-tracking in SingleItemDecoder.__call__ + and (indefLen)ValueDecoder and should not be used for other purposes. + The client is not supposed to ever seek before this position. + """ + return self._markedPosition + + @markedPosition.setter + def markedPosition(self, value): + # By setting the value, we ensure we won't seek back before it. + # `value` should be the same as the current position + # We don't check for this for performance reasons. + self._markedPosition = value + + # Whenever we set _marked_position, we know for sure + # that we will not return back, and thus it is + # safe to drop all cached data. + if self._cache.tell() > io.DEFAULT_BUFFER_SIZE: + self._cache = io.BytesIO(self._cache.read()) + self._markedPosition = 0 + + def tell(self): + return self._cache.tell() + + +def asSeekableStream(substrate): + """Convert object to seekable byte-stream. + + Parameters + ---------- + substrate: :py:class:`bytes` or :py:class:`io.IOBase` or :py:class:`univ.OctetString` + + Returns + ------- + : :py:class:`io.IOBase` + + Raises + ------ + : :py:class:`~pyasn1.error.PyAsn1Error` + If the supplied substrate cannot be converted to a seekable stream. + """ + if isinstance(substrate, io.BytesIO): + return substrate + + elif isinstance(substrate, bytes): + return io.BytesIO(substrate) + + elif isinstance(substrate, univ.OctetString): + return io.BytesIO(substrate.asOctets()) + + try: + if substrate.seekable(): # Will fail for most invalid types + return substrate + else: + return CachingStreamWrapper(substrate) + + except AttributeError: + raise error.UnsupportedSubstrateError( + "Cannot convert " + substrate.__class__.__name__ + + " to a seekable bit stream.") + + +def isEndOfStream(substrate): + """Check whether we have reached the end of a stream. + + Although it is more effective to read and catch exceptions, this + function + + Parameters + ---------- + substrate: :py:class:`IOBase` + Stream to check + + Returns + ------- + : :py:class:`bool` + """ + if isinstance(substrate, io.BytesIO): + cp = substrate.tell() + substrate.seek(0, os.SEEK_END) + result = substrate.tell() == cp + substrate.seek(cp, os.SEEK_SET) + yield result + + else: + received = substrate.read(1) + if received is None: + yield + + if received: + substrate.seek(-1, os.SEEK_CUR) + + yield not received + + +def peekIntoStream(substrate, size=-1): + """Peek into stream. + + Parameters + ---------- + substrate: :py:class:`IOBase` + Stream to read from. + + size: :py:class:`int` + How many bytes to peek (-1 = all available) + + Returns + ------- + : :py:class:`bytes` or :py:class:`str` + The return type depends on Python major version + """ + if hasattr(substrate, "peek"): + received = substrate.peek(size) + if received is None: + yield + + while len(received) < size: + yield + + yield received + + else: + current_position = substrate.tell() + try: + for chunk in readFromStream(substrate, size): + yield chunk + + finally: + substrate.seek(current_position) + + +def readFromStream(substrate, size=-1, context=None): + """Read from the stream. + + Parameters + ---------- + substrate: :py:class:`IOBase` + Stream to read from. + + Keyword parameters + ------------------ + size: :py:class:`int` + How many bytes to read (-1 = all available) + + context: :py:class:`dict` + Opaque caller context will be attached to exception objects created + by this function. + + Yields + ------ + : :py:class:`bytes` or :py:class:`str` or :py:class:`SubstrateUnderrunError` + Read data or :py:class:`~pyasn1.error.SubstrateUnderrunError` + object if no `size` bytes is readily available in the stream. The + data type depends on Python major version + + Raises + ------ + : :py:class:`~pyasn1.error.EndOfStreamError` + Input stream is exhausted + """ + while True: + # this will block unless stream is non-blocking + received = substrate.read(size) + if received is None: # non-blocking stream can do this + yield error.SubstrateUnderrunError(context=context) + + elif not received and size != 0: # end-of-stream + raise error.EndOfStreamError(context=context) + + elif len(received) < size: + substrate.seek(-len(received), os.SEEK_CUR) + + # behave like a non-blocking stream + yield error.SubstrateUnderrunError(context=context) + + else: + break + + yield received diff --git a/plugins/ldap-user-sync/vendor/pyasn1/compat/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/compat/__init__.py new file mode 100644 index 00000000..d3e676ac --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/compat/__init__.py @@ -0,0 +1,4 @@ +# This file is necessary to make this directory a package. + +# sentinal for missing argument +_MISSING = object() diff --git a/plugins/ldap-user-sync/vendor/pyasn1/compat/integer.py b/plugins/ldap-user-sync/vendor/pyasn1/compat/integer.py new file mode 100644 index 00000000..306210e5 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/compat/integer.py @@ -0,0 +1,13 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +def to_bytes(value, signed=False, length=0): + length = max(value.bit_length(), length) + + if signed and length % 8 == 0: + length += 1 + + return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/debug.py b/plugins/ldap-user-sync/vendor/pyasn1/debug.py new file mode 100644 index 00000000..07194235 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/debug.py @@ -0,0 +1,146 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import logging +import sys + +from pyasn1 import __version__ +from pyasn1 import error + +__all__ = ['Debug', 'setLogger', 'hexdump'] + +DEBUG_NONE = 0x0000 +DEBUG_ENCODER = 0x0001 +DEBUG_DECODER = 0x0002 +DEBUG_ALL = 0xffff + +FLAG_MAP = { + 'none': DEBUG_NONE, + 'encoder': DEBUG_ENCODER, + 'decoder': DEBUG_DECODER, + 'all': DEBUG_ALL +} + +LOGGEE_MAP = {} + + +class Printer(object): + # noinspection PyShadowingNames + def __init__(self, logger=None, handler=None, formatter=None): + if logger is None: + logger = logging.getLogger('pyasn1') + + logger.setLevel(logging.DEBUG) + + if handler is None: + handler = logging.StreamHandler() + + if formatter is None: + formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s') + + handler.setFormatter(formatter) + handler.setLevel(logging.DEBUG) + logger.addHandler(handler) + + self.__logger = logger + + def __call__(self, msg): + self.__logger.debug(msg) + + def __str__(self): + return '' + + +class Debug(object): + defaultPrinter = Printer() + + def __init__(self, *flags, **options): + self._flags = DEBUG_NONE + + if 'loggerName' in options: + # route our logs to parent logger + self._printer = Printer( + logger=logging.getLogger(options['loggerName']), + handler=logging.NullHandler() + ) + + elif 'printer' in options: + self._printer = options.get('printer') + + else: + self._printer = self.defaultPrinter + + self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags))) + + for flag in flags: + inverse = flag and flag[0] in ('!', '~') + if inverse: + flag = flag[1:] + try: + if inverse: + self._flags &= ~FLAG_MAP[flag] + else: + self._flags |= FLAG_MAP[flag] + except KeyError: + raise error.PyAsn1Error('bad debug flag %s' % flag) + + self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled')) + + def __str__(self): + return 'logger %s, flags %x' % (self._printer, self._flags) + + def __call__(self, msg): + self._printer(msg) + + def __and__(self, flag): + return self._flags & flag + + def __rand__(self, flag): + return flag & self._flags + +_LOG = DEBUG_NONE + + +def setLogger(userLogger): + global _LOG + + if userLogger: + _LOG = userLogger + else: + _LOG = DEBUG_NONE + + # Update registered logging clients + for module, (name, flags) in LOGGEE_MAP.items(): + setattr(module, name, _LOG & flags and _LOG or DEBUG_NONE) + + +def registerLoggee(module, name='LOG', flags=DEBUG_NONE): + LOGGEE_MAP[sys.modules[module]] = name, flags + setLogger(_LOG) + return _LOG + + +def hexdump(octets): + return ' '.join( + ['%s%.2X' % (n % 16 == 0 and ('\n%.5d: ' % n) or '', x) + for n, x in zip(range(len(octets)), octets)] + ) + + +class Scope(object): + def __init__(self): + self._list = [] + + def __str__(self): return '.'.join(self._list) + + def push(self, token): + self._list.append(token) + + def pop(self): + return self._list.pop() + + +scope = Scope() diff --git a/plugins/ldap-user-sync/vendor/pyasn1/error.py b/plugins/ldap-user-sync/vendor/pyasn1/error.py new file mode 100644 index 00000000..75c9a3f4 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/error.py @@ -0,0 +1,116 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# + + +class PyAsn1Error(Exception): + """Base pyasn1 exception + + `PyAsn1Error` is the base exception class (based on + :class:`Exception`) that represents all possible ASN.1 related + errors. + + Parameters + ---------- + args: + Opaque positional parameters + + Keyword Args + ------------ + kwargs: + Opaque keyword parameters + + """ + def __init__(self, *args, **kwargs): + self._args = args + self._kwargs = kwargs + + @property + def context(self): + """Return exception context + + When exception object is created, the caller can supply some opaque + context for the upper layers to better understand the cause of the + exception. + + Returns + ------- + : :py:class:`dict` + Dict holding context specific data + """ + return self._kwargs.get('context', {}) + + +class ValueConstraintError(PyAsn1Error): + """ASN.1 type constraints violation exception + + The `ValueConstraintError` exception indicates an ASN.1 value + constraint violation. + + It might happen on value object instantiation (for scalar types) or on + serialization (for constructed types). + """ + + +class SubstrateUnderrunError(PyAsn1Error): + """ASN.1 data structure deserialization error + + The `SubstrateUnderrunError` exception indicates insufficient serialised + data on input of a de-serialization codec. + """ + + +class EndOfStreamError(SubstrateUnderrunError): + """ASN.1 data structure deserialization error + + The `EndOfStreamError` exception indicates the condition of the input + stream has been closed. + """ + + +class UnsupportedSubstrateError(PyAsn1Error): + """Unsupported substrate type to parse as ASN.1 data.""" + + +class PyAsn1UnicodeError(PyAsn1Error, UnicodeError): + """Unicode text processing error + + The `PyAsn1UnicodeError` exception is a base class for errors relating to + unicode text de/serialization. + + Apart from inheriting from :class:`PyAsn1Error`, it also inherits from + :class:`UnicodeError` to help the caller catching unicode-related errors. + """ + def __init__(self, message, unicode_error=None): + if isinstance(unicode_error, UnicodeError): + UnicodeError.__init__(self, *unicode_error.args) + PyAsn1Error.__init__(self, message) + + +class PyAsn1UnicodeDecodeError(PyAsn1UnicodeError, UnicodeDecodeError): + """Unicode text decoding error + + The `PyAsn1UnicodeDecodeError` exception represents a failure to + deserialize unicode text. + + Apart from inheriting from :class:`PyAsn1UnicodeError`, it also inherits + from :class:`UnicodeDecodeError` to help the caller catching unicode-related + errors. + """ + + +class PyAsn1UnicodeEncodeError(PyAsn1UnicodeError, UnicodeEncodeError): + """Unicode text encoding error + + The `PyAsn1UnicodeEncodeError` exception represents a failure to + serialize unicode text. + + Apart from inheriting from :class:`PyAsn1UnicodeError`, it also inherits + from :class:`UnicodeEncodeError` to help the caller catching + unicode-related errors. + """ + + diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/__init__.py b/plugins/ldap-user-sync/vendor/pyasn1/type/__init__.py new file mode 100644 index 00000000..8c3066b2 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/base.py b/plugins/ldap-user-sync/vendor/pyasn1/type/base.py new file mode 100644 index 00000000..aa86e520 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/base.py @@ -0,0 +1,699 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import sys + +from pyasn1 import error +from pyasn1.type import constraint +from pyasn1.type import tag +from pyasn1.type import tagmap + +__all__ = ['Asn1Item', 'Asn1Type', 'SimpleAsn1Type', + 'ConstructedAsn1Type'] + + +class Asn1Item(object): + @classmethod + def getTypeId(cls, increment=1): + try: + Asn1Item._typeCounter += increment + except AttributeError: + Asn1Item._typeCounter = increment + return Asn1Item._typeCounter + + +class Asn1Type(Asn1Item): + """Base class for all classes representing ASN.1 types. + + In the user code, |ASN.1| class is normally used only for telling + ASN.1 objects from others. + + Note + ---- + For as long as ASN.1 is concerned, a way to compare ASN.1 types + is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods. + """ + #: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing + #: ASN.1 tag(s) associated with |ASN.1| type. + tagSet = tag.TagSet() + + #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + #: object imposing constraints on initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Disambiguation ASN.1 types identification + typeId = None + + def __init__(self, **kwargs): + readOnly = { + 'tagSet': self.tagSet, + 'subtypeSpec': self.subtypeSpec + } + + readOnly.update(kwargs) + + self.__dict__.update(readOnly) + + self._readOnly = readOnly + + def __setattr__(self, name, value): + if name[0] != '_' and name in self._readOnly: + raise error.PyAsn1Error('read-only instance attribute "%s"' % name) + + self.__dict__[name] = value + + def __str__(self): + return self.prettyPrint() + + @property + def readOnly(self): + return self._readOnly + + @property + def effectiveTagSet(self): + """For |ASN.1| type is equivalent to *tagSet* + """ + return self.tagSet # used by untagged types + + @property + def tagMap(self): + """Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object. + """ + return tagmap.TagMap({self.tagSet: self}) + + def isSameTypeWith(self, other, matchTags=True, matchConstraints=True): + """Examine |ASN.1| type for equality with other ASN.1 type. + + ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints + (:py:mod:`~pyasn1.type.constraint`) are examined when carrying + out ASN.1 types comparison. + + Python class inheritance relationship is NOT considered. + + Parameters + ---------- + other: a pyasn1 type object + Class instance representing ASN.1 type. + + Returns + ------- + : :class:`bool` + :obj:`True` if *other* is |ASN.1| type, + :obj:`False` otherwise. + """ + return (self is other or + (not matchTags or self.tagSet == other.tagSet) and + (not matchConstraints or self.subtypeSpec == other.subtypeSpec)) + + def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True): + """Examine |ASN.1| type for subtype relationship with other ASN.1 type. + + ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints + (:py:mod:`~pyasn1.type.constraint`) are examined when carrying + out ASN.1 types comparison. + + Python class inheritance relationship is NOT considered. + + Parameters + ---------- + other: a pyasn1 type object + Class instance representing ASN.1 type. + + Returns + ------- + : :class:`bool` + :obj:`True` if *other* is a subtype of |ASN.1| type, + :obj:`False` otherwise. + """ + return (not matchTags or + (self.tagSet.isSuperTagSetOf(other.tagSet)) and + (not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec))) + + @staticmethod + def isNoValue(*values): + for value in values: + if value is not noValue: + return False + return True + + def prettyPrint(self, scope=0): + raise NotImplementedError + + # backward compatibility + + def getTagSet(self): + return self.tagSet + + def getEffectiveTagSet(self): + return self.effectiveTagSet + + def getTagMap(self): + return self.tagMap + + def getSubtypeSpec(self): + return self.subtypeSpec + + # backward compatibility + def hasValue(self): + return self.isValue + +# Backward compatibility +Asn1ItemBase = Asn1Type + + +class NoValue(object): + """Create a singleton instance of NoValue class. + + The *NoValue* sentinel object represents an instance of ASN.1 schema + object as opposed to ASN.1 value object. + + Only ASN.1 schema-related operations can be performed on ASN.1 + schema objects. + + Warning + ------- + Any operation attempted on the *noValue* object will raise the + *PyAsn1Error* exception. + """ + skipMethods = { + '__slots__', + # attributes + '__getattribute__', + '__getattr__', + '__setattr__', + '__delattr__', + # class instance + '__class__', + '__init__', + '__del__', + '__new__', + '__repr__', + '__qualname__', + '__objclass__', + 'im_class', + '__sizeof__', + # pickle protocol + '__reduce__', + '__reduce_ex__', + '__getnewargs__', + '__getinitargs__', + '__getstate__', + '__setstate__', + } + + _instance = None + + def __new__(cls): + if cls._instance is None: + def getPlug(name): + def plug(self, *args, **kw): + raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % name) + return plug + + op_names = [name + for typ in (str, int, list, dict) + for name in dir(typ) + if (name not in cls.skipMethods and + name.startswith('__') and + name.endswith('__') and + callable(getattr(typ, name)))] + + for name in set(op_names): + setattr(cls, name, getPlug(name)) + + cls._instance = object.__new__(cls) + + return cls._instance + + def __getattr__(self, attr): + if attr in self.skipMethods: + raise AttributeError('Attribute %s not present' % attr) + + raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % attr) + + def __repr__(self): + return '<%s object>' % self.__class__.__name__ + + +noValue = NoValue() + + +class SimpleAsn1Type(Asn1Type): + """Base class for all simple classes representing ASN.1 types. + + ASN.1 distinguishes types by their ability to hold other objects. + Scalar types are known as *simple* in ASN.1. + + In the user code, |ASN.1| class is normally used only for telling + ASN.1 objects from others. + + Note + ---- + For as long as ASN.1 is concerned, a way to compare ASN.1 types + is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods. + """ + #: Default payload value + defaultValue = noValue + + def __init__(self, value=noValue, **kwargs): + Asn1Type.__init__(self, **kwargs) + if value is noValue: + value = self.defaultValue + else: + value = self.prettyIn(value) + try: + self.subtypeSpec(value) + + except error.PyAsn1Error as exValue: + raise type(exValue)('%s at %s' % (exValue, self.__class__.__name__)) + + self._value = value + + def __repr__(self): + representation = '%s %s object' % ( + self.__class__.__name__, self.isValue and 'value' or 'schema') + + for attr, value in self.readOnly.items(): + if value: + representation += ', %s %s' % (attr, value) + + if self.isValue: + value = self.prettyPrint() + if len(value) > 32: + value = value[:16] + '...' + value[-16:] + representation += ', payload [%s]' % value + + return '<%s>' % representation + + def __eq__(self, other): + if self is other: + return True + return self._value == other + + def __ne__(self, other): + return self._value != other + + def __lt__(self, other): + return self._value < other + + def __le__(self, other): + return self._value <= other + + def __gt__(self, other): + return self._value > other + + def __ge__(self, other): + return self._value >= other + + def __bool__(self): + return bool(self._value) + + def __hash__(self): + return hash(self._value) + + @property + def isValue(self): + """Indicate that |ASN.1| object represents ASN.1 value. + + If *isValue* is :obj:`False` then this object represents just + ASN.1 schema. + + If *isValue* is :obj:`True` then, in addition to its ASN.1 schema + features, this object can also be used like a Python built-in object + (e.g. :class:`int`, :class:`str`, :class:`dict` etc.). + + Returns + ------- + : :class:`bool` + :obj:`False` if object represents just ASN.1 schema. + :obj:`True` if object represents ASN.1 schema and can be used as a normal value. + + Note + ---- + There is an important distinction between PyASN1 schema and value objects. + The PyASN1 schema objects can only participate in ASN.1 schema-related + operations (e.g. defining or testing the structure of the data). Most + obvious uses of ASN.1 schema is to guide serialisation codecs whilst + encoding/decoding serialised ASN.1 contents. + + The PyASN1 value objects can **additionally** participate in many operations + involving regular Python objects (e.g. arithmetic, comprehension etc). + """ + return self._value is not noValue + + def clone(self, value=noValue, **kwargs): + """Create a modified version of |ASN.1| schema or value object. + + The `clone()` method accepts the same set arguments as |ASN.1| + class takes on instantiation except that all arguments + of the `clone()` method are optional. + + Whatever arguments are supplied, they are used to create a copy + of `self` taking precedence over the ones used to instantiate `self`. + + Note + ---- + Due to the immutable nature of the |ASN.1| object, if no arguments + are supplied, no new |ASN.1| object will be created and `self` will + be returned instead. + """ + if value is noValue: + if not kwargs: + return self + + value = self._value + + initializers = self.readOnly.copy() + initializers.update(kwargs) + + return self.__class__(value, **initializers) + + def subtype(self, value=noValue, **kwargs): + """Create a specialization of |ASN.1| schema or value object. + + The subtype relationship between ASN.1 types has no correlation with + subtype relationship between Python types. ASN.1 type is mainly identified + by its tag(s) (:py:class:`~pyasn1.type.tag.TagSet`) and value range + constraints (:py:class:`~pyasn1.type.constraint.ConstraintsIntersection`). + These ASN.1 type properties are implemented as |ASN.1| attributes. + + The `subtype()` method accepts the same set arguments as |ASN.1| + class takes on instantiation except that all parameters + of the `subtype()` method are optional. + + With the exception of the arguments described below, the rest of + supplied arguments they are used to create a copy of `self` taking + precedence over the ones used to instantiate `self`. + + The following arguments to `subtype()` create a ASN.1 subtype out of + |ASN.1| type: + + Other Parameters + ---------------- + implicitTag: :py:class:`~pyasn1.type.tag.Tag` + Implicitly apply given ASN.1 tag object to `self`'s + :py:class:`~pyasn1.type.tag.TagSet`, then use the result as + new object's ASN.1 tag(s). + + explicitTag: :py:class:`~pyasn1.type.tag.Tag` + Explicitly apply given ASN.1 tag object to `self`'s + :py:class:`~pyasn1.type.tag.TagSet`, then use the result as + new object's ASN.1 tag(s). + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Add ASN.1 constraints object to one of the `self`'s, then + use the result as new object's ASN.1 constraints. + + Returns + ------- + : + new instance of |ASN.1| schema or value object + + Note + ---- + Due to the immutable nature of the |ASN.1| object, if no arguments + are supplied, no new |ASN.1| object will be created and `self` will + be returned instead. + """ + if value is noValue: + if not kwargs: + return self + + value = self._value + + initializers = self.readOnly.copy() + + implicitTag = kwargs.pop('implicitTag', None) + if implicitTag is not None: + initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag) + + explicitTag = kwargs.pop('explicitTag', None) + if explicitTag is not None: + initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag) + + for arg, option in kwargs.items(): + initializers[arg] += option + + return self.__class__(value, **initializers) + + def prettyIn(self, value): + return value + + def prettyOut(self, value): + return str(value) + + def prettyPrint(self, scope=0): + return self.prettyOut(self._value) + + def prettyPrintType(self, scope=0): + return '%s -> %s' % (self.tagSet, self.__class__.__name__) + +# Backward compatibility +AbstractSimpleAsn1Item = SimpleAsn1Type + +# +# Constructed types: +# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice +# * ASN1 types and values are represened by Python class instances +# * Value initialization is made for defaulted components only +# * Primary method of component addressing is by-position. Data model for base +# type is Python sequence. Additional type-specific addressing methods +# may be implemented for particular types. +# * SequenceOf and SetOf types do not implement any additional methods +# * Sequence, Set and Choice types also implement by-identifier addressing +# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing +# * Sequence and Set types may include optional and defaulted +# components +# * Constructed types hold a reference to component types used for value +# verification and ordering. +# * Component type is a scalar type for SequenceOf/SetOf types and a list +# of types for Sequence/Set/Choice. +# + + +class ConstructedAsn1Type(Asn1Type): + """Base class for all constructed classes representing ASN.1 types. + + ASN.1 distinguishes types by their ability to hold other objects. + Those "nesting" types are known as *constructed* in ASN.1. + + In the user code, |ASN.1| class is normally used only for telling + ASN.1 objects from others. + + Note + ---- + For as long as ASN.1 is concerned, a way to compare ASN.1 types + is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods. + """ + + #: If :obj:`True`, requires exact component type matching, + #: otherwise subtype relation is only enforced + strictConstraints = False + + componentType = None + + # backward compatibility, unused + sizeSpec = constraint.ConstraintsIntersection() + + def __init__(self, **kwargs): + readOnly = { + 'componentType': self.componentType, + # backward compatibility, unused + 'sizeSpec': self.sizeSpec + } + + # backward compatibility: preserve legacy sizeSpec support + kwargs = self._moveSizeSpec(**kwargs) + + readOnly.update(kwargs) + + Asn1Type.__init__(self, **readOnly) + + def _moveSizeSpec(self, **kwargs): + # backward compatibility, unused + sizeSpec = kwargs.pop('sizeSpec', self.sizeSpec) + if sizeSpec: + subtypeSpec = kwargs.pop('subtypeSpec', self.subtypeSpec) + if subtypeSpec: + subtypeSpec = sizeSpec + + else: + subtypeSpec += sizeSpec + + kwargs['subtypeSpec'] = subtypeSpec + + return kwargs + + def __repr__(self): + representation = '%s %s object' % ( + self.__class__.__name__, self.isValue and 'value' or 'schema' + ) + + for attr, value in self.readOnly.items(): + if value is not noValue: + representation += ', %s=%r' % (attr, value) + + if self.isValue and self.components: + representation += ', payload [%s]' % ', '.join( + [repr(x) for x in self.components]) + + return '<%s>' % representation + + def __eq__(self, other): + return self is other or self.components == other + + def __ne__(self, other): + return self.components != other + + def __lt__(self, other): + return self.components < other + + def __le__(self, other): + return self.components <= other + + def __gt__(self, other): + return self.components > other + + def __ge__(self, other): + return self.components >= other + + def __bool__(self): + return bool(self.components) + + @property + def components(self): + raise error.PyAsn1Error('Method not implemented') + + def _cloneComponentValues(self, myClone, cloneValueFlag): + pass + + def clone(self, **kwargs): + """Create a modified version of |ASN.1| schema object. + + The `clone()` method accepts the same set arguments as |ASN.1| + class takes on instantiation except that all arguments + of the `clone()` method are optional. + + Whatever arguments are supplied, they are used to create a copy + of `self` taking precedence over the ones used to instantiate `self`. + + Possible values of `self` are never copied over thus `clone()` can + only create a new schema object. + + Returns + ------- + : + new instance of |ASN.1| type/value + + Note + ---- + Due to the mutable nature of the |ASN.1| object, even if no arguments + are supplied, a new |ASN.1| object will be created and returned. + """ + cloneValueFlag = kwargs.pop('cloneValueFlag', False) + + initializers = self.readOnly.copy() + initializers.update(kwargs) + + clone = self.__class__(**initializers) + + if cloneValueFlag: + self._cloneComponentValues(clone, cloneValueFlag) + + return clone + + def subtype(self, **kwargs): + """Create a specialization of |ASN.1| schema object. + + The `subtype()` method accepts the same set arguments as |ASN.1| + class takes on instantiation except that all parameters + of the `subtype()` method are optional. + + With the exception of the arguments described below, the rest of + supplied arguments they are used to create a copy of `self` taking + precedence over the ones used to instantiate `self`. + + The following arguments to `subtype()` create a ASN.1 subtype out of + |ASN.1| type. + + Other Parameters + ---------------- + implicitTag: :py:class:`~pyasn1.type.tag.Tag` + Implicitly apply given ASN.1 tag object to `self`'s + :py:class:`~pyasn1.type.tag.TagSet`, then use the result as + new object's ASN.1 tag(s). + + explicitTag: :py:class:`~pyasn1.type.tag.Tag` + Explicitly apply given ASN.1 tag object to `self`'s + :py:class:`~pyasn1.type.tag.TagSet`, then use the result as + new object's ASN.1 tag(s). + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Add ASN.1 constraints object to one of the `self`'s, then + use the result as new object's ASN.1 constraints. + + + Returns + ------- + : + new instance of |ASN.1| type/value + + Note + ---- + Due to the mutable nature of the |ASN.1| object, even if no arguments + are supplied, a new |ASN.1| object will be created and returned. + """ + + initializers = self.readOnly.copy() + + cloneValueFlag = kwargs.pop('cloneValueFlag', False) + + implicitTag = kwargs.pop('implicitTag', None) + if implicitTag is not None: + initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag) + + explicitTag = kwargs.pop('explicitTag', None) + if explicitTag is not None: + initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag) + + for arg, option in kwargs.items(): + initializers[arg] += option + + clone = self.__class__(**initializers) + + if cloneValueFlag: + self._cloneComponentValues(clone, cloneValueFlag) + + return clone + + def getComponentByPosition(self, idx): + raise error.PyAsn1Error('Method not implemented') + + def setComponentByPosition(self, idx, value, verifyConstraints=True): + raise error.PyAsn1Error('Method not implemented') + + def setComponents(self, *args, **kwargs): + for idx, value in enumerate(args): + self[idx] = value + for k in kwargs: + self[k] = kwargs[k] + return self + + # backward compatibility + + def setDefaultComponents(self): + pass + + def getComponentType(self): + return self.componentType + + # backward compatibility, unused + def verifySizeSpec(self): + self.subtypeSpec(self) + + + # Backward compatibility +AbstractConstructedAsn1Item = ConstructedAsn1Type diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/char.py b/plugins/ldap-user-sync/vendor/pyasn1/type/char.py new file mode 100644 index 00000000..ec65f006 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/char.py @@ -0,0 +1,288 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import sys + +from pyasn1 import error +from pyasn1.type import tag +from pyasn1.type import univ + +__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString', + 'IA5String', 'GraphicString', 'VisibleString', 'ISO646String', + 'GeneralString', 'UniversalString', 'BMPString', 'UTF8String'] + +NoValue = univ.NoValue +noValue = univ.noValue + + +class AbstractCharacterString(univ.OctetString): + """Creates |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, + its objects are immutable and duck-type :class:`bytes`. + When used in octet-stream context, |ASN.1| type assumes + "|encoding|" encoding. + + Keyword Args + ------------ + value: :class:`str`, :class:`bytes` or |ASN.1| object + :class:`str`, alternatively :class:`bytes` + representing octet-stream of serialised unicode string + (note `encoding` parameter) or |ASN.1| class instance. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + encoding: :py:class:`str` + Unicode codec ID to encode/decode + :class:`str` the payload when |ASN.1| object is used + in octet-stream context. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + """ + + def __str__(self): + return str(self._value) + + def __bytes__(self): + try: + return self._value.encode(self.encoding) + except UnicodeEncodeError as exc: + raise error.PyAsn1UnicodeEncodeError( + "Can't encode string '%s' with codec " + "%s" % (self._value, self.encoding), exc + ) + + def prettyIn(self, value): + try: + if isinstance(value, str): + return value + elif isinstance(value, bytes): + return value.decode(self.encoding) + elif isinstance(value, (tuple, list)): + return self.prettyIn(bytes(value)) + elif isinstance(value, univ.OctetString): + return value.asOctets().decode(self.encoding) + else: + return str(value) + + except (UnicodeDecodeError, LookupError) as exc: + raise error.PyAsn1UnicodeDecodeError( + "Can't decode string '%s' with codec " + "%s" % (value, self.encoding), exc + ) + + def asOctets(self, padding=True): + return bytes(self) + + def asNumbers(self, padding=True): + return tuple(bytes(self)) + + # + # See OctetString.prettyPrint() for the explanation + # + + def prettyOut(self, value): + return value + + def prettyPrint(self, scope=0): + # first see if subclass has its own .prettyOut() + value = self.prettyOut(self._value) + + if value is not self._value: + return value + + return AbstractCharacterString.__str__(self) + + def __reversed__(self): + return reversed(self._value) + + +class NumericString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18) + ) + encoding = 'us-ascii' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class PrintableString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19) + ) + encoding = 'us-ascii' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class TeletexString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20) + ) + encoding = 'iso-8859-1' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class T61String(TeletexString): + __doc__ = TeletexString.__doc__ + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class VideotexString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21) + ) + encoding = 'iso-8859-1' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class IA5String(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22) + ) + encoding = 'us-ascii' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class GraphicString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25) + ) + encoding = 'iso-8859-1' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class VisibleString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26) + ) + encoding = 'us-ascii' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class ISO646String(VisibleString): + __doc__ = VisibleString.__doc__ + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + +class GeneralString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27) + ) + encoding = 'iso-8859-1' + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class UniversalString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28) + ) + encoding = "utf-32-be" + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class BMPString(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30) + ) + encoding = "utf-16-be" + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() + + +class UTF8String(AbstractCharacterString): + __doc__ = AbstractCharacterString.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = AbstractCharacterString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12) + ) + encoding = "utf-8" + + # Optimization for faster codec lookup + typeId = AbstractCharacterString.getTypeId() diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/constraint.py b/plugins/ldap-user-sync/vendor/pyasn1/type/constraint.py new file mode 100644 index 00000000..02368d0a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/constraint.py @@ -0,0 +1,751 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +# Original concept and code by Mike C. Fletcher. +# +import sys + +from pyasn1.type import error + +__all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint', + 'ValueRangeConstraint', 'ValueSizeConstraint', + 'PermittedAlphabetConstraint', 'InnerTypeConstraint', + 'ConstraintsExclusion', 'ConstraintsIntersection', + 'ConstraintsUnion'] + + +class AbstractConstraint(object): + + def __init__(self, *values): + self._valueMap = set() + self._setValues(values) + self.__hash = hash((self.__class__.__name__, self._values)) + + def __call__(self, value, idx=None): + if not self._values: + return + + try: + self._testValue(value, idx) + + except error.ValueConstraintError as exc: + raise error.ValueConstraintError( + '%s failed at: %r' % (self, exc) + ) + + def __repr__(self): + representation = '%s object' % (self.__class__.__name__) + + if self._values: + representation += ', consts %s' % ', '.join( + [repr(x) for x in self._values]) + + return '<%s>' % representation + + def __eq__(self, other): + if self is other: + return True + return self._values == other + + def __ne__(self, other): + return self._values != other + + def __lt__(self, other): + return self._values < other + + def __le__(self, other): + return self._values <= other + + def __gt__(self, other): + return self._values > other + + def __ge__(self, other): + return self._values >= other + + def __bool__(self): + return bool(self._values) + + def __hash__(self): + return self.__hash + + def _setValues(self, values): + self._values = values + + def _testValue(self, value, idx): + raise error.ValueConstraintError(value) + + # Constraints derivation logic + def getValueMap(self): + return self._valueMap + + def isSuperTypeOf(self, otherConstraint): + # TODO: fix possible comparison of set vs scalars here + return (otherConstraint is self or + not self._values or + otherConstraint == self or + self in otherConstraint.getValueMap()) + + def isSubTypeOf(self, otherConstraint): + return (otherConstraint is self or + not self or + otherConstraint == self or + otherConstraint in self._valueMap) + + +class SingleValueConstraint(AbstractConstraint): + """Create a SingleValueConstraint object. + + The SingleValueConstraint satisfies any value that + is present in the set of permitted values. + + Objects of this type are iterable (emitting constraint values) and + can act as operands for some arithmetic operations e.g. addition + and subtraction. The latter can be used for combining multiple + SingleValueConstraint objects into one. + + The SingleValueConstraint object can be applied to + any ASN.1 type. + + Parameters + ---------- + *values: :class:`int` + Full set of values permitted by this constraint object. + + Examples + -------- + .. code-block:: python + + class DivisorOfSix(Integer): + ''' + ASN.1 specification: + + Divisor-Of-6 ::= INTEGER (1 | 2 | 3 | 6) + ''' + subtypeSpec = SingleValueConstraint(1, 2, 3, 6) + + # this will succeed + divisor_of_six = DivisorOfSix(1) + + # this will raise ValueConstraintError + divisor_of_six = DivisorOfSix(7) + """ + def _setValues(self, values): + self._values = values + self._set = set(values) + + def _testValue(self, value, idx): + if value not in self._set: + raise error.ValueConstraintError(value) + + # Constrains can be merged or reduced + + def __contains__(self, item): + return item in self._set + + def __iter__(self): + return iter(self._set) + + def __add__(self, constraint): + return self.__class__(*(self._set.union(constraint))) + + def __sub__(self, constraint): + return self.__class__(*(self._set.difference(constraint))) + + +class ContainedSubtypeConstraint(AbstractConstraint): + """Create a ContainedSubtypeConstraint object. + + The ContainedSubtypeConstraint satisfies any value that + is present in the set of permitted values and also + satisfies included constraints. + + The ContainedSubtypeConstraint object can be applied to + any ASN.1 type. + + Parameters + ---------- + *values: + Full set of values and constraint objects permitted + by this constraint object. + + Examples + -------- + .. code-block:: python + + class DivisorOfEighteen(Integer): + ''' + ASN.1 specification: + + Divisors-of-18 ::= INTEGER (INCLUDES Divisors-of-6 | 9 | 18) + ''' + subtypeSpec = ContainedSubtypeConstraint( + SingleValueConstraint(1, 2, 3, 6), 9, 18 + ) + + # this will succeed + divisor_of_eighteen = DivisorOfEighteen(9) + + # this will raise ValueConstraintError + divisor_of_eighteen = DivisorOfEighteen(10) + """ + def _testValue(self, value, idx): + for constraint in self._values: + if isinstance(constraint, AbstractConstraint): + constraint(value, idx) + elif value not in self._set: + raise error.ValueConstraintError(value) + + +class ValueRangeConstraint(AbstractConstraint): + """Create a ValueRangeConstraint object. + + The ValueRangeConstraint satisfies any value that + falls in the range of permitted values. + + The ValueRangeConstraint object can only be applied + to :class:`~pyasn1.type.univ.Integer` and + :class:`~pyasn1.type.univ.Real` types. + + Parameters + ---------- + start: :class:`int` + Minimum permitted value in the range (inclusive) + + end: :class:`int` + Maximum permitted value in the range (inclusive) + + Examples + -------- + .. code-block:: python + + class TeenAgeYears(Integer): + ''' + ASN.1 specification: + + TeenAgeYears ::= INTEGER (13 .. 19) + ''' + subtypeSpec = ValueRangeConstraint(13, 19) + + # this will succeed + teen_year = TeenAgeYears(18) + + # this will raise ValueConstraintError + teen_year = TeenAgeYears(20) + """ + def _testValue(self, value, idx): + if value < self.start or value > self.stop: + raise error.ValueConstraintError(value) + + def _setValues(self, values): + if len(values) != 2: + raise error.PyAsn1Error( + '%s: bad constraint values' % (self.__class__.__name__,) + ) + self.start, self.stop = values + if self.start > self.stop: + raise error.PyAsn1Error( + '%s: screwed constraint values (start > stop): %s > %s' % ( + self.__class__.__name__, + self.start, self.stop + ) + ) + AbstractConstraint._setValues(self, values) + + +class ValueSizeConstraint(ValueRangeConstraint): + """Create a ValueSizeConstraint object. + + The ValueSizeConstraint satisfies any value for + as long as its size falls within the range of + permitted sizes. + + The ValueSizeConstraint object can be applied + to :class:`~pyasn1.type.univ.BitString`, + :class:`~pyasn1.type.univ.OctetString` (including + all :ref:`character ASN.1 types `), + :class:`~pyasn1.type.univ.SequenceOf` + and :class:`~pyasn1.type.univ.SetOf` types. + + Parameters + ---------- + minimum: :class:`int` + Minimum permitted size of the value (inclusive) + + maximum: :class:`int` + Maximum permitted size of the value (inclusive) + + Examples + -------- + .. code-block:: python + + class BaseballTeamRoster(SetOf): + ''' + ASN.1 specification: + + BaseballTeamRoster ::= SET SIZE (1..25) OF PlayerNames + ''' + componentType = PlayerNames() + subtypeSpec = ValueSizeConstraint(1, 25) + + # this will succeed + team = BaseballTeamRoster() + team.extend(['Jan', 'Matej']) + encode(team) + + # this will raise ValueConstraintError + team = BaseballTeamRoster() + team.extend(['Jan'] * 26) + encode(team) + + Note + ---- + Whenever ValueSizeConstraint is applied to mutable types + (e.g. :class:`~pyasn1.type.univ.SequenceOf`, + :class:`~pyasn1.type.univ.SetOf`), constraint + validation only happens at the serialisation phase rather + than schema instantiation phase (as it is with immutable + types). + """ + def _testValue(self, value, idx): + valueSize = len(value) + if valueSize < self.start or valueSize > self.stop: + raise error.ValueConstraintError(value) + + +class PermittedAlphabetConstraint(SingleValueConstraint): + """Create a PermittedAlphabetConstraint object. + + The PermittedAlphabetConstraint satisfies any character + string for as long as all its characters are present in + the set of permitted characters. + + Objects of this type are iterable (emitting constraint values) and + can act as operands for some arithmetic operations e.g. addition + and subtraction. + + The PermittedAlphabetConstraint object can only be applied + to the :ref:`character ASN.1 types ` such as + :class:`~pyasn1.type.char.IA5String`. + + Parameters + ---------- + *alphabet: :class:`str` + Full set of characters permitted by this constraint object. + + Example + ------- + .. code-block:: python + + class BooleanValue(IA5String): + ''' + ASN.1 specification: + + BooleanValue ::= IA5String (FROM ('T' | 'F')) + ''' + subtypeSpec = PermittedAlphabetConstraint('T', 'F') + + # this will succeed + truth = BooleanValue('T') + truth = BooleanValue('TF') + + # this will raise ValueConstraintError + garbage = BooleanValue('TAF') + + ASN.1 `FROM ... EXCEPT ...` clause can be modelled by combining multiple + PermittedAlphabetConstraint objects into one: + + Example + ------- + .. code-block:: python + + class Lipogramme(IA5String): + ''' + ASN.1 specification: + + Lipogramme ::= + IA5String (FROM (ALL EXCEPT ("e"|"E"))) + ''' + subtypeSpec = ( + PermittedAlphabetConstraint(*string.printable) - + PermittedAlphabetConstraint('e', 'E') + ) + + # this will succeed + lipogramme = Lipogramme('A work of fiction?') + + # this will raise ValueConstraintError + lipogramme = Lipogramme('Eel') + + Note + ---- + Although `ConstraintsExclusion` object could seemingly be used for this + purpose, practically, for it to work, it needs to represent its operand + constraints as sets and intersect one with the other. That would require + the insight into the constraint values (and their types) that are otherwise + hidden inside the constraint object. + + Therefore it's more practical to model `EXCEPT` clause at + `PermittedAlphabetConstraint` level instead. + """ + def _setValues(self, values): + self._values = values + self._set = set(values) + + def _testValue(self, value, idx): + if not self._set.issuperset(value): + raise error.ValueConstraintError(value) + + +class ComponentPresentConstraint(AbstractConstraint): + """Create a ComponentPresentConstraint object. + + The ComponentPresentConstraint is only satisfied when the value + is not `None`. + + The ComponentPresentConstraint object is typically used with + `WithComponentsConstraint`. + + Examples + -------- + .. code-block:: python + + present = ComponentPresentConstraint() + + # this will succeed + present('whatever') + + # this will raise ValueConstraintError + present(None) + """ + def _setValues(self, values): + self._values = ('',) + + if values: + raise error.PyAsn1Error('No arguments expected') + + def _testValue(self, value, idx): + if value is None: + raise error.ValueConstraintError( + 'Component is not present:') + + +class ComponentAbsentConstraint(AbstractConstraint): + """Create a ComponentAbsentConstraint object. + + The ComponentAbsentConstraint is only satisfied when the value + is `None`. + + The ComponentAbsentConstraint object is typically used with + `WithComponentsConstraint`. + + Examples + -------- + .. code-block:: python + + absent = ComponentAbsentConstraint() + + # this will succeed + absent(None) + + # this will raise ValueConstraintError + absent('whatever') + """ + def _setValues(self, values): + self._values = ('',) + + if values: + raise error.PyAsn1Error('No arguments expected') + + def _testValue(self, value, idx): + if value is not None: + raise error.ValueConstraintError( + 'Component is not absent: %r' % value) + + +class WithComponentsConstraint(AbstractConstraint): + """Create a WithComponentsConstraint object. + + The `WithComponentsConstraint` satisfies any mapping object that has + constrained fields present or absent, what is indicated by + `ComponentPresentConstraint` and `ComponentAbsentConstraint` + objects respectively. + + The `WithComponentsConstraint` object is typically applied + to :class:`~pyasn1.type.univ.Set` or + :class:`~pyasn1.type.univ.Sequence` types. + + Parameters + ---------- + *fields: :class:`tuple` + Zero or more tuples of (`field`, `constraint`) indicating constrained + fields. + + Notes + ----- + On top of the primary use of `WithComponentsConstraint` (ensuring presence + or absence of particular components of a :class:`~pyasn1.type.univ.Set` or + :class:`~pyasn1.type.univ.Sequence`), it is also possible to pass any other + constraint objects or their combinations. In case of scalar fields, these + constraints will be verified in addition to the constraints belonging to + scalar components themselves. However, formally, these additional + constraints do not change the type of these ASN.1 objects. + + Examples + -------- + + .. code-block:: python + + class Item(Sequence): # Set is similar + ''' + ASN.1 specification: + + Item ::= SEQUENCE { + id INTEGER OPTIONAL, + name OCTET STRING OPTIONAL + } WITH COMPONENTS id PRESENT, name ABSENT | id ABSENT, name PRESENT + ''' + componentType = NamedTypes( + OptionalNamedType('id', Integer()), + OptionalNamedType('name', OctetString()) + ) + withComponents = ConstraintsUnion( + WithComponentsConstraint( + ('id', ComponentPresentConstraint()), + ('name', ComponentAbsentConstraint()) + ), + WithComponentsConstraint( + ('id', ComponentAbsentConstraint()), + ('name', ComponentPresentConstraint()) + ) + ) + + item = Item() + + # This will succeed + item['id'] = 1 + + # This will succeed + item.reset() + item['name'] = 'John' + + # This will fail (on encoding) + item.reset() + descr['id'] = 1 + descr['name'] = 'John' + """ + def _testValue(self, value, idx): + for field, constraint in self._values: + constraint(value.get(field)) + + def _setValues(self, values): + AbstractConstraint._setValues(self, values) + + +# This is a bit kludgy, meaning two op modes within a single constraint +class InnerTypeConstraint(AbstractConstraint): + """Value must satisfy the type and presence constraints""" + + def _testValue(self, value, idx): + if self.__singleTypeConstraint: + self.__singleTypeConstraint(value) + elif self.__multipleTypeConstraint: + if idx not in self.__multipleTypeConstraint: + raise error.ValueConstraintError(value) + constraint, status = self.__multipleTypeConstraint[idx] + if status == 'ABSENT': # XXX presence is not checked! + raise error.ValueConstraintError(value) + constraint(value) + + def _setValues(self, values): + self.__multipleTypeConstraint = {} + self.__singleTypeConstraint = None + for v in values: + if isinstance(v, tuple): + self.__multipleTypeConstraint[v[0]] = v[1], v[2] + else: + self.__singleTypeConstraint = v + AbstractConstraint._setValues(self, values) + + +# Logic operations on constraints + +class ConstraintsExclusion(AbstractConstraint): + """Create a ConstraintsExclusion logic operator object. + + The ConstraintsExclusion logic operator succeeds when the + value does *not* satisfy the operand constraint. + + The ConstraintsExclusion object can be applied to + any constraint and logic operator object. + + Parameters + ---------- + *constraints: + Constraint or logic operator objects. + + Examples + -------- + .. code-block:: python + + class LuckyNumber(Integer): + subtypeSpec = ConstraintsExclusion( + SingleValueConstraint(13) + ) + + # this will succeed + luckyNumber = LuckyNumber(12) + + # this will raise ValueConstraintError + luckyNumber = LuckyNumber(13) + + Note + ---- + The `FROM ... EXCEPT ...` ASN.1 clause should be modeled by combining + constraint objects into one. See `PermittedAlphabetConstraint` for more + information. + """ + def _testValue(self, value, idx): + for constraint in self._values: + try: + constraint(value, idx) + + except error.ValueConstraintError: + continue + + raise error.ValueConstraintError(value) + + def _setValues(self, values): + AbstractConstraint._setValues(self, values) + + +class AbstractConstraintSet(AbstractConstraint): + + def __getitem__(self, idx): + return self._values[idx] + + def __iter__(self): + return iter(self._values) + + def __add__(self, value): + return self.__class__(*(self._values + (value,))) + + def __radd__(self, value): + return self.__class__(*((value,) + self._values)) + + def __len__(self): + return len(self._values) + + # Constraints inclusion in sets + + def _setValues(self, values): + self._values = values + for constraint in values: + if constraint: + self._valueMap.add(constraint) + self._valueMap.update(constraint.getValueMap()) + + +class ConstraintsIntersection(AbstractConstraintSet): + """Create a ConstraintsIntersection logic operator object. + + The ConstraintsIntersection logic operator only succeeds + if *all* its operands succeed. + + The ConstraintsIntersection object can be applied to + any constraint and logic operator objects. + + The ConstraintsIntersection object duck-types the immutable + container object like Python :py:class:`tuple`. + + Parameters + ---------- + *constraints: + Constraint or logic operator objects. + + Examples + -------- + .. code-block:: python + + class CapitalAndSmall(IA5String): + ''' + ASN.1 specification: + + CapitalAndSmall ::= + IA5String (FROM ("A".."Z"|"a".."z")) + ''' + subtypeSpec = ConstraintsIntersection( + PermittedAlphabetConstraint('A', 'Z'), + PermittedAlphabetConstraint('a', 'z') + ) + + # this will succeed + capital_and_small = CapitalAndSmall('Hello') + + # this will raise ValueConstraintError + capital_and_small = CapitalAndSmall('hello') + """ + def _testValue(self, value, idx): + for constraint in self._values: + constraint(value, idx) + + +class ConstraintsUnion(AbstractConstraintSet): + """Create a ConstraintsUnion logic operator object. + + The ConstraintsUnion logic operator succeeds if + *at least* a single operand succeeds. + + The ConstraintsUnion object can be applied to + any constraint and logic operator objects. + + The ConstraintsUnion object duck-types the immutable + container object like Python :py:class:`tuple`. + + Parameters + ---------- + *constraints: + Constraint or logic operator objects. + + Examples + -------- + .. code-block:: python + + class CapitalOrSmall(IA5String): + ''' + ASN.1 specification: + + CapitalOrSmall ::= + IA5String (FROM ("A".."Z") | FROM ("a".."z")) + ''' + subtypeSpec = ConstraintsUnion( + PermittedAlphabetConstraint('A', 'Z'), + PermittedAlphabetConstraint('a', 'z') + ) + + # this will succeed + capital_or_small = CapitalAndSmall('Hello') + + # this will raise ValueConstraintError + capital_or_small = CapitalOrSmall('hello!') + """ + def _testValue(self, value, idx): + for constraint in self._values: + try: + constraint(value, idx) + except error.ValueConstraintError: + pass + else: + return + + raise error.ValueConstraintError( + 'all of %s failed for "%s"' % (self._values, value) + ) + +# TODO: +# refactor InnerTypeConstraint +# add tests for type check +# implement other constraint types +# make constraint validation easy to skip diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/error.py b/plugins/ldap-user-sync/vendor/pyasn1/type/error.py new file mode 100644 index 00000000..0ff082ab --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/error.py @@ -0,0 +1,11 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +from pyasn1.error import PyAsn1Error + + +class ValueConstraintError(PyAsn1Error): + pass diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/namedtype.py b/plugins/ldap-user-sync/vendor/pyasn1/type/namedtype.py new file mode 100644 index 00000000..5f6c4ca3 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/namedtype.py @@ -0,0 +1,550 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import sys + +from pyasn1 import error +from pyasn1.type import tag +from pyasn1.type import tagmap + +__all__ = ['NamedType', 'OptionalNamedType', 'DefaultedNamedType', + 'NamedTypes'] + +class NamedType(object): + """Create named field object for a constructed ASN.1 type. + + The |NamedType| object represents a single name and ASN.1 type of a constructed ASN.1 type. + + |NamedType| objects are immutable and duck-type Python :class:`tuple` objects + holding *name* and *asn1Object* components. + + Parameters + ---------- + name: :py:class:`str` + Field name + + asn1Object: + ASN.1 type object + """ + isOptional = False + isDefaulted = False + + def __init__(self, name, asn1Object, openType=None): + self.__name = name + self.__type = asn1Object + self.__nameAndType = name, asn1Object + self.__openType = openType + + def __repr__(self): + representation = '%s=%r' % (self.name, self.asn1Object) + + if self.openType: + representation += ', open type %r' % self.openType + + return '<%s object, type %s>' % ( + self.__class__.__name__, representation) + + def __eq__(self, other): + return self.__nameAndType == other + + def __ne__(self, other): + return self.__nameAndType != other + + def __lt__(self, other): + return self.__nameAndType < other + + def __le__(self, other): + return self.__nameAndType <= other + + def __gt__(self, other): + return self.__nameAndType > other + + def __ge__(self, other): + return self.__nameAndType >= other + + def __hash__(self): + return hash(self.__nameAndType) + + def __getitem__(self, idx): + return self.__nameAndType[idx] + + def __iter__(self): + return iter(self.__nameAndType) + + @property + def name(self): + return self.__name + + @property + def asn1Object(self): + return self.__type + + @property + def openType(self): + return self.__openType + + # Backward compatibility + + def getName(self): + return self.name + + def getType(self): + return self.asn1Object + + +class OptionalNamedType(NamedType): + __doc__ = NamedType.__doc__ + + isOptional = True + + +class DefaultedNamedType(NamedType): + __doc__ = NamedType.__doc__ + + isDefaulted = True + + +class NamedTypes(object): + """Create a collection of named fields for a constructed ASN.1 type. + + The NamedTypes object represents a collection of named fields of a constructed ASN.1 type. + + *NamedTypes* objects are immutable and duck-type Python :class:`dict` objects + holding *name* as keys and ASN.1 type object as values. + + Parameters + ---------- + *namedTypes: :class:`~pyasn1.type.namedtype.NamedType` + + Examples + -------- + + .. code-block:: python + + class Description(Sequence): + ''' + ASN.1 specification: + + Description ::= SEQUENCE { + surname IA5String, + first-name IA5String OPTIONAL, + age INTEGER DEFAULT 40 + } + ''' + componentType = NamedTypes( + NamedType('surname', IA5String()), + OptionalNamedType('first-name', IA5String()), + DefaultedNamedType('age', Integer(40)) + ) + + descr = Description() + descr['surname'] = 'Smith' + descr['first-name'] = 'John' + """ + def __init__(self, *namedTypes, **kwargs): + self.__namedTypes = namedTypes + self.__namedTypesLen = len(self.__namedTypes) + self.__minTagSet = self.__computeMinTagSet() + self.__nameToPosMap = self.__computeNameToPosMap() + self.__tagToPosMap = self.__computeTagToPosMap() + self.__ambiguousTypes = 'terminal' not in kwargs and self.__computeAmbiguousTypes() or {} + self.__uniqueTagMap = self.__computeTagMaps(unique=True) + self.__nonUniqueTagMap = self.__computeTagMaps(unique=False) + self.__hasOptionalOrDefault = any([True for namedType in self.__namedTypes + if namedType.isDefaulted or namedType.isOptional]) + self.__hasOpenTypes = any([True for namedType in self.__namedTypes + if namedType.openType]) + + self.__requiredComponents = frozenset( + [idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted] + ) + self.__keys = frozenset([namedType.name for namedType in self.__namedTypes]) + self.__values = tuple([namedType.asn1Object for namedType in self.__namedTypes]) + self.__items = tuple([(namedType.name, namedType.asn1Object) for namedType in self.__namedTypes]) + + def __repr__(self): + representation = ', '.join(['%r' % x for x in self.__namedTypes]) + return '<%s object, types %s>' % ( + self.__class__.__name__, representation) + + def __eq__(self, other): + return self.__namedTypes == other + + def __ne__(self, other): + return self.__namedTypes != other + + def __lt__(self, other): + return self.__namedTypes < other + + def __le__(self, other): + return self.__namedTypes <= other + + def __gt__(self, other): + return self.__namedTypes > other + + def __ge__(self, other): + return self.__namedTypes >= other + + def __hash__(self): + return hash(self.__namedTypes) + + def __getitem__(self, idx): + try: + return self.__namedTypes[idx] + + except TypeError: + return self.__namedTypes[self.__nameToPosMap[idx]] + + def __contains__(self, key): + return key in self.__nameToPosMap + + def __iter__(self): + return (x[0] for x in self.__namedTypes) + + def __bool__(self): + return self.__namedTypesLen > 0 + + def __len__(self): + return self.__namedTypesLen + + # Python dict protocol + + def values(self): + return self.__values + + def keys(self): + return self.__keys + + def items(self): + return self.__items + + def clone(self): + return self.__class__(*self.__namedTypes) + + class PostponedError(object): + def __init__(self, errorMsg): + self.__errorMsg = errorMsg + + def __getitem__(self, item): + raise error.PyAsn1Error(self.__errorMsg) + + def __computeTagToPosMap(self): + tagToPosMap = {} + for idx, namedType in enumerate(self.__namedTypes): + tagMap = namedType.asn1Object.tagMap + if isinstance(tagMap, NamedTypes.PostponedError): + return tagMap + if not tagMap: + continue + for _tagSet in tagMap.presentTypes: + if _tagSet in tagToPosMap: + return NamedTypes.PostponedError('Duplicate component tag %s at %s' % (_tagSet, namedType)) + tagToPosMap[_tagSet] = idx + + return tagToPosMap + + def __computeNameToPosMap(self): + nameToPosMap = {} + for idx, namedType in enumerate(self.__namedTypes): + if namedType.name in nameToPosMap: + return NamedTypes.PostponedError('Duplicate component name %s at %s' % (namedType.name, namedType)) + nameToPosMap[namedType.name] = idx + + return nameToPosMap + + def __computeAmbiguousTypes(self): + ambiguousTypes = {} + partialAmbiguousTypes = () + for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))): + if namedType.isOptional or namedType.isDefaulted: + partialAmbiguousTypes = (namedType,) + partialAmbiguousTypes + else: + partialAmbiguousTypes = (namedType,) + if len(partialAmbiguousTypes) == len(self.__namedTypes): + ambiguousTypes[idx] = self + else: + ambiguousTypes[idx] = NamedTypes(*partialAmbiguousTypes, **dict(terminal=True)) + return ambiguousTypes + + def getTypeByPosition(self, idx): + """Return ASN.1 type object by its position in fields set. + + Parameters + ---------- + idx: :py:class:`int` + Field index + + Returns + ------- + : + ASN.1 type + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If given position is out of fields range + """ + try: + return self.__namedTypes[idx].asn1Object + + except IndexError: + raise error.PyAsn1Error('Type position out of range') + + def getPositionByType(self, tagSet): + """Return field position by its ASN.1 type. + + Parameters + ---------- + tagSet: :class:`~pysnmp.type.tag.TagSet` + ASN.1 tag set distinguishing one ASN.1 type from others. + + Returns + ------- + : :py:class:`int` + ASN.1 type position in fields set + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If *tagSet* is not present or ASN.1 types are not unique within callee *NamedTypes* + """ + try: + return self.__tagToPosMap[tagSet] + + except KeyError: + raise error.PyAsn1Error('Type %s not found' % (tagSet,)) + + def getNameByPosition(self, idx): + """Return field name by its position in fields set. + + Parameters + ---------- + idx: :py:class:`idx` + Field index + + Returns + ------- + : :py:class:`str` + Field name + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If given field name is not present in callee *NamedTypes* + """ + try: + return self.__namedTypes[idx].name + + except IndexError: + raise error.PyAsn1Error('Type position out of range') + + def getPositionByName(self, name): + """Return field position by filed name. + + Parameters + ---------- + name: :py:class:`str` + Field name + + Returns + ------- + : :py:class:`int` + Field position in fields set + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If *name* is not present or not unique within callee *NamedTypes* + """ + try: + return self.__nameToPosMap[name] + + except KeyError: + raise error.PyAsn1Error('Name %s not found' % (name,)) + + def getTagMapNearPosition(self, idx): + """Return ASN.1 types that are allowed at or past given field position. + + Some ASN.1 serialisation allow for skipping optional and defaulted fields. + Some constructed ASN.1 types allow reordering of the fields. When recovering + such objects it may be important to know which types can possibly be + present at any given position in the field sets. + + Parameters + ---------- + idx: :py:class:`int` + Field index + + Returns + ------- + : :class:`~pyasn1.type.tagmap.TagMap` + Map if ASN.1 types allowed at given field position + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If given position is out of fields range + """ + try: + return self.__ambiguousTypes[idx].tagMap + + except KeyError: + raise error.PyAsn1Error('Type position out of range') + + def getPositionNearType(self, tagSet, idx): + """Return the closest field position where given ASN.1 type is allowed. + + Some ASN.1 serialisation allow for skipping optional and defaulted fields. + Some constructed ASN.1 types allow reordering of the fields. When recovering + such objects it may be important to know at which field position, in field set, + given *tagSet* is allowed at or past *idx* position. + + Parameters + ---------- + tagSet: :class:`~pyasn1.type.tag.TagSet` + ASN.1 type which field position to look up + + idx: :py:class:`int` + Field position at or past which to perform ASN.1 type look up + + Returns + ------- + : :py:class:`int` + Field position in fields set + + Raises + ------ + ~pyasn1.error.PyAsn1Error + If *tagSet* is not present or not unique within callee *NamedTypes* + or *idx* is out of fields range + """ + try: + return idx + self.__ambiguousTypes[idx].getPositionByType(tagSet) + + except KeyError: + raise error.PyAsn1Error('Type position out of range') + + def __computeMinTagSet(self): + minTagSet = None + for namedType in self.__namedTypes: + asn1Object = namedType.asn1Object + + try: + tagSet = asn1Object.minTagSet + + except AttributeError: + tagSet = asn1Object.tagSet + + if minTagSet is None or tagSet < minTagSet: + minTagSet = tagSet + + return minTagSet or tag.TagSet() + + @property + def minTagSet(self): + """Return the minimal TagSet among ASN.1 type in callee *NamedTypes*. + + Some ASN.1 types/serialisation protocols require ASN.1 types to be + arranged based on their numerical tag value. The *minTagSet* property + returns that. + + Returns + ------- + : :class:`~pyasn1.type.tagset.TagSet` + Minimal TagSet among ASN.1 types in callee *NamedTypes* + """ + return self.__minTagSet + + def __computeTagMaps(self, unique): + presentTypes = {} + skipTypes = {} + defaultType = None + for namedType in self.__namedTypes: + tagMap = namedType.asn1Object.tagMap + if isinstance(tagMap, NamedTypes.PostponedError): + return tagMap + for tagSet in tagMap: + if unique and tagSet in presentTypes: + return NamedTypes.PostponedError('Non-unique tagSet %s of %s at %s' % (tagSet, namedType, self)) + presentTypes[tagSet] = namedType.asn1Object + skipTypes.update(tagMap.skipTypes) + + if defaultType is None: + defaultType = tagMap.defaultType + elif tagMap.defaultType is not None: + return NamedTypes.PostponedError('Duplicate default ASN.1 type at %s' % (self,)) + + return tagmap.TagMap(presentTypes, skipTypes, defaultType) + + @property + def tagMap(self): + """Return a *TagMap* object from tags and types recursively. + + Return a :class:`~pyasn1.type.tagmap.TagMap` object by + combining tags from *TagMap* objects of children types and + associating them with their immediate child type. + + Example + ------- + .. code-block:: python + + OuterType ::= CHOICE { + innerType INTEGER + } + + Calling *.tagMap* on *OuterType* will yield a map like this: + + .. code-block:: python + + Integer.tagSet -> Choice + """ + return self.__nonUniqueTagMap + + @property + def tagMapUnique(self): + """Return a *TagMap* object from unique tags and types recursively. + + Return a :class:`~pyasn1.type.tagmap.TagMap` object by + combining tags from *TagMap* objects of children types and + associating them with their immediate child type. + + Example + ------- + .. code-block:: python + + OuterType ::= CHOICE { + innerType INTEGER + } + + Calling *.tagMapUnique* on *OuterType* will yield a map like this: + + .. code-block:: python + + Integer.tagSet -> Choice + + Note + ---- + + Duplicate *TagSet* objects found in the tree of children + types would cause error. + """ + return self.__uniqueTagMap + + @property + def hasOptionalOrDefault(self): + return self.__hasOptionalOrDefault + + @property + def hasOpenTypes(self): + return self.__hasOpenTypes + + @property + def namedTypes(self): + return tuple(self.__namedTypes) + + @property + def requiredComponents(self): + return self.__requiredComponents diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/namedval.py b/plugins/ldap-user-sync/vendor/pyasn1/type/namedval.py new file mode 100644 index 00000000..46a6496d --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/namedval.py @@ -0,0 +1,192 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +# ASN.1 named integers +# +from pyasn1 import error + +__all__ = ['NamedValues'] + + +class NamedValues(object): + """Create named values object. + + The |NamedValues| object represents a collection of string names + associated with numeric IDs. These objects are used for giving + names to otherwise numerical values. + + |NamedValues| objects are immutable and duck-type Python + :class:`dict` object mapping ID to name and vice-versa. + + Parameters + ---------- + *args: variable number of two-element :py:class:`tuple` + + name: :py:class:`str` + Value label + + value: :py:class:`int` + Numeric value + + Keyword Args + ------------ + name: :py:class:`str` + Value label + + value: :py:class:`int` + Numeric value + + Examples + -------- + + .. code-block:: pycon + + >>> nv = NamedValues('a', 'b', ('c', 0), d=1) + >>> nv + >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3} + >>> nv[0] + 'c' + >>> nv['a'] + 2 + """ + def __init__(self, *args, **kwargs): + self.__names = {} + self.__numbers = {} + + anonymousNames = [] + + for namedValue in args: + if isinstance(namedValue, (tuple, list)): + try: + name, number = namedValue + + except ValueError: + raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,)) + + else: + anonymousNames.append(namedValue) + continue + + if name in self.__names: + raise error.PyAsn1Error('Duplicate name %s' % (name,)) + + if number in self.__numbers: + raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number)) + + self.__names[name] = number + self.__numbers[number] = name + + for name, number in kwargs.items(): + if name in self.__names: + raise error.PyAsn1Error('Duplicate name %s' % (name,)) + + if number in self.__numbers: + raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number)) + + self.__names[name] = number + self.__numbers[number] = name + + if anonymousNames: + + number = self.__numbers and max(self.__numbers) + 1 or 0 + + for name in anonymousNames: + + if name in self.__names: + raise error.PyAsn1Error('Duplicate name %s' % (name,)) + + self.__names[name] = number + self.__numbers[number] = name + + number += 1 + + def __repr__(self): + representation = ', '.join(['%s=%d' % x for x in self.items()]) + + if len(representation) > 64: + representation = representation[:32] + '...' + representation[-32:] + + return '<%s object, enums %s>' % ( + self.__class__.__name__, representation) + + def __eq__(self, other): + return dict(self) == other + + def __ne__(self, other): + return dict(self) != other + + def __lt__(self, other): + return dict(self) < other + + def __le__(self, other): + return dict(self) <= other + + def __gt__(self, other): + return dict(self) > other + + def __ge__(self, other): + return dict(self) >= other + + def __hash__(self): + return hash(self.items()) + + # Python dict protocol (read-only) + + def __getitem__(self, key): + try: + return self.__numbers[key] + + except KeyError: + return self.__names[key] + + def __len__(self): + return len(self.__names) + + def __contains__(self, key): + return key in self.__names or key in self.__numbers + + def __iter__(self): + return iter(self.__names) + + def values(self): + return iter(self.__numbers) + + def keys(self): + return iter(self.__names) + + def items(self): + for name in self.__names: + yield name, self.__names[name] + + # support merging + + def __add__(self, namedValues): + return self.__class__(*tuple(self.items()) + tuple(namedValues.items())) + + # XXX clone/subtype? + + def clone(self, *args, **kwargs): + new = self.__class__(*args, **kwargs) + return self + new + + # legacy protocol + + def getName(self, value): + if value in self.__numbers: + return self.__numbers[value] + + def getValue(self, name): + if name in self.__names: + return self.__names[name] + + def getValues(self, *names): + try: + return [self.__names[name] for name in names] + + except KeyError: + raise error.PyAsn1Error( + 'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),) + ) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/opentype.py b/plugins/ldap-user-sync/vendor/pyasn1/type/opentype.py new file mode 100644 index 00000000..5a15f896 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/opentype.py @@ -0,0 +1,104 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# + +__all__ = ['OpenType'] + + +class OpenType(object): + """Create ASN.1 type map indexed by a value + + The *OpenType* object models an untyped field of a constructed ASN.1 + type. In ASN.1 syntax it is usually represented by the + `ANY DEFINED BY` for scalars or `SET OF ANY DEFINED BY`, + `SEQUENCE OF ANY DEFINED BY` for container types clauses. Typically + used together with :class:`~pyasn1.type.univ.Any` object. + + OpenType objects duck-type a read-only Python :class:`dict` objects, + however the passed `typeMap` is not copied, but stored by reference. + That means the user can manipulate `typeMap` at run time having this + reflected on *OpenType* object behavior. + + The |OpenType| class models an untyped field of a constructed ASN.1 + type. In ASN.1 syntax it is usually represented by the + `ANY DEFINED BY` for scalars or `SET OF ANY DEFINED BY`, + `SEQUENCE OF ANY DEFINED BY` for container types clauses. Typically + used with :class:`~pyasn1.type.univ.Any` type. + + Parameters + ---------- + name: :py:class:`str` + Field name + + typeMap: :py:class:`dict` + A map of value->ASN.1 type. It's stored by reference and can be + mutated later to register new mappings. + + Examples + -------- + + For untyped scalars: + + .. code-block:: python + + openType = OpenType( + 'id', {1: Integer(), + 2: OctetString()} + ) + Sequence( + componentType=NamedTypes( + NamedType('id', Integer()), + NamedType('blob', Any(), openType=openType) + ) + ) + + For untyped `SET OF` or `SEQUENCE OF` vectors: + + .. code-block:: python + + openType = OpenType( + 'id', {1: Integer(), + 2: OctetString()} + ) + Sequence( + componentType=NamedTypes( + NamedType('id', Integer()), + NamedType('blob', SetOf(componentType=Any()), + openType=openType) + ) + ) + """ + + def __init__(self, name, typeMap=None): + self.__name = name + if typeMap is None: + self.__typeMap = {} + else: + self.__typeMap = typeMap + + @property + def name(self): + return self.__name + + # Python dict protocol + + def values(self): + return self.__typeMap.values() + + def keys(self): + return self.__typeMap.keys() + + def items(self): + return self.__typeMap.items() + + def __contains__(self, key): + return key in self.__typeMap + + def __getitem__(self, key): + return self.__typeMap[key] + + def __iter__(self): + return iter(self.__typeMap) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/tag.py b/plugins/ldap-user-sync/vendor/pyasn1/type/tag.py new file mode 100644 index 00000000..28cd3fdb --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/tag.py @@ -0,0 +1,347 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +from pyasn1 import error + +__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext', + 'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed', + 'tagCategoryImplicit', 'tagCategoryExplicit', + 'tagCategoryUntagged', 'Tag', 'TagSet'] + +#: Identifier for ASN.1 class UNIVERSAL +tagClassUniversal = 0x00 + +#: Identifier for ASN.1 class APPLICATION +tagClassApplication = 0x40 + +#: Identifier for ASN.1 class context-specific +tagClassContext = 0x80 + +#: Identifier for ASN.1 class private +tagClassPrivate = 0xC0 + +#: Identifier for "simple" ASN.1 structure (e.g. scalar) +tagFormatSimple = 0x00 + +#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components) +tagFormatConstructed = 0x20 + +tagCategoryImplicit = 0x01 +tagCategoryExplicit = 0x02 +tagCategoryUntagged = 0x04 + + +def _tagIdToStr(tagId): + # Decimal rendering of a huge tag ID can exceed the interpreter's + # integer-to-string conversion limit (sys.get_int_max_str_digits(), + # Python 3.11+) and raise ValueError; hexadecimal is not limited + try: + return str(tagId) + except ValueError: + return hex(tagId) + + +class Tag(object): + """Create ASN.1 tag + + Represents ASN.1 tag that can be attached to a ASN.1 type to make + types distinguishable from each other. + + *Tag* objects are immutable and duck-type Python :class:`tuple` objects + holding three integer components of a tag. + + Parameters + ---------- + tagClass: :py:class:`int` + Tag *class* value + + tagFormat: :py:class:`int` + Tag *format* value + + tagId: :py:class:`int` + Tag ID value + """ + def __init__(self, tagClass, tagFormat, tagId): + if tagId < 0: + raise error.PyAsn1Error( + 'Negative tag ID (%s) not allowed' % _tagIdToStr(tagId)) + self.__tagClass = tagClass + self.__tagFormat = tagFormat + self.__tagId = tagId + self.__tagClassId = tagClass, tagId + self.__hash = hash(self.__tagClassId) + + def __repr__(self): + representation = '[%s:%s:%s]' % ( + self.__tagClass, self.__tagFormat, _tagIdToStr(self.__tagId)) + return '<%s object, tag %s>' % ( + self.__class__.__name__, representation) + + def __eq__(self, other): + return self.__tagClassId == other + + def __ne__(self, other): + return self.__tagClassId != other + + def __lt__(self, other): + return self.__tagClassId < other + + def __le__(self, other): + return self.__tagClassId <= other + + def __gt__(self, other): + return self.__tagClassId > other + + def __ge__(self, other): + return self.__tagClassId >= other + + def __hash__(self): + return self.__hash + + def __getitem__(self, idx): + if idx == 0: + return self.__tagClass + elif idx == 1: + return self.__tagFormat + elif idx == 2: + return self.__tagId + else: + raise IndexError + + def __iter__(self): + yield self.__tagClass + yield self.__tagFormat + yield self.__tagId + + def __and__(self, otherTag): + return self.__class__(self.__tagClass & otherTag.tagClass, + self.__tagFormat & otherTag.tagFormat, + self.__tagId & otherTag.tagId) + + def __or__(self, otherTag): + return self.__class__(self.__tagClass | otherTag.tagClass, + self.__tagFormat | otherTag.tagFormat, + self.__tagId | otherTag.tagId) + + @property + def tagClass(self): + """ASN.1 tag class + + Returns + ------- + : :py:class:`int` + Tag class + """ + return self.__tagClass + + @property + def tagFormat(self): + """ASN.1 tag format + + Returns + ------- + : :py:class:`int` + Tag format + """ + return self.__tagFormat + + @property + def tagId(self): + """ASN.1 tag ID + + Returns + ------- + : :py:class:`int` + Tag ID + """ + return self.__tagId + + +class TagSet(object): + """Create a collection of ASN.1 tags + + Represents a combination of :class:`~pyasn1.type.tag.Tag` objects + that can be attached to a ASN.1 type to make types distinguishable + from each other. + + *TagSet* objects are immutable and duck-type Python :class:`tuple` objects + holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects. + + Parameters + ---------- + baseTag: :class:`~pyasn1.type.tag.Tag` + Base *Tag* object. This tag survives IMPLICIT tagging. + + *superTags: :class:`~pyasn1.type.tag.Tag` + Additional *Tag* objects taking part in subtyping. + + Examples + -------- + .. code-block:: python + + class OrderNumber(NumericString): + ''' + ASN.1 specification + + Order-number ::= + [APPLICATION 5] IMPLICIT NumericString + ''' + tagSet = NumericString.tagSet.tagImplicitly( + Tag(tagClassApplication, tagFormatSimple, 5) + ) + + orderNumber = OrderNumber('1234') + """ + def __init__(self, baseTag=(), *superTags): + self.__baseTag = baseTag + self.__superTags = superTags + self.__superTagsClassId = tuple( + [(superTag.tagClass, superTag.tagId) for superTag in superTags] + ) + self.__lenOfSuperTags = len(superTags) + self.__hash = hash(self.__superTagsClassId) + + def __repr__(self): + representation = '-'.join( + ['%s:%s:%s' % (x.tagClass, x.tagFormat, _tagIdToStr(x.tagId)) + for x in self.__superTags]) + if representation: + representation = 'tags ' + representation + else: + representation = 'untagged' + + return '<%s object, %s>' % (self.__class__.__name__, representation) + + def __add__(self, superTag): + return self.__class__(self.__baseTag, *self.__superTags + (superTag,)) + + def __radd__(self, superTag): + return self.__class__(self.__baseTag, *(superTag,) + self.__superTags) + + def __getitem__(self, i): + if i.__class__ is slice: + return self.__class__(self.__baseTag, *self.__superTags[i]) + else: + return self.__superTags[i] + + def __eq__(self, other): + return self.__superTagsClassId == other + + def __ne__(self, other): + return self.__superTagsClassId != other + + def __lt__(self, other): + return self.__superTagsClassId < other + + def __le__(self, other): + return self.__superTagsClassId <= other + + def __gt__(self, other): + return self.__superTagsClassId > other + + def __ge__(self, other): + return self.__superTagsClassId >= other + + def __hash__(self): + return self.__hash + + def __len__(self): + return self.__lenOfSuperTags + + @property + def baseTag(self): + """Return base ASN.1 tag + + Returns + ------- + : :class:`~pyasn1.type.tag.Tag` + Base tag of this *TagSet* + """ + return self.__baseTag + + @property + def superTags(self): + """Return ASN.1 tags + + Returns + ------- + : :py:class:`tuple` + Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains + """ + return self.__superTags + + def tagExplicitly(self, superTag): + """Return explicitly tagged *TagSet* + + Create a new *TagSet* representing callee *TagSet* explicitly tagged + with passed tag(s). With explicit tagging mode, new tags are appended + to existing tag(s). + + Parameters + ---------- + superTag: :class:`~pyasn1.type.tag.Tag` + *Tag* object to tag this *TagSet* + + Returns + ------- + : :class:`~pyasn1.type.tag.TagSet` + New *TagSet* object + """ + if superTag.tagClass == tagClassUniversal: + raise error.PyAsn1Error("Can't tag with UNIVERSAL class tag") + if superTag.tagFormat != tagFormatConstructed: + superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId) + return self + superTag + + def tagImplicitly(self, superTag): + """Return implicitly tagged *TagSet* + + Create a new *TagSet* representing callee *TagSet* implicitly tagged + with passed tag(s). With implicit tagging mode, new tag(s) replace the + last existing tag. + + Parameters + ---------- + superTag: :class:`~pyasn1.type.tag.Tag` + *Tag* object to tag this *TagSet* + + Returns + ------- + : :class:`~pyasn1.type.tag.TagSet` + New *TagSet* object + """ + if self.__superTags: + superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId) + return self[:-1] + superTag + + def isSuperTagSetOf(self, tagSet): + """Test type relationship against given *TagSet* + + The callee is considered to be a supertype of given *TagSet* + tag-wise if all tags in *TagSet* are present in the callee and + they are in the same order. + + Parameters + ---------- + tagSet: :class:`~pyasn1.type.tag.TagSet` + *TagSet* object to evaluate against the callee + + Returns + ------- + : :py:class:`bool` + :obj:`True` if callee is a supertype of *tagSet* + """ + if len(tagSet) < self.__lenOfSuperTags: + return False + return self.__superTags == tagSet[:self.__lenOfSuperTags] + + # Backward compatibility + + def getBaseTag(self): + return self.__baseTag + +def initTagSet(tag): + return TagSet(tag, tag) diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/tagmap.py b/plugins/ldap-user-sync/vendor/pyasn1/type/tagmap.py new file mode 100644 index 00000000..7f8a955a --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/tagmap.py @@ -0,0 +1,96 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +from pyasn1 import error + +__all__ = ['TagMap'] + + +class TagMap(object): + """Map *TagSet* objects to ASN.1 types + + Create an object mapping *TagSet* object to ASN.1 type. + + *TagMap* objects are immutable and duck-type read-only Python + :class:`dict` objects holding *TagSet* objects as keys and ASN.1 + type objects as values. + + Parameters + ---------- + presentTypes: :py:class:`dict` + Map of :class:`~pyasn1.type.tag.TagSet` to ASN.1 objects considered + as being unconditionally present in the *TagMap*. + + skipTypes: :py:class:`dict` + A collection of :class:`~pyasn1.type.tag.TagSet` objects considered + as absent in the *TagMap* even when *defaultType* is present. + + defaultType: ASN.1 type object + An ASN.1 type object callee *TagMap* returns for any *TagSet* key not present + in *presentTypes* (unless given key is present in *skipTypes*). + """ + def __init__(self, presentTypes=None, skipTypes=None, defaultType=None): + self.__presentTypes = presentTypes or {} + self.__skipTypes = skipTypes or {} + self.__defaultType = defaultType + + def __contains__(self, tagSet): + return (tagSet in self.__presentTypes or + self.__defaultType is not None and tagSet not in self.__skipTypes) + + def __getitem__(self, tagSet): + try: + return self.__presentTypes[tagSet] + except KeyError: + if self.__defaultType is None: + raise + elif tagSet in self.__skipTypes: + raise error.PyAsn1Error('Key in negative map') + else: + return self.__defaultType + + def __iter__(self): + return iter(self.__presentTypes) + + def __repr__(self): + representation = '%s object' % self.__class__.__name__ + + if self.__presentTypes: + representation += ', present %s' % repr(self.__presentTypes) + + if self.__skipTypes: + representation += ', skip %s' % repr(self.__skipTypes) + + if self.__defaultType is not None: + representation += ', default %s' % repr(self.__defaultType) + + return '<%s>' % representation + + @property + def presentTypes(self): + """Return *TagSet* to ASN.1 type map present in callee *TagMap*""" + return self.__presentTypes + + @property + def skipTypes(self): + """Return *TagSet* collection unconditionally absent in callee *TagMap*""" + return self.__skipTypes + + @property + def defaultType(self): + """Return default ASN.1 type being returned for any missing *TagSet*""" + return self.__defaultType + + # Backward compatibility + + def getPosMap(self): + return self.presentTypes + + def getNegMap(self): + return self.skipTypes + + def getDef(self): + return self.defaultType diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/univ.py b/plugins/ldap-user-sync/vendor/pyasn1/type/univ.py new file mode 100644 index 00000000..8b786dd9 --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/univ.py @@ -0,0 +1,3338 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import math +import sys + +from pyasn1 import error +from pyasn1.codec.ber import eoo +from pyasn1.compat import integer +from pyasn1.type import base +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import tag +from pyasn1.type import tagmap + +NoValue = base.NoValue +noValue = NoValue() + +__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null', + 'ObjectIdentifier', 'Real', 'Enumerated', + 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf', + 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any', + 'NoValue', 'noValue'] + +# "Simple" ASN.1 types (yet incomplete) + + +class Integer(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`int` objects. + + Keyword Args + ------------ + value: :class:`int`, :class:`str` or |ASN.1| object + Python :class:`int` or :class:`str` literal or |ASN.1| class + instance. If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` + Object representing non-default symbolic aliases for numbers + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + + .. code-block:: python + + class ErrorCode(Integer): + ''' + ASN.1 specification: + + ErrorCode ::= + INTEGER { disk-full(1), no-disk(-1), + disk-not-formatted(2) } + + error ErrorCode ::= disk-full + ''' + namedValues = NamedValues( + ('disk-full', 1), ('no-disk', -1), + ('disk-not-formatted', 2) + ) + + error = ErrorCode('disk-full') + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object + #: representing symbolic aliases for numbers + namedValues = namedval.NamedValues() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + def __init__(self, value=noValue, **kwargs): + if 'namedValues' not in kwargs: + kwargs['namedValues'] = self.namedValues + + base.SimpleAsn1Type.__init__(self, value, **kwargs) + + def __and__(self, value): + return self.clone(self._value & value) + + def __rand__(self, value): + return self.clone(value & self._value) + + def __or__(self, value): + return self.clone(self._value | value) + + def __ror__(self, value): + return self.clone(value | self._value) + + def __xor__(self, value): + return self.clone(self._value ^ value) + + def __rxor__(self, value): + return self.clone(value ^ self._value) + + def __lshift__(self, value): + return self.clone(self._value << value) + + def __rshift__(self, value): + return self.clone(self._value >> value) + + def __add__(self, value): + return self.clone(self._value + value) + + def __radd__(self, value): + return self.clone(value + self._value) + + def __sub__(self, value): + return self.clone(self._value - value) + + def __rsub__(self, value): + return self.clone(value - self._value) + + def __mul__(self, value): + return self.clone(self._value * value) + + def __rmul__(self, value): + return self.clone(value * self._value) + + def __mod__(self, value): + return self.clone(self._value % value) + + def __rmod__(self, value): + return self.clone(value % self._value) + + def __pow__(self, value, modulo=None): + return self.clone(pow(self._value, value, modulo)) + + def __rpow__(self, value): + return self.clone(pow(value, self._value)) + + def __floordiv__(self, value): + return self.clone(self._value // value) + + def __rfloordiv__(self, value): + return self.clone(value // self._value) + + def __truediv__(self, value): + return Real(self._value / value) + + def __rtruediv__(self, value): + return Real(value / self._value) + + def __divmod__(self, value): + return self.clone(divmod(self._value, value)) + + def __rdivmod__(self, value): + return self.clone(divmod(value, self._value)) + + __hash__ = base.SimpleAsn1Type.__hash__ + + def __int__(self): + return int(self._value) + + def __float__(self): + return float(self._value) + + def __abs__(self): + return self.clone(abs(self._value)) + + def __index__(self): + return int(self._value) + + def __pos__(self): + return self.clone(+self._value) + + def __neg__(self): + return self.clone(-self._value) + + def __invert__(self): + return self.clone(~self._value) + + def __round__(self, n=0): + r = round(self._value, n) + if n: + return self.clone(r) + else: + return r + + def __floor__(self): + return math.floor(self._value) + + def __ceil__(self): + return math.ceil(self._value) + + def __trunc__(self): + return self.clone(math.trunc(self._value)) + + def __lt__(self, value): + return self._value < value + + def __le__(self, value): + return self._value <= value + + def __eq__(self, value): + return self._value == value + + def __ne__(self, value): + return self._value != value + + def __gt__(self, value): + return self._value > value + + def __ge__(self, value): + return self._value >= value + + def prettyIn(self, value): + try: + return int(value) + + except ValueError: + try: + return self.namedValues[value] + + except KeyError as exc: + raise error.PyAsn1Error( + 'Can\'t coerce %r into integer: %s' % (value, exc) + ) + + def prettyOut(self, value): + try: + return str(self.namedValues[value]) + + except KeyError: + return str(value) + + # backward compatibility + + def getNamedValues(self): + return self.namedValues + + +class Boolean(Integer): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`int` objects. + + Keyword Args + ------------ + value: :class:`int`, :class:`str` or |ASN.1| object + Python :class:`int` or :class:`str` literal or |ASN.1| class + instance. If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s).Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` + Object representing non-default symbolic aliases for numbers + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class RoundResult(Boolean): + ''' + ASN.1 specification: + + RoundResult ::= BOOLEAN + + ok RoundResult ::= TRUE + ko RoundResult ::= FALSE + ''' + ok = RoundResult(True) + ko = RoundResult(False) + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01), + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1) + + #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object + #: representing symbolic aliases for numbers + namedValues = namedval.NamedValues(('False', 0), ('True', 1)) + + # Optimization for faster codec lookup + typeId = Integer.getTypeId() + + +class SizedInteger(int): + bitLength = leadingZeroBits = None + + def setBitLength(self, bitLength): + self.bitLength = bitLength + self.leadingZeroBits = max(bitLength - self.bit_length(), 0) + return self + + def __len__(self): + if self.bitLength is None: + self.setBitLength(self.bit_length()) + + return self.bitLength + + +class BitString(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type both Python :class:`tuple` (as a tuple + of bits) and :class:`int` objects. + + Keyword Args + ------------ + value: :class:`int`, :class:`str` or |ASN.1| object + Python :class:`int` or :class:`str` literal representing binary + or hexadecimal number or sequence of integer bits or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` + Object representing non-default symbolic aliases for numbers + + binValue: :py:class:`str` + Binary string initializer to use instead of the *value*. + Example: '10110011'. + + hexValue: :py:class:`str` + Hexadecimal string initializer to use instead of the *value*. + Example: 'DEADBEEF'. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class Rights(BitString): + ''' + ASN.1 specification: + + Rights ::= BIT STRING { user-read(0), user-write(1), + group-read(2), group-write(3), + other-read(4), other-write(5) } + + group1 Rights ::= { group-read, group-write } + group2 Rights ::= '0011'B + group3 Rights ::= '3'H + ''' + namedValues = NamedValues( + ('user-read', 0), ('user-write', 1), + ('group-read', 2), ('group-write', 3), + ('other-read', 4), ('other-write', 5) + ) + + group1 = Rights(('group-read', 'group-write')) + group2 = Rights('0011') + group3 = Rights(0x3) + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object + #: representing symbolic aliases for numbers + namedValues = namedval.NamedValues() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + defaultBinValue = defaultHexValue = noValue + + def __init__(self, value=noValue, **kwargs): + if value is noValue: + if kwargs: + try: + value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True) + + except KeyError: + pass + + try: + value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True) + + except KeyError: + pass + + if value is noValue: + if self.defaultBinValue is not noValue: + value = self.fromBinaryString(self.defaultBinValue, internalFormat=True) + + elif self.defaultHexValue is not noValue: + value = self.fromHexString(self.defaultHexValue, internalFormat=True) + + if 'namedValues' not in kwargs: + kwargs['namedValues'] = self.namedValues + + base.SimpleAsn1Type.__init__(self, value, **kwargs) + + def __str__(self): + return self.asBinary() + + def __eq__(self, other): + other = self.prettyIn(other) + return self is other or self._value == other and len(self._value) == len(other) + + def __ne__(self, other): + other = self.prettyIn(other) + return self._value != other or len(self._value) != len(other) + + def __lt__(self, other): + other = self.prettyIn(other) + return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other + + def __le__(self, other): + other = self.prettyIn(other) + return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other + + def __gt__(self, other): + other = self.prettyIn(other) + return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other + + def __ge__(self, other): + other = self.prettyIn(other) + return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other + + # Immutable sequence object protocol + + def __len__(self): + return len(self._value) + + def __getitem__(self, i): + if i.__class__ is slice: + return self.clone([self[x] for x in range(*i.indices(len(self)))]) + else: + length = len(self._value) - 1 + if i > length or i < 0: + raise IndexError('bit index out of range') + return (self._value >> (length - i)) & 1 + + def __iter__(self): + length = len(self._value) + while length: + length -= 1 + yield (self._value >> length) & 1 + + def __reversed__(self): + return reversed(tuple(self)) + + # arithmetic operators + + def __add__(self, value): + value = self.prettyIn(value) + return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value))) + + def __radd__(self, value): + value = self.prettyIn(value) + return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value))) + + def __mul__(self, value): + bitString = self._value + while value > 1: + bitString <<= len(self._value) + bitString |= self._value + value -= 1 + return self.clone(bitString) + + def __rmul__(self, value): + return self * value + + def __lshift__(self, count): + return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count)) + + def __rshift__(self, count): + return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count))) + + def __int__(self): + return int(self._value) + + def __float__(self): + return float(self._value) + + def asNumbers(self): + """Get |ASN.1| value as a sequence of 8-bit integers. + + If |ASN.1| object length is not a multiple of 8, result + will be left-padded with zeros. + """ + return tuple(self.asOctets()) + + def asOctets(self): + """Get |ASN.1| value as a sequence of octets. + + If |ASN.1| object length is not a multiple of 8, result + will be left-padded with zeros. + """ + return integer.to_bytes(self._value, length=len(self)) + + def asInteger(self): + """Get |ASN.1| value as a single integer value. + """ + return self._value + + def asBinary(self): + """Get |ASN.1| value as a text string of bits. + """ + binString = bin(self._value)[2:] + return '0' * (len(self._value) - len(binString)) + binString + + @classmethod + def fromHexString(cls, value, internalFormat=False, prepend=None): + """Create a |ASN.1| object initialized from the hex string. + + Parameters + ---------- + value: :class:`str` + Text string like 'DEADBEEF' + """ + try: + value = SizedInteger(value, 16).setBitLength(len(value) * 4) + + except ValueError as exc: + raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, exc)) + + if prepend is not None: + value = SizedInteger( + (SizedInteger(prepend) << len(value)) | value + ).setBitLength(len(prepend) + len(value)) + + if not internalFormat: + value = cls(value) + + return value + + @classmethod + def fromBinaryString(cls, value, internalFormat=False, prepend=None): + """Create a |ASN.1| object initialized from a string of '0' and '1'. + + Parameters + ---------- + value: :class:`str` + Text string like '1010111' + """ + try: + value = SizedInteger(value or '0', 2).setBitLength(len(value)) + + except ValueError as exc: + raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, exc)) + + if prepend is not None: + value = SizedInteger( + (SizedInteger(prepend) << len(value)) | value + ).setBitLength(len(prepend) + len(value)) + + if not internalFormat: + value = cls(value) + + return value + + @classmethod + def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0): + """Create a |ASN.1| object initialized from a string. + + Parameters + ---------- + value: :class:`bytes` + Text string like b'\\\\x01\\\\xff' + """ + value = SizedInteger(int.from_bytes(bytes(value), 'big') >> padding).setBitLength(len(value) * 8 - padding) + + if prepend is not None: + value = SizedInteger( + (SizedInteger(prepend) << len(value)) | value + ).setBitLength(len(prepend) + len(value)) + + if not internalFormat: + value = cls(value) + + return value + + def prettyIn(self, value): + if isinstance(value, SizedInteger): + return value + elif isinstance(value, str): + if not value: + return SizedInteger(0).setBitLength(0) + + elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated) + if value[-2:] == '\'B': + return self.fromBinaryString(value[1:-2], internalFormat=True) + elif value[-2:] == '\'H': + return self.fromHexString(value[1:-2], internalFormat=True) + else: + raise error.PyAsn1Error( + 'Bad BIT STRING value notation %s' % (value,) + ) + + elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active' + names = [x.strip() for x in value.split(',')] + + try: + + bitPositions = [self.namedValues[name] for name in names] + + except KeyError: + raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,)) + + rightmostPosition = max(bitPositions) + + number = 0 + for bitPosition in bitPositions: + number |= 1 << (rightmostPosition - bitPosition) + + return SizedInteger(number).setBitLength(rightmostPosition + 1) + + elif value.startswith('0x'): + return self.fromHexString(value[2:], internalFormat=True) + + elif value.startswith('0b'): + return self.fromBinaryString(value[2:], internalFormat=True) + + else: # assume plain binary string like '1011' + return self.fromBinaryString(value, internalFormat=True) + + elif isinstance(value, (tuple, list)): + return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True) + + elif isinstance(value, BitString): + return SizedInteger(value).setBitLength(len(value)) + + elif isinstance(value, int): + return SizedInteger(value) + + else: + raise error.PyAsn1Error( + 'Bad BitString initializer type \'%s\'' % (value,) + ) + + +class OctetString(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type :class:`bytes`. + When used in Unicode context, |ASN.1| type + assumes "|encoding|" serialisation. + + Keyword Args + ------------ + value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object + :class:`bytes`, alternatively :class:`str` + representing character string to be serialised into octets + (note `encoding` parameter) or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + encoding: :py:class:`str` + Unicode codec ID to encode/decode + :class:`str` the payload when |ASN.1| object is used + in text string context. + + binValue: :py:class:`str` + Binary string initializer to use instead of the *value*. + Example: '10110011'. + + hexValue: :py:class:`str` + Hexadecimal string initializer to use instead of the *value*. + Example: 'DEADBEEF'. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class Icon(OctetString): + ''' + ASN.1 specification: + + Icon ::= OCTET STRING + + icon1 Icon ::= '001100010011001000110011'B + icon2 Icon ::= '313233'H + ''' + icon1 = Icon.fromBinaryString('001100010011001000110011') + icon2 = Icon.fromHexString('313233') + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + defaultBinValue = defaultHexValue = noValue + encoding = 'iso-8859-1' + + def __init__(self, value=noValue, **kwargs): + if kwargs: + if value is noValue: + try: + value = self.fromBinaryString(kwargs.pop('binValue')) + + except KeyError: + pass + + try: + value = self.fromHexString(kwargs.pop('hexValue')) + + except KeyError: + pass + + if value is noValue: + if self.defaultBinValue is not noValue: + value = self.fromBinaryString(self.defaultBinValue) + + elif self.defaultHexValue is not noValue: + value = self.fromHexString(self.defaultHexValue) + + if 'encoding' not in kwargs: + kwargs['encoding'] = self.encoding + + base.SimpleAsn1Type.__init__(self, value, **kwargs) + + def prettyIn(self, value): + if isinstance(value, bytes): + return value + + elif isinstance(value, str): + try: + return value.encode(self.encoding) + + except UnicodeEncodeError as exc: + raise error.PyAsn1UnicodeEncodeError( + "Can't encode string '%s' with '%s' " + "codec" % (value, self.encoding), exc + ) + elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way + return value.asOctets() + + elif isinstance(value, base.SimpleAsn1Type): # this mostly targets Integer objects + return self.prettyIn(str(value)) + + elif isinstance(value, (tuple, list)): + return self.prettyIn(bytes(value)) + + else: + return bytes(value) + + def __str__(self): + try: + return self._value.decode(self.encoding) + + except UnicodeDecodeError as exc: + raise error.PyAsn1UnicodeDecodeError( + "Can't decode string '%s' with '%s' codec at " + "'%s'" % (self._value, self.encoding, + self.__class__.__name__), exc + ) + + def __bytes__(self): + return bytes(self._value) + + def asOctets(self): + return bytes(self._value) + + def asNumbers(self): + return tuple(self._value) + + # + # Normally, `.prettyPrint()` is called from `__str__()`. Historically, + # OctetString.prettyPrint() used to return hexified payload + # representation in cases when non-printable content is present. At the + # same time `str()` used to produce either octet-stream (Py2) or + # text (Py3) representations. + # + # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is + # reversed to preserve the original behaviour. + # + # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness + # and end up with just `__str__()` producing hexified representation while + # both text and octet-stream representation should only be requested via + # the `.asOctets()` method. + # + # Note: ASN.1 OCTET STRING is never mean to contain text! + # + + def prettyOut(self, value): + return value + + def prettyPrint(self, scope=0): + # first see if subclass has its own .prettyOut() + value = self.prettyOut(self._value) + + if value is not self._value: + return value + + numbers = self.asNumbers() + + for x in numbers: + # hexify if needed + if x < 32 or x > 126: + return '0x' + ''.join(('%.2x' % x for x in numbers)) + else: + # this prevents infinite recursion + return OctetString.__str__(self) + + @staticmethod + def fromBinaryString(value): + """Create a |ASN.1| object initialized from a string of '0' and '1'. + + Parameters + ---------- + value: :class:`str` + Text string like '1010111' + """ + bitNo = 8 + byte = 0 + r = [] + for v in value: + if bitNo: + bitNo -= 1 + else: + bitNo = 7 + r.append(byte) + byte = 0 + if v in ('0', '1'): + v = int(v) + else: + raise error.PyAsn1Error( + 'Non-binary OCTET STRING initializer %s' % (v,) + ) + byte |= v << bitNo + + r.append(byte) + + return bytes(r) + + @staticmethod + def fromHexString(value): + """Create a |ASN.1| object initialized from the hex string. + + Parameters + ---------- + value: :class:`str` + Text string like 'DEADBEEF' + """ + r = [] + p = [] + for v in value: + if p: + r.append(int(p + v, 16)) + p = None + else: + p = v + if p: + r.append(int(p + '0', 16)) + + return bytes(r) + + # Immutable sequence object protocol + + def __len__(self): + return len(self._value) + + def __getitem__(self, i): + if i.__class__ is slice: + return self.clone(self._value[i]) + else: + return self._value[i] + + def __iter__(self): + return iter(self._value) + + def __contains__(self, value): + return value in self._value + + def __add__(self, value): + return self.clone(self._value + self.prettyIn(value)) + + def __radd__(self, value): + return self.clone(self.prettyIn(value) + self._value) + + def __mul__(self, value): + return self.clone(self._value * value) + + def __rmul__(self, value): + return self * value + + def __int__(self): + return int(self._value) + + def __float__(self): + return float(self._value) + + def __reversed__(self): + return reversed(self._value) + + +class Null(OctetString): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`str` objects + (always empty). + + Keyword Args + ------------ + value: :class:`str` or |ASN.1| object + Python empty :class:`str` literal or any object that evaluates to :obj:`False` + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class Ack(Null): + ''' + ASN.1 specification: + + Ack ::= NULL + ''' + ack = Ack('') + """ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05) + ) + subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(b'') + + # Optimization for faster codec lookup + typeId = OctetString.getTypeId() + + def prettyIn(self, value): + if value: + return value + + return b'' + + +class ObjectIdentifier(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`tuple` objects + (tuple of non-negative integers). + + Keyword Args + ------------ + value: :class:`tuple`, :class:`str` or |ASN.1| object + Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class ID(ObjectIdentifier): + ''' + ASN.1 specification: + + ID ::= OBJECT IDENTIFIER + + id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) } + id-bp ID ::= { id-edims 11 } + ''' + id_edims = ID('2.6.7') + id_bp = id_edims + (11,) + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + def __add__(self, other): + return self.clone(self._value + other) + + def __radd__(self, other): + return self.clone(other + self._value) + + def asTuple(self): + return self._value + + # Sequence object protocol + + def __len__(self): + return len(self._value) + + def __getitem__(self, i): + if i.__class__ is slice: + return self.clone(self._value[i]) + else: + return self._value[i] + + def __iter__(self): + return iter(self._value) + + def __contains__(self, value): + return value in self._value + + def index(self, suboid): + return self._value.index(suboid) + + def isPrefixOf(self, other): + """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object. + + Parameters + ---------- + other: |ASN.1| object + |ASN.1| object + + Returns + ------- + : :class:`bool` + :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object + or :obj:`False` otherwise. + """ + l = len(self) + if l <= len(other): + if self._value[:l] == other[:l]: + return True + return False + + def prettyIn(self, value): + if isinstance(value, ObjectIdentifier): + return tuple(value) + elif isinstance(value, str): + if '-' in value: + raise error.PyAsn1Error( + # sys.exc_info in case prettyIn was called while handling an exception + 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) + ) + try: + return tuple([int(subOid) for subOid in value.split('.') if subOid]) + except ValueError as exc: + raise error.PyAsn1Error( + 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, exc) + ) + + try: + tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0]) + + except (ValueError, TypeError) as exc: + raise error.PyAsn1Error( + 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, exc) + ) + + if len(tupleOfInts) == len(value): + return tupleOfInts + + raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__)) + + def prettyOut(self, value): + return '.'.join([str(x) for x in value]) + + +class RelativeOID(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`tuple` objects + (tuple of non-negative integers). + Keyword Args + ------------ + value: :class:`tuple`, :class:`str` or |ASN.1| object + Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object. + If `value` is not given, schema object will be created. + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + Examples + -------- + .. code-block:: python + class RelOID(RelativeOID): + ''' + ASN.1 specification: + id-pad-null RELATIVE-OID ::= { 0 } + id-pad-once RELATIVE-OID ::= { 5 6 } + id-pad-twice RELATIVE-OID ::= { 5 6 7 } + ''' + id_pad_null = RelOID('0') + id_pad_once = RelOID('5.6') + id_pad_twice = id_pad_once + (7,) + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0d) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + def __add__(self, other): + return self.clone(self._value + other) + + def __radd__(self, other): + return self.clone(other + self._value) + + def asTuple(self): + return self._value + + # Sequence object protocol + + def __len__(self): + return len(self._value) + + def __getitem__(self, i): + if i.__class__ is slice: + return self.clone(self._value[i]) + else: + return self._value[i] + + def __iter__(self): + return iter(self._value) + + def __contains__(self, value): + return value in self._value + + def index(self, suboid): + return self._value.index(suboid) + + def isPrefixOf(self, other): + """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object. + Parameters + ---------- + other: |ASN.1| object + |ASN.1| object + Returns + ------- + : :class:`bool` + :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object + or :obj:`False` otherwise. + """ + l = len(self) + if l <= len(other): + if self._value[:l] == other[:l]: + return True + return False + + def prettyIn(self, value): + if isinstance(value, RelativeOID): + return tuple(value) + elif isinstance(value, str): + if '-' in value: + raise error.PyAsn1Error( + # sys.exc_info in case prettyIn was called while handling an exception + 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) + ) + try: + return tuple([int(subOid) for subOid in value.split('.') if subOid]) + except ValueError as exc: + raise error.PyAsn1Error( + 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, exc) + ) + + try: + tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0]) + + except (ValueError, TypeError) as exc: + raise error.PyAsn1Error( + 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, exc) + ) + + if len(tupleOfInts) == len(value): + return tupleOfInts + + raise error.PyAsn1Error('Malformed RELATIVE-OID %s at %s' % (value, self.__class__.__name__)) + + def prettyOut(self, value): + return '.'.join([str(x) for x in value]) + + +class Real(base.SimpleAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`float` objects. + Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its + elements are mantissa, base and exponent. + + Keyword Args + ------------ + value: :class:`tuple`, :class:`float` or |ASN.1| object + Python sequence of :class:`int` (representing mantissa, base and + exponent) or :class:`float` instance or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class Pi(Real): + ''' + ASN.1 specification: + + Pi ::= REAL + + pi Pi ::= { mantissa 314159, base 10, exponent -5 } + + ''' + pi = Pi((314159, 10, -5)) + """ + binEncBase = None # binEncBase = 16 is recommended for large numbers + + try: + _plusInf = float('inf') + _minusInf = float('-inf') + _inf = _plusInf, _minusInf + + except ValueError: + # Infinity support is platform and Python dependent + _plusInf = _minusInf = None + _inf = () + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Optimization for faster codec lookup + typeId = base.SimpleAsn1Type.getTypeId() + + @staticmethod + def __normalizeBase10(value): + m, b, e = value + while m and m % 10 == 0: + m //= 10 + e += 1 + return m, b, e + + def prettyIn(self, value): + if isinstance(value, tuple) and len(value) == 3: + if (not isinstance(value[0], (int, float)) or + not isinstance(value[1], int) or + not isinstance(value[2], int)): + raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,)) + if (isinstance(value[0], float) and + self._inf and value[0] in self._inf): + return value[0] + if value[1] not in (2, 10): + raise error.PyAsn1Error( + 'Prohibited base for Real value: %s' % (value[1],) + ) + if value[1] == 10: + value = self.__normalizeBase10(value) + return value + elif isinstance(value, int): + return self.__normalizeBase10((value, 10, 0)) + elif isinstance(value, float) or isinstance(value, str): + if isinstance(value, str): + try: + value = float(value) + except ValueError: + raise error.PyAsn1Error( + 'Bad real value syntax: %s' % (value,) + ) + if self._inf and value in self._inf: + return value + else: + e = 0 + while int(value) != value: + value *= 10 + e -= 1 + return self.__normalizeBase10((int(value), 10, e)) + elif isinstance(value, Real): + return tuple(value) + raise error.PyAsn1Error( + 'Bad real value syntax: %s' % (value,) + ) + + def prettyPrint(self, scope=0): + try: + return self.prettyOut(float(self)) + + except OverflowError: + return '' + + @property + def isPlusInf(self): + """Indicate PLUS-INFINITY object value + + Returns + ------- + : :class:`bool` + :obj:`True` if calling object represents plus infinity + or :obj:`False` otherwise. + + """ + return self._value == self._plusInf + + @property + def isMinusInf(self): + """Indicate MINUS-INFINITY object value + + Returns + ------- + : :class:`bool` + :obj:`True` if calling object represents minus infinity + or :obj:`False` otherwise. + """ + return self._value == self._minusInf + + @property + def isInf(self): + return self._value in self._inf + + def __add__(self, value): + return self.clone(float(self) + value) + + def __radd__(self, value): + return self + value + + def __mul__(self, value): + return self.clone(float(self) * value) + + def __rmul__(self, value): + return self * value + + def __sub__(self, value): + return self.clone(float(self) - value) + + def __rsub__(self, value): + return self.clone(value - float(self)) + + def __mod__(self, value): + return self.clone(float(self) % value) + + def __rmod__(self, value): + return self.clone(value % float(self)) + + def __pow__(self, value, modulo=None): + return self.clone(pow(float(self), value, modulo)) + + def __rpow__(self, value): + return self.clone(pow(value, float(self))) + + def __truediv__(self, value): + return self.clone(float(self) / value) + + def __rtruediv__(self, value): + return self.clone(value / float(self)) + + def __divmod__(self, value): + return self.clone(float(self) // value) + + def __rdivmod__(self, value): + return self.clone(value // float(self)) + + def __int__(self): + return int(float(self)) + + def __float__(self): + if self._value in self._inf: + return self._value + + mantissa, base, exponent = self._value + + if not mantissa: + return 0.0 + + if base == 2: + return math.ldexp(float(mantissa), exponent) + + # base is 10 (prettyIn() rejects everything else); refuse to + # materialize astronomically large integers via pow() + if exponent > sys.float_info.max_10_exp: + raise OverflowError('Real value too large to convert to float') + + return float(mantissa * pow(base, exponent)) + + def __abs__(self): + return self.clone(abs(float(self))) + + def __pos__(self): + return self.clone(+float(self)) + + def __neg__(self): + return self.clone(-float(self)) + + def __round__(self, n=0): + r = round(float(self), n) + if n: + return self.clone(r) + else: + return r + + def __floor__(self): + return self.clone(math.floor(float(self))) + + def __ceil__(self): + return self.clone(math.ceil(float(self))) + + def __trunc__(self): + return self.clone(math.trunc(float(self))) + + def __lt__(self, value): + return float(self) < value + + def __le__(self, value): + return float(self) <= value + + def __eq__(self, value): + return float(self) == value + + def __ne__(self, value): + return float(self) != value + + def __gt__(self, value): + return float(self) > value + + def __ge__(self, value): + return float(self) >= value + + def __bool__(self): + return bool(float(self)) + + __hash__ = base.SimpleAsn1Type.__hash__ + + def __getitem__(self, idx): + if self._value in self._inf: + raise error.PyAsn1Error('Invalid infinite value operation') + else: + return self._value[idx] + + # compatibility stubs + + def isPlusInfinity(self): + return self.isPlusInf + + def isMinusInfinity(self): + return self.isMinusInf + + def isInfinity(self): + return self.isInf + + +class Enumerated(Integer): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its + objects are immutable and duck-type Python :class:`int` objects. + + Keyword Args + ------------ + value: :class:`int`, :class:`str` or |ASN.1| object + Python :class:`int` or :class:`str` literal or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` + Object representing non-default symbolic aliases for numbers + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + + .. code-block:: python + + class RadioButton(Enumerated): + ''' + ASN.1 specification: + + RadioButton ::= ENUMERATED { button1(0), button2(1), + button3(2) } + + selected-by-default RadioButton ::= button1 + ''' + namedValues = NamedValues( + ('button1', 0), ('button2', 1), + ('button3', 2) + ) + + selected_by_default = RadioButton('button1') + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Optimization for faster codec lookup + typeId = Integer.getTypeId() + + #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object + #: representing symbolic aliases for numbers + namedValues = namedval.NamedValues() + + +# "Structured" ASN.1 types + +class SequenceOfAndSetOfBase(base.ConstructedAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, + its objects are mutable and duck-type Python :class:`list` objects. + + Keyword Args + ------------ + componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A pyasn1 object representing ASN.1 type allowed within |ASN.1| type + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type can only occur on explicit + `.isInconsistent` call. + + Examples + -------- + + .. code-block:: python + + class LotteryDraw(SequenceOf): # SetOf is similar + ''' + ASN.1 specification: + + LotteryDraw ::= SEQUENCE OF INTEGER + ''' + componentType = Integer() + + lotteryDraw = LotteryDraw() + lotteryDraw.extend([123, 456, 789]) + """ + def __init__(self, *args, **kwargs): + # support positional params for backward compatibility + if args: + for key, value in zip(('componentType', 'tagSet', + 'subtypeSpec'), args): + if key in kwargs: + raise error.PyAsn1Error('Conflicting positional and keyword params!') + kwargs['componentType'] = value + + self._componentValues = noValue + + base.ConstructedAsn1Type.__init__(self, **kwargs) + + # Python list protocol + + def __getitem__(self, idx): + try: + return self.getComponentByPosition(idx) + + except error.PyAsn1Error as exc: + raise IndexError(exc) + + def __setitem__(self, idx, value): + try: + self.setComponentByPosition(idx, value) + + except error.PyAsn1Error as exc: + raise IndexError(exc) + + def append(self, value): + if self._componentValues is noValue: + pos = 0 + + else: + pos = len(self._componentValues) + + self[pos] = value + + def count(self, value): + return list(self._componentValues.values()).count(value) + + def extend(self, values): + for value in values: + self.append(value) + + if self._componentValues is noValue: + self._componentValues = {} + + def index(self, value, start=0, stop=None): + if stop is None: + stop = len(self) + + indices, values = zip(*self._componentValues.items()) + + # TODO: remove when Py2.5 support is gone + values = list(values) + + try: + return indices[values.index(value, start, stop)] + + except error.PyAsn1Error as exc: + raise ValueError(exc) + + def reverse(self): + self._componentValues.reverse() + + def sort(self, key=None, reverse=False): + self._componentValues = dict( + enumerate(sorted(self._componentValues.values(), + key=key, reverse=reverse))) + + def __len__(self): + if self._componentValues is noValue or not self._componentValues: + return 0 + + return max(self._componentValues) + 1 + + def __iter__(self): + for idx in range(0, len(self)): + yield self.getComponentByPosition(idx) + + def _cloneComponentValues(self, myClone, cloneValueFlag): + for idx, componentValue in self._componentValues.items(): + if componentValue is not noValue: + if isinstance(componentValue, base.ConstructedAsn1Type): + myClone.setComponentByPosition( + idx, componentValue.clone(cloneValueFlag=cloneValueFlag) + ) + else: + myClone.setComponentByPosition(idx, componentValue.clone()) + + def getComponentByPosition(self, idx, default=noValue, instantiate=True): + """Return |ASN.1| type component value by position. + + Equivalent to Python sequence subscription operation (e.g. `[]`). + + Parameters + ---------- + idx : :class:`int` + Component index (zero-based). Must either refer to an existing + component or to N+1 component (if *componentType* is set). In the latter + case a new component type gets instantiated and appended to the |ASN.1| + sequence. + + Keyword Args + ------------ + default: :class:`object` + If set and requested component is a schema object, return the `default` + object instead of the requested component. + + instantiate: :class:`bool` + If :obj:`True` (default), inner component will be automatically instantiated. + If :obj:`False` either existing component or the :class:`NoValue` object will be + returned. + + Returns + ------- + : :py:class:`~pyasn1.type.base.PyAsn1Item` + Instantiate |ASN.1| component type or return existing component value + + Examples + -------- + + .. code-block:: python + + # can also be SetOf + class MySequenceOf(SequenceOf): + componentType = OctetString() + + s = MySequenceOf() + + # returns component #0 with `.isValue` property False + s.getComponentByPosition(0) + + # returns None + s.getComponentByPosition(0, default=None) + + s.clear() + + # returns noValue + s.getComponentByPosition(0, instantiate=False) + + # sets component #0 to OctetString() ASN.1 schema + # object and returns it + s.getComponentByPosition(0, instantiate=True) + + # sets component #0 to ASN.1 value object + s.setComponentByPosition(0, 'ABCD') + + # returns OctetString('ABCD') value object + s.getComponentByPosition(0, instantiate=False) + + s.clear() + + # returns noValue + s.getComponentByPosition(0, instantiate=False) + """ + if isinstance(idx, slice): + indices = tuple(range(len(self))) + return [self.getComponentByPosition(subidx, default, instantiate) + for subidx in indices[idx]] + + if idx < 0: + idx = len(self) + idx + if idx < 0: + raise error.PyAsn1Error( + 'SequenceOf/SetOf index is out of range') + + try: + componentValue = self._componentValues[idx] + + except (KeyError, error.PyAsn1Error): + if not instantiate: + return default + + self.setComponentByPosition(idx) + + componentValue = self._componentValues[idx] + + if default is noValue or componentValue.isValue: + return componentValue + else: + return default + + def setComponentByPosition(self, idx, value=noValue, + verifyConstraints=True, + matchTags=True, + matchConstraints=True): + """Assign |ASN.1| type component by position. + + Equivalent to Python sequence item assignment operation (e.g. `[]`) + or list.append() (when idx == len(self)). + + Parameters + ---------- + idx: :class:`int` + Component index (zero-based). Must either refer to existing + component or to N+1 component. In the latter case a new component + type gets instantiated (if *componentType* is set, or given ASN.1 + object is taken otherwise) and appended to the |ASN.1| sequence. + + Keyword Args + ------------ + value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A Python value to initialize |ASN.1| component with (if *componentType* is set) + or ASN.1 value object to assign to |ASN.1| component. + If `value` is not given, schema object will be set as a component. + + verifyConstraints: :class:`bool` + If :obj:`False`, skip constraints validation + + matchTags: :class:`bool` + If :obj:`False`, skip component tags matching + + matchConstraints: :class:`bool` + If :obj:`False`, skip component constraints matching + + Returns + ------- + self + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer + IndexError + When idx > len(self) + """ + if isinstance(idx, slice): + indices = tuple(range(len(self))) + startIdx = indices and indices[idx][0] or 0 + for subIdx, subValue in enumerate(value): + self.setComponentByPosition( + startIdx + subIdx, subValue, verifyConstraints, + matchTags, matchConstraints) + return self + + if idx < 0: + idx = len(self) + idx + if idx < 0: + raise error.PyAsn1Error( + 'SequenceOf/SetOf index is out of range') + + componentType = self.componentType + + if self._componentValues is noValue: + componentValues = {} + + else: + componentValues = self._componentValues + + currentValue = componentValues.get(idx, noValue) + + if value is noValue: + if componentType is not None: + value = componentType.clone() + + elif currentValue is noValue: + raise error.PyAsn1Error('Component type not defined') + + elif not isinstance(value, base.Asn1Item): + if (componentType is not None and + isinstance(componentType, base.SimpleAsn1Type)): + value = componentType.clone(value=value) + + elif (currentValue is not noValue and + isinstance(currentValue, base.SimpleAsn1Type)): + value = currentValue.clone(value=value) + + else: + raise error.PyAsn1Error( + 'Non-ASN.1 value %r and undefined component' + ' type at %r' % (value, self)) + + elif componentType is not None and (matchTags or matchConstraints): + subtypeChecker = ( + self.strictConstraints and + componentType.isSameTypeWith or + componentType.isSuperTypeOf) + + if not subtypeChecker(value, verifyConstraints and matchTags, + verifyConstraints and matchConstraints): + # TODO: we should wrap componentType with UnnamedType to carry + # additional properties associated with componentType + if componentType.typeId != Any.typeId: + raise error.PyAsn1Error( + 'Component value is tag-incompatible: %r vs ' + '%r' % (value, componentType)) + + componentValues[idx] = value + + self._componentValues = componentValues + + return self + + @property + def componentTagMap(self): + if self.componentType is not None: + return self.componentType.tagMap + + @property + def components(self): + return [self._componentValues[idx] + for idx in sorted(self._componentValues)] + + def clear(self): + """Remove all components and become an empty |ASN.1| value object. + + Has the same effect on |ASN.1| object as it does on :class:`list` + built-in. + """ + self._componentValues = {} + return self + + def reset(self): + """Remove all components and become a |ASN.1| schema object. + + See :meth:`isValue` property for more information on the + distinction between value and schema objects. + """ + self._componentValues = noValue + return self + + def prettyPrint(self, scope=0): + scope += 1 + representation = self.__class__.__name__ + ':\n' + + if not self.isValue: + return representation + + for idx, componentValue in enumerate(self): + representation += ' ' * scope + if (componentValue is noValue and + self.componentType is not None): + representation += '' + else: + representation += componentValue.prettyPrint(scope) + + return representation + + def prettyPrintType(self, scope=0): + scope += 1 + representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) + if self.componentType is not None: + representation += ' ' * scope + representation += self.componentType.prettyPrintType(scope) + return representation + '\n' + ' ' * (scope - 1) + '}' + + + @property + def isValue(self): + """Indicate that |ASN.1| object represents ASN.1 value. + + If *isValue* is :obj:`False` then this object represents just ASN.1 schema. + + If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, + this object can also be used like a Python built-in object + (e.g. :class:`int`, :class:`str`, :class:`dict` etc.). + + Returns + ------- + : :class:`bool` + :obj:`False` if object represents just ASN.1 schema. + :obj:`True` if object represents ASN.1 schema and can be used as a normal value. + + Note + ---- + There is an important distinction between PyASN1 schema and value objects. + The PyASN1 schema objects can only participate in ASN.1 schema-related + operations (e.g. defining or testing the structure of the data). Most + obvious uses of ASN.1 schema is to guide serialisation codecs whilst + encoding/decoding serialised ASN.1 contents. + + The PyASN1 value objects can **additionally** participate in many operations + involving regular Python objects (e.g. arithmetic, comprehension etc). + """ + if self._componentValues is noValue: + return False + + if len(self._componentValues) != len(self): + return False + + for componentValue in self._componentValues.values(): + if componentValue is noValue or not componentValue.isValue: + return False + + return True + + @property + def isInconsistent(self): + """Run necessary checks to ensure |ASN.1| object consistency. + + Default action is to verify |ASN.1| object against constraints imposed + by `subtypeSpec`. + + Raises + ------ + :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found + """ + if self.componentType is noValue or not self.subtypeSpec: + return False + + if self._componentValues is noValue: + return True + + mapping = {} + + for idx, value in self._componentValues.items(): + # Absent fields are not in the mapping + if value is noValue: + continue + + mapping[idx] = value + + try: + # Represent SequenceOf/SetOf as a bare dict to constraints chain + self.subtypeSpec(mapping) + + except error.PyAsn1Error as exc: + return exc + + return False + +class SequenceOf(SequenceOfAndSetOfBase): + __doc__ = SequenceOfAndSetOfBase.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) + ) + + #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + #: object representing ASN.1 type allowed within |ASN.1| type + componentType = None + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Disambiguation ASN.1 types identification + typeId = SequenceOfAndSetOfBase.getTypeId() + + +class SetOf(SequenceOfAndSetOfBase): + __doc__ = SequenceOfAndSetOfBase.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) + ) + + #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + #: object representing ASN.1 type allowed within |ASN.1| type + componentType = None + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Disambiguation ASN.1 types identification + typeId = SequenceOfAndSetOfBase.getTypeId() + + +class SequenceAndSetBase(base.ConstructedAsn1Type): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, + its objects are mutable and duck-type Python :class:`dict` objects. + + Keyword Args + ------------ + componentType: :py:class:`~pyasn1.type.namedtype.NamedType` + Object holding named ASN.1 types allowed within this collection + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type can only occur on explicit + `.isInconsistent` call. + + Examples + -------- + + .. code-block:: python + + class Description(Sequence): # Set is similar + ''' + ASN.1 specification: + + Description ::= SEQUENCE { + surname IA5String, + first-name IA5String OPTIONAL, + age INTEGER DEFAULT 40 + } + ''' + componentType = NamedTypes( + NamedType('surname', IA5String()), + OptionalNamedType('first-name', IA5String()), + DefaultedNamedType('age', Integer(40)) + ) + + descr = Description() + descr['surname'] = 'Smith' + descr['first-name'] = 'John' + """ + #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes` + #: object representing named ASN.1 types allowed within |ASN.1| type + componentType = namedtype.NamedTypes() + + + class DynamicNames(object): + """Fields names/positions mapping for component-less objects""" + def __init__(self): + self._keyToIdxMap = {} + self._idxToKeyMap = {} + + def __len__(self): + return len(self._keyToIdxMap) + + def __contains__(self, item): + return item in self._keyToIdxMap or item in self._idxToKeyMap + + def __iter__(self): + return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap))) + + def __getitem__(self, item): + try: + return self._keyToIdxMap[item] + + except KeyError: + return self._idxToKeyMap[item] + + def getNameByPosition(self, idx): + try: + return self._idxToKeyMap[idx] + + except KeyError: + raise error.PyAsn1Error('Type position out of range') + + def getPositionByName(self, name): + try: + return self._keyToIdxMap[name] + + except KeyError: + raise error.PyAsn1Error('Name %s not found' % (name,)) + + def addField(self, idx): + self._keyToIdxMap['field-%d' % idx] = idx + self._idxToKeyMap[idx] = 'field-%d' % idx + + + def __init__(self, **kwargs): + base.ConstructedAsn1Type.__init__(self, **kwargs) + self._componentTypeLen = len(self.componentType) + if self._componentTypeLen: + self._componentValues = [] + else: + self._componentValues = noValue + self._dynamicNames = self._componentTypeLen or self.DynamicNames() + + def __getitem__(self, idx): + if isinstance(idx, str): + try: + return self.getComponentByName(idx) + + except error.PyAsn1Error as exc: + # duck-typing dict + raise KeyError(exc) + + else: + try: + return self.getComponentByPosition(idx) + + except error.PyAsn1Error as exc: + # duck-typing list + raise IndexError(exc) + + def __setitem__(self, idx, value): + if isinstance(idx, str): + try: + self.setComponentByName(idx, value) + + except error.PyAsn1Error as exc: + # duck-typing dict + raise KeyError(exc) + + else: + try: + self.setComponentByPosition(idx, value) + + except error.PyAsn1Error as exc: + # duck-typing list + raise IndexError(exc) + + def __contains__(self, key): + if self._componentTypeLen: + return key in self.componentType + else: + return key in self._dynamicNames + + def __len__(self): + return len(self._componentValues) + + def __iter__(self): + return iter(self.componentType or self._dynamicNames) + + # Python dict protocol + + def values(self): + for idx in range(self._componentTypeLen or len(self._dynamicNames)): + yield self[idx] + + def keys(self): + return iter(self) + + def items(self): + for idx in range(self._componentTypeLen or len(self._dynamicNames)): + if self._componentTypeLen: + yield self.componentType[idx].name, self[idx] + else: + yield self._dynamicNames[idx], self[idx] + + def update(self, *iterValue, **mappingValue): + for k, v in iterValue: + self[k] = v + for k in mappingValue: + self[k] = mappingValue[k] + + def clear(self): + """Remove all components and become an empty |ASN.1| value object. + + Has the same effect on |ASN.1| object as it does on :class:`dict` + built-in. + """ + self._componentValues = [] + self._dynamicNames = self.DynamicNames() + return self + + def reset(self): + """Remove all components and become a |ASN.1| schema object. + + See :meth:`isValue` property for more information on the + distinction between value and schema objects. + """ + self._componentValues = noValue + self._dynamicNames = self.DynamicNames() + return self + + @property + def components(self): + return self._componentValues + + def _cloneComponentValues(self, myClone, cloneValueFlag): + if self._componentValues is noValue: + return + + for idx, componentValue in enumerate(self._componentValues): + if componentValue is not noValue: + if isinstance(componentValue, base.ConstructedAsn1Type): + myClone.setComponentByPosition( + idx, componentValue.clone(cloneValueFlag=cloneValueFlag) + ) + else: + myClone.setComponentByPosition(idx, componentValue.clone()) + + def getComponentByName(self, name, default=noValue, instantiate=True): + """Returns |ASN.1| type component by name. + + Equivalent to Python :class:`dict` subscription operation (e.g. `[]`). + + Parameters + ---------- + name: :class:`str` + |ASN.1| type component name + + Keyword Args + ------------ + default: :class:`object` + If set and requested component is a schema object, return the `default` + object instead of the requested component. + + instantiate: :class:`bool` + If :obj:`True` (default), inner component will be automatically + instantiated. + If :obj:`False` either existing component or the :class:`NoValue` + object will be returned. + + Returns + ------- + : :py:class:`~pyasn1.type.base.PyAsn1Item` + Instantiate |ASN.1| component type or return existing + component value + """ + if self._componentTypeLen: + idx = self.componentType.getPositionByName(name) + else: + try: + idx = self._dynamicNames.getPositionByName(name) + + except KeyError: + raise error.PyAsn1Error('Name %s not found' % (name,)) + + return self.getComponentByPosition(idx, default=default, instantiate=instantiate) + + def setComponentByName(self, name, value=noValue, + verifyConstraints=True, + matchTags=True, + matchConstraints=True): + """Assign |ASN.1| type component by name. + + Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`). + + Parameters + ---------- + name: :class:`str` + |ASN.1| type component name + + Keyword Args + ------------ + value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A Python value to initialize |ASN.1| component with (if *componentType* is set) + or ASN.1 value object to assign to |ASN.1| component. + If `value` is not given, schema object will be set as a component. + + verifyConstraints: :class:`bool` + If :obj:`False`, skip constraints validation + + matchTags: :class:`bool` + If :obj:`False`, skip component tags matching + + matchConstraints: :class:`bool` + If :obj:`False`, skip component constraints matching + + Returns + ------- + self + """ + if self._componentTypeLen: + idx = self.componentType.getPositionByName(name) + else: + try: + idx = self._dynamicNames.getPositionByName(name) + + except KeyError: + raise error.PyAsn1Error('Name %s not found' % (name,)) + + return self.setComponentByPosition( + idx, value, verifyConstraints, matchTags, matchConstraints + ) + + def getComponentByPosition(self, idx, default=noValue, instantiate=True): + """Returns |ASN.1| type component by index. + + Equivalent to Python sequence subscription operation (e.g. `[]`). + + Parameters + ---------- + idx: :class:`int` + Component index (zero-based). Must either refer to an existing + component or (if *componentType* is set) new ASN.1 schema object gets + instantiated. + + Keyword Args + ------------ + default: :class:`object` + If set and requested component is a schema object, return the `default` + object instead of the requested component. + + instantiate: :class:`bool` + If :obj:`True` (default), inner component will be automatically + instantiated. + If :obj:`False` either existing component or the :class:`NoValue` + object will be returned. + + Returns + ------- + : :py:class:`~pyasn1.type.base.PyAsn1Item` + a PyASN1 object + + Examples + -------- + + .. code-block:: python + + # can also be Set + class MySequence(Sequence): + componentType = NamedTypes( + NamedType('id', OctetString()) + ) + + s = MySequence() + + # returns component #0 with `.isValue` property False + s.getComponentByPosition(0) + + # returns None + s.getComponentByPosition(0, default=None) + + s.clear() + + # returns noValue + s.getComponentByPosition(0, instantiate=False) + + # sets component #0 to OctetString() ASN.1 schema + # object and returns it + s.getComponentByPosition(0, instantiate=True) + + # sets component #0 to ASN.1 value object + s.setComponentByPosition(0, 'ABCD') + + # returns OctetString('ABCD') value object + s.getComponentByPosition(0, instantiate=False) + + s.clear() + + # returns noValue + s.getComponentByPosition(0, instantiate=False) + """ + try: + if self._componentValues is noValue: + componentValue = noValue + + else: + componentValue = self._componentValues[idx] + + except IndexError: + componentValue = noValue + + if not instantiate: + if componentValue is noValue or not componentValue.isValue: + return default + else: + return componentValue + + if componentValue is noValue: + self.setComponentByPosition(idx) + + componentValue = self._componentValues[idx] + + if default is noValue or componentValue.isValue: + return componentValue + else: + return default + + def setComponentByPosition(self, idx, value=noValue, + verifyConstraints=True, + matchTags=True, + matchConstraints=True): + """Assign |ASN.1| type component by position. + + Equivalent to Python sequence item assignment operation (e.g. `[]`). + + Parameters + ---------- + idx : :class:`int` + Component index (zero-based). Must either refer to existing + component (if *componentType* is set) or to N+1 component + otherwise. In the latter case a new component of given ASN.1 + type gets instantiated and appended to |ASN.1| sequence. + + Keyword Args + ------------ + value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A Python value to initialize |ASN.1| component with (if *componentType* is set) + or ASN.1 value object to assign to |ASN.1| component. + If `value` is not given, schema object will be set as a component. + + verifyConstraints : :class:`bool` + If :obj:`False`, skip constraints validation + + matchTags: :class:`bool` + If :obj:`False`, skip component tags matching + + matchConstraints: :class:`bool` + If :obj:`False`, skip component constraints matching + + Returns + ------- + self + """ + componentType = self.componentType + componentTypeLen = self._componentTypeLen + + if self._componentValues is noValue: + componentValues = [] + + else: + componentValues = self._componentValues + + try: + currentValue = componentValues[idx] + + except IndexError: + currentValue = noValue + if componentTypeLen: + if componentTypeLen < idx: + raise error.PyAsn1Error('component index out of range') + + componentValues = [noValue] * componentTypeLen + + if value is noValue: + if componentTypeLen: + value = componentType.getTypeByPosition(idx) + if isinstance(value, base.ConstructedAsn1Type): + value = value.clone(cloneValueFlag=componentType[idx].isDefaulted) + + elif currentValue is noValue: + raise error.PyAsn1Error('Component type not defined') + + elif not isinstance(value, base.Asn1Item): + if componentTypeLen: + subComponentType = componentType.getTypeByPosition(idx) + if isinstance(subComponentType, base.SimpleAsn1Type): + value = subComponentType.clone(value=value) + + else: + raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__) + + elif currentValue is not noValue and isinstance(currentValue, base.SimpleAsn1Type): + value = currentValue.clone(value=value) + + else: + raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__) + + elif ((verifyConstraints or matchTags or matchConstraints) and + componentTypeLen): + subComponentType = componentType.getTypeByPosition(idx) + if subComponentType is not noValue: + subtypeChecker = (self.strictConstraints and + subComponentType.isSameTypeWith or + subComponentType.isSuperTypeOf) + + if not subtypeChecker(value, verifyConstraints and matchTags, + verifyConstraints and matchConstraints): + if not componentType[idx].openType: + raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) + + if componentTypeLen or idx in self._dynamicNames: + componentValues[idx] = value + + elif len(componentValues) == idx: + componentValues.append(value) + self._dynamicNames.addField(idx) + + else: + raise error.PyAsn1Error('Component index out of range') + + self._componentValues = componentValues + + return self + + @property + def isValue(self): + """Indicate that |ASN.1| object represents ASN.1 value. + + If *isValue* is :obj:`False` then this object represents just ASN.1 schema. + + If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, + this object can also be used like a Python built-in object (e.g. + :class:`int`, :class:`str`, :class:`dict` etc.). + + Returns + ------- + : :class:`bool` + :obj:`False` if object represents just ASN.1 schema. + :obj:`True` if object represents ASN.1 schema and can be used as a + normal value. + + Note + ---- + There is an important distinction between PyASN1 schema and value objects. + The PyASN1 schema objects can only participate in ASN.1 schema-related + operations (e.g. defining or testing the structure of the data). Most + obvious uses of ASN.1 schema is to guide serialisation codecs whilst + encoding/decoding serialised ASN.1 contents. + + The PyASN1 value objects can **additionally** participate in many operations + involving regular Python objects (e.g. arithmetic, comprehension etc). + + It is sufficient for |ASN.1| objects to have all non-optional and non-defaulted + components being value objects to be considered as a value objects as a whole. + In other words, even having one or more optional components not turned into + value objects, |ASN.1| object is still considered as a value object. Defaulted + components are normally value objects by default. + """ + if self._componentValues is noValue: + return False + + componentType = self.componentType + + if componentType: + for idx, subComponentType in enumerate(componentType.namedTypes): + if subComponentType.isDefaulted or subComponentType.isOptional: + continue + + if not self._componentValues: + return False + + componentValue = self._componentValues[idx] + if componentValue is noValue or not componentValue.isValue: + return False + + else: + for componentValue in self._componentValues: + if componentValue is noValue or not componentValue.isValue: + return False + + return True + + @property + def isInconsistent(self): + """Run necessary checks to ensure |ASN.1| object consistency. + + Default action is to verify |ASN.1| object against constraints imposed + by `subtypeSpec`. + + Raises + ------ + :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found + """ + if self.componentType is noValue or not self.subtypeSpec: + return False + + if self._componentValues is noValue: + return True + + mapping = {} + + for idx, value in enumerate(self._componentValues): + # Absent fields are not in the mapping + if value is noValue: + continue + + name = self.componentType.getNameByPosition(idx) + + mapping[name] = value + + try: + # Represent Sequence/Set as a bare dict to constraints chain + self.subtypeSpec(mapping) + + except error.PyAsn1Error as exc: + return exc + + return False + + def prettyPrint(self, scope=0): + """Return an object representation string. + + Returns + ------- + : :class:`str` + Human-friendly object representation. + """ + scope += 1 + representation = self.__class__.__name__ + ':\n' + for idx, componentValue in enumerate(self._componentValues): + if componentValue is not noValue and componentValue.isValue: + representation += ' ' * scope + if self.componentType: + representation += self.componentType.getNameByPosition(idx) + else: + representation += self._dynamicNames.getNameByPosition(idx) + representation = '%s=%s\n' % ( + representation, componentValue.prettyPrint(scope) + ) + return representation + + def prettyPrintType(self, scope=0): + scope += 1 + representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) + for idx, componentType in enumerate(self.componentType.values() or self._componentValues): + representation += ' ' * scope + if self.componentType: + representation += '"%s"' % self.componentType.getNameByPosition(idx) + else: + representation += '"%s"' % self._dynamicNames.getNameByPosition(idx) + representation = '%s = %s\n' % ( + representation, componentType.prettyPrintType(scope) + ) + return representation + '\n' + ' ' * (scope - 1) + '}' + + # backward compatibility + + def setDefaultComponents(self): + return self + + def getComponentType(self): + if self._componentTypeLen: + return self.componentType + + def getNameByPosition(self, idx): + if self._componentTypeLen: + return self.componentType[idx].name + +class Sequence(SequenceAndSetBase): + __doc__ = SequenceAndSetBase.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) + ) + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) + #: object imposing size constraint on |ASN.1| objects + componentType = namedtype.NamedTypes() + + # Disambiguation ASN.1 types identification + typeId = SequenceAndSetBase.getTypeId() + + # backward compatibility + + def getComponentTagMapNearPosition(self, idx): + if self.componentType: + return self.componentType.getTagMapNearPosition(idx) + + def getComponentPositionNearType(self, tagSet, idx): + if self.componentType: + return self.componentType.getPositionNearType(tagSet, idx) + else: + return idx + + +class Set(SequenceAndSetBase): + __doc__ = SequenceAndSetBase.__doc__ + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) + ) + + #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) + #: object representing ASN.1 type allowed within |ASN.1| type + componentType = namedtype.NamedTypes() + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Disambiguation ASN.1 types identification + typeId = SequenceAndSetBase.getTypeId() + + def getComponent(self, innerFlag=False): + return self + + def getComponentByType(self, tagSet, default=noValue, + instantiate=True, innerFlag=False): + """Returns |ASN.1| type component by ASN.1 tag. + + Parameters + ---------- + tagSet : :py:class:`~pyasn1.type.tag.TagSet` + Object representing ASN.1 tags to identify one of + |ASN.1| object component + + Keyword Args + ------------ + default: :class:`object` + If set and requested component is a schema object, return the `default` + object instead of the requested component. + + instantiate: :class:`bool` + If :obj:`True` (default), inner component will be automatically + instantiated. + If :obj:`False` either existing component or the :class:`noValue` + object will be returned. + + Returns + ------- + : :py:class:`~pyasn1.type.base.PyAsn1Item` + a pyasn1 object + """ + componentValue = self.getComponentByPosition( + self.componentType.getPositionByType(tagSet), + default=default, instantiate=instantiate + ) + if innerFlag and isinstance(componentValue, Set): + # get inner component by inner tagSet + return componentValue.getComponent(innerFlag=True) + else: + # get outer component by inner tagSet + return componentValue + + def setComponentByType(self, tagSet, value=noValue, + verifyConstraints=True, + matchTags=True, + matchConstraints=True, + innerFlag=False): + """Assign |ASN.1| type component by ASN.1 tag. + + Parameters + ---------- + tagSet : :py:class:`~pyasn1.type.tag.TagSet` + Object representing ASN.1 tags to identify one of + |ASN.1| object component + + Keyword Args + ------------ + value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A Python value to initialize |ASN.1| component with (if *componentType* is set) + or ASN.1 value object to assign to |ASN.1| component. + If `value` is not given, schema object will be set as a component. + + verifyConstraints : :class:`bool` + If :obj:`False`, skip constraints validation + + matchTags: :class:`bool` + If :obj:`False`, skip component tags matching + + matchConstraints: :class:`bool` + If :obj:`False`, skip component constraints matching + + innerFlag: :class:`bool` + If :obj:`True`, search for matching *tagSet* recursively. + + Returns + ------- + self + """ + idx = self.componentType.getPositionByType(tagSet) + + if innerFlag: # set inner component by inner tagSet + componentType = self.componentType.getTypeByPosition(idx) + + if componentType.tagSet: + return self.setComponentByPosition( + idx, value, verifyConstraints, matchTags, matchConstraints + ) + else: + componentType = self.getComponentByPosition(idx) + return componentType.setComponentByType( + tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag + ) + else: # set outer component by inner tagSet + return self.setComponentByPosition( + idx, value, verifyConstraints, matchTags, matchConstraints + ) + + @property + def componentTagMap(self): + if self.componentType: + return self.componentType.tagMapUnique + + +class Choice(Set): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, + its objects are mutable and duck-type Python :class:`list` objects. + + Keyword Args + ------------ + componentType: :py:class:`~pyasn1.type.namedtype.NamedType` + Object holding named ASN.1 types allowed within this collection + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type can only occur on explicit + `.isInconsistent` call. + + Examples + -------- + + .. code-block:: python + + class Afters(Choice): + ''' + ASN.1 specification: + + Afters ::= CHOICE { + cheese [0] IA5String, + dessert [1] IA5String + } + ''' + componentType = NamedTypes( + NamedType('cheese', IA5String().subtype( + implicitTag=Tag(tagClassContext, tagFormatSimple, 0) + ), + NamedType('dessert', IA5String().subtype( + implicitTag=Tag(tagClassContext, tagFormatSimple, 1) + ) + ) + + afters = Afters() + afters['cheese'] = 'Mascarpone' + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.TagSet() # untagged + + #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) + #: object representing ASN.1 type allowed within |ASN.1| type + componentType = namedtype.NamedTypes() + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection( + constraint.ValueSizeConstraint(1, 1) + ) + + # Disambiguation ASN.1 types identification + typeId = Set.getTypeId() + + _currentIdx = None + + def __eq__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] == other + return NotImplemented + + def __ne__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] != other + return NotImplemented + + def __lt__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] < other + return NotImplemented + + def __le__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] <= other + return NotImplemented + + def __gt__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] > other + return NotImplemented + + def __ge__(self, other): + if self._componentValues: + return self._componentValues[self._currentIdx] >= other + return NotImplemented + + def __bool__(self): + return bool(self._componentValues) + + def __len__(self): + return self._currentIdx is not None and 1 or 0 + + def __contains__(self, key): + if self._currentIdx is None: + return False + return key == self.componentType[self._currentIdx].getName() + + def __iter__(self): + if self._currentIdx is None: + raise StopIteration + yield self.componentType[self._currentIdx].getName() + + # Python dict protocol + + def values(self): + if self._currentIdx is not None: + yield self._componentValues[self._currentIdx] + + def keys(self): + if self._currentIdx is not None: + yield self.componentType[self._currentIdx].getName() + + def items(self): + if self._currentIdx is not None: + yield self.componentType[self._currentIdx].getName(), self[self._currentIdx] + + def checkConsistency(self): + if self._currentIdx is None: + raise error.PyAsn1Error('Component not chosen') + + def _cloneComponentValues(self, myClone, cloneValueFlag): + try: + component = self.getComponent() + except error.PyAsn1Error: + pass + else: + if isinstance(component, Choice): + tagSet = component.effectiveTagSet + else: + tagSet = component.tagSet + if isinstance(component, base.ConstructedAsn1Type): + myClone.setComponentByType( + tagSet, component.clone(cloneValueFlag=cloneValueFlag) + ) + else: + myClone.setComponentByType(tagSet, component.clone()) + + def getComponentByPosition(self, idx, default=noValue, instantiate=True): + __doc__ = Set.__doc__ + + if self._currentIdx is None or self._currentIdx != idx: + return Set.getComponentByPosition(self, idx, default=default, + instantiate=instantiate) + + return self._componentValues[idx] + + def setComponentByPosition(self, idx, value=noValue, + verifyConstraints=True, + matchTags=True, + matchConstraints=True): + """Assign |ASN.1| type component by position. + + Equivalent to Python sequence item assignment operation (e.g. `[]`). + + Parameters + ---------- + idx: :class:`int` + Component index (zero-based). Must either refer to existing + component or to N+1 component. In the latter case a new component + type gets instantiated (if *componentType* is set, or given ASN.1 + object is taken otherwise) and appended to the |ASN.1| sequence. + + Keyword Args + ------------ + value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative + A Python value to initialize |ASN.1| component with (if *componentType* is set) + or ASN.1 value object to assign to |ASN.1| component. Once a new value is + set to *idx* component, previous value is dropped. + If `value` is not given, schema object will be set as a component. + + verifyConstraints : :class:`bool` + If :obj:`False`, skip constraints validation + + matchTags: :class:`bool` + If :obj:`False`, skip component tags matching + + matchConstraints: :class:`bool` + If :obj:`False`, skip component constraints matching + + Returns + ------- + self + """ + oldIdx = self._currentIdx + Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints) + self._currentIdx = idx + if oldIdx is not None and oldIdx != idx: + self._componentValues[oldIdx] = noValue + return self + + @property + def effectiveTagSet(self): + """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged).""" + if self.tagSet: + return self.tagSet + else: + component = self.getComponent() + return component.effectiveTagSet + + @property + def tagMap(self): + """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping + ASN.1 tags to ASN.1 objects contained within callee. + """ + if self.tagSet: + return Set.tagMap.fget(self) + else: + return self.componentType.tagMapUnique + + def getComponent(self, innerFlag=False): + """Return currently assigned component of the |ASN.1| object. + + Returns + ------- + : :py:class:`~pyasn1.type.base.PyAsn1Item` + a PyASN1 object + """ + if self._currentIdx is None: + raise error.PyAsn1Error('Component not chosen') + else: + c = self._componentValues[self._currentIdx] + if innerFlag and isinstance(c, Choice): + return c.getComponent(innerFlag) + else: + return c + + def getName(self, innerFlag=False): + """Return the name of currently assigned component of the |ASN.1| object. + + Returns + ------- + : :py:class:`str` + |ASN.1| component name + """ + if self._currentIdx is None: + raise error.PyAsn1Error('Component not chosen') + else: + if innerFlag: + c = self._componentValues[self._currentIdx] + if isinstance(c, Choice): + return c.getName(innerFlag) + return self.componentType.getNameByPosition(self._currentIdx) + + @property + def isValue(self): + """Indicate that |ASN.1| object represents ASN.1 value. + + If *isValue* is :obj:`False` then this object represents just ASN.1 schema. + + If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, + this object can also be used like a Python built-in object (e.g. + :class:`int`, :class:`str`, :class:`dict` etc.). + + Returns + ------- + : :class:`bool` + :obj:`False` if object represents just ASN.1 schema. + :obj:`True` if object represents ASN.1 schema and can be used as a normal + value. + + Note + ---- + There is an important distinction between PyASN1 schema and value objects. + The PyASN1 schema objects can only participate in ASN.1 schema-related + operations (e.g. defining or testing the structure of the data). Most + obvious uses of ASN.1 schema is to guide serialisation codecs whilst + encoding/decoding serialised ASN.1 contents. + + The PyASN1 value objects can **additionally** participate in many operations + involving regular Python objects (e.g. arithmetic, comprehension etc). + """ + if self._currentIdx is None: + return False + + componentValue = self._componentValues[self._currentIdx] + + return componentValue is not noValue and componentValue.isValue + + def clear(self): + self._currentIdx = None + return Set.clear(self) + + # compatibility stubs + + def getMinTagSet(self): + return self.minTagSet + + +class Any(OctetString): + """Create |ASN.1| schema or value object. + + |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, + its objects are immutable and duck-type :class:`bytes`. + When used in Unicode context, |ASN.1| type assumes + "|encoding|" serialisation. + + Keyword Args + ------------ + value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object + :class:`bytes`, alternatively :class:`str` + representing character string to be serialised into octets (note + `encoding` parameter) or |ASN.1| object. + If `value` is not given, schema object will be created. + + tagSet: :py:class:`~pyasn1.type.tag.TagSet` + Object representing non-default ASN.1 tag(s) + + subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` + Object representing non-default ASN.1 subtype constraint(s). Constraints + verification for |ASN.1| type occurs automatically on object + instantiation. + + encoding: :py:class:`str` + Unicode codec ID to encode/decode + :class:`str` the payload when |ASN.1| object is used + in text string context. + + binValue: :py:class:`str` + Binary string initializer to use instead of the *value*. + Example: '10110011'. + + hexValue: :py:class:`str` + Hexadecimal string initializer to use instead of the *value*. + Example: 'DEADBEEF'. + + Raises + ------ + ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error + On constraint violation or bad initializer. + + Examples + -------- + .. code-block:: python + + class Error(Sequence): + ''' + ASN.1 specification: + + Error ::= SEQUENCE { + code INTEGER, + parameter ANY DEFINED BY code -- Either INTEGER or REAL + } + ''' + componentType=NamedTypes( + NamedType('code', Integer()), + NamedType('parameter', Any(), + openType=OpenType('code', {1: Integer(), + 2: Real()})) + ) + + error = Error() + error['code'] = 1 + error['parameter'] = Integer(1234) + """ + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) + #: associated with |ASN.1| type. + tagSet = tag.TagSet() # untagged + + #: Set (on class, not on instance) or return a + #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object + #: imposing constraints on |ASN.1| type initialization values. + subtypeSpec = constraint.ConstraintsIntersection() + + # Disambiguation ASN.1 types identification + typeId = OctetString.getTypeId() + + @property + def tagMap(self): + """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping + ASN.1 tags to ASN.1 objects contained within callee. + """ + try: + return self._tagMap + + except AttributeError: + self._tagMap = tagmap.TagMap( + {self.tagSet: self}, + {eoo.endOfOctets.tagSet: eoo.endOfOctets}, + self + ) + + return self._tagMap + +# XXX +# coercion rules? diff --git a/plugins/ldap-user-sync/vendor/pyasn1/type/useful.py b/plugins/ldap-user-sync/vendor/pyasn1/type/useful.py new file mode 100644 index 00000000..49c00f5e --- /dev/null +++ b/plugins/ldap-user-sync/vendor/pyasn1/type/useful.py @@ -0,0 +1,190 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2020, Ilya Etingof +# License: https://pyasn1.readthedocs.io/en/latest/license.html +# +import datetime + +from pyasn1 import error +from pyasn1.type import char +from pyasn1.type import tag +from pyasn1.type import univ + +__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime'] + +NoValue = univ.NoValue +noValue = univ.noValue + + +class ObjectDescriptor(char.GraphicString): + __doc__ = char.GraphicString.__doc__ + + #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects + tagSet = char.GraphicString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7) + ) + + # Optimization for faster codec lookup + typeId = char.GraphicString.getTypeId() + + +class TimeMixIn(object): + + _yearsDigits = 4 + _hasSubsecond = False + _optionalMinutes = False + _shortTZ = False + + class FixedOffset(datetime.tzinfo): + """Fixed offset in minutes east from UTC.""" + + # defaulted arguments required + # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html + def __init__(self, offset=0, name='UTC'): + self.__offset = datetime.timedelta(minutes=offset) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return datetime.timedelta(0) + + UTC = FixedOffset() + + @property + def asDateTime(self): + """Create :py:class:`datetime.datetime` object from a |ASN.1| object. + + Returns + ------- + : + new instance of :py:class:`datetime.datetime` object + """ + text = str(self) + if text.endswith('Z'): + tzinfo = TimeMixIn.UTC + text = text[:-1] + + elif '-' in text or '+' in text: + if '+' in text: + text, plusminus, tz = text.partition('+') + else: + text, plusminus, tz = text.partition('-') + + if self._shortTZ and len(tz) == 2: + tz += '00' + + if len(tz) != 4: + raise error.PyAsn1Error('malformed time zone offset %s' % tz) + + try: + minutes = int(tz[:2]) * 60 + int(tz[2:]) + if plusminus == '-': + minutes *= -1 + + except ValueError: + raise error.PyAsn1Error('unknown time specification %s' % self) + + tzinfo = TimeMixIn.FixedOffset(minutes, '?') + + else: + tzinfo = None + + if '.' in text or ',' in text: + if '.' in text: + text, _, ms = text.partition('.') + else: + text, _, ms = text.partition(',') + + try: + # Normalize variable-length fraction to microseconds + ms = int(ms.ljust(6, '0')[:6]) + + except ValueError: + raise error.PyAsn1Error('bad sub-second time specification %s' % self) + + else: + ms = 0 + + if self._optionalMinutes and len(text) - self._yearsDigits == 6: + text += '0000' + elif len(text) - self._yearsDigits == 8: + text += '00' + + try: + dt = datetime.datetime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') + + except ValueError: + raise error.PyAsn1Error('malformed datetime format %s' % self) + + return dt.replace(microsecond=ms, tzinfo=tzinfo) + + @classmethod + def fromDateTime(cls, dt): + """Create |ASN.1| object from a :py:class:`datetime.datetime` object. + + Parameters + ---------- + dt: :py:class:`datetime.datetime` object + The `datetime.datetime` object to initialize the |ASN.1| object + from + + Returns + ------- + : + new instance of |ASN.1| value + """ + text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') + if cls._hasSubsecond and dt.microsecond: + text += ('.%06d' % dt.microsecond).rstrip('0') + + if dt.utcoffset(): + seconds = dt.utcoffset().seconds + if seconds < 0: + text += '-' + else: + text += '+' + text += '%.2d%.2d' % (seconds // 3600, seconds % 3600) + else: + text += 'Z' + + return cls(text) + + +class GeneralizedTime(char.VisibleString, TimeMixIn): + __doc__ = char.VisibleString.__doc__ + + #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects + tagSet = char.VisibleString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24) + ) + + # Optimization for faster codec lookup + typeId = char.VideotexString.getTypeId() + + _yearsDigits = 4 + _hasSubsecond = True + _optionalMinutes = True + _shortTZ = True + + +class UTCTime(char.VisibleString, TimeMixIn): + __doc__ = char.VisibleString.__doc__ + + #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects + tagSet = char.VisibleString.tagSet.tagImplicitly( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23) + ) + + # Optimization for faster codec lookup + typeId = char.VideotexString.getTypeId() + + _yearsDigits = 2 + _hasSubsecond = False + _optionalMinutes = False + _shortTZ = False diff --git a/plugins/ldap-user-sync/xc_password.py b/plugins/ldap-user-sync/xc_password.py new file mode 100644 index 00000000..0837bff8 --- /dev/null +++ b/plugins/ldap-user-sync/xc_password.py @@ -0,0 +1,20 @@ +"""Xtream Codes (XC) API password helpers. + +The XC password is a secret separate from a user's Dispatcharr login +password, used by IPTV client apps to authenticate against Dispatcharr's +own Xtream-Codes-compatible API. It lives at +``user.custom_properties["xc_password"]`` as a plain string (no separate +model/table exists for it in Dispatcharr core). +""" + +import secrets + + +def generate(length=24): + length = max(8, int(length or 24)) + return secrets.token_urlsafe(length)[:length] + + +def write_for_user(user, secret): + user.custom_properties = {**(user.custom_properties or {}), "xc_password": secret} + user.save(update_fields=["custom_properties"]) From f2cdc9fab3d8a6f718af18f13b91625a4aa3fc01 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 13:38:59 +0100 Subject: [PATCH 2/8] [ldap-user-sync] Add plugin logo --- plugins/ldap-user-sync/logo.png | Bin 0 -> 25104 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/ldap-user-sync/logo.png diff --git a/plugins/ldap-user-sync/logo.png b/plugins/ldap-user-sync/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd04198c240e64ef693c4ef9f8d154a58d87c96 GIT binary patch literal 25104 zcmeEuV{>LrwDuj_cWm1>C$=-OCbq4KZQD*Jwr$(Cok`9-AKrR@!>Kye)zzzacXd_o zy;k?SdR@K473C!mU~ymp004rNq?j@Q0P;@+0YF3kD|8&oe*IT-QkD<_)J)@@{i}$X zYD)c*lLOHFlc511p%wt}|GNCkIR7#L0G0;=0Q*;h{P!#m^#8Sj0P?{8zx-cEvvV9N z06+*JB_^!u4szuKPE#w2 z+{ha12XjgpGm5oTU9l!|K%OS`d`q2m?%Ek^?bi3r%g1!vO}8P&98m}BO;)C(fRRZ4wWiZmj=fJ|P| z|0j%Z3L3yWL5#aUK+>cK>xs;=*{x5*c)ksIa)9?*$c4#{hFq6TG0P2f3@%a}-C55{ z|9oHE45*dxs!hMQCPu<|)z!)?g!0c}fAO+4G{52w&gnx?>K^o0)uG*Nav(wgaKOLb z<)JV6uC(3(4npSA=*9=ljl@LquPvZWc_qV#6MrQwo)ivGzA|Pkd`#zT`W~&o<2Lt! z_Ta)D`f(Z|`IR4$PP^M!95J6@dWJ$3)0>(6#ep9F1*A;NK%2ZpJbnPD{aqBU26`W6 znmQr}UOP@vsz#ZeI)&#l`^ymKoC4`UxCZ%X+^4coi-$ zW&#wS8;}&L;H~IzRG&-x43Cij35qI}DCiV|^UE|>8$p|5ck_3(4iw-wciv3&s!jNS zVt=rItPx|72-ltVR&!C`F4|Fqu0wa_Nq(@AT^EnT2DuH3D7ogY?H?gZM1X_GRY`18 z$nutUpWTHM@3|Qr2_kv~O@3Jzn-%RYy*&0~RYGktv?N%DWa7{+WxPGz8)0NWa^!Co zL?o&J+E_9M;6bbAm*1PwOspkZ%Z`bdAugT$i|NYZDICT$b0nJs@x7j!*n8@&7Fu+R1~v~oI}BXZjR#B zH;GBpw}I+mQ3u=`F6Mly;l46y0{;5|-x6@nhXA2WW+QCxpOLh%E`9_T;A`dv!%bK= z(QvTtNNlK%^}nO5*KN#^6Xq9Hc|^FRt#Z*}tq_P37`xy>s$fP;Cw_A>3?=V5_083P z#8AMUUDpdi@hItnjKnDy&BahLiDP$QL}G#K{N`m*G8IC+Av&|~djgZZlVQb>Ws<4> zozcH8oNQ=}iu?r{)=y1t<6u#Tee|Ir*zI)%_FY9zmlO!$%L@neZbIwW|WYIqY zQu^qK8n}JCds6A2$8=~^dHL19%qa}Ph-?Po?NJwEt+1o^(!#sf~Z2mSE zV1S_VOcPc3VU}Io+=-O2CF(SlUN+atZ>i2mYumB+Q8;%BzAEyL|MQ7k2*ebWgVLeqcN`?VP<+UmK&%jd*oz)8uq2JLnbf|aTAwYS42cuZ|;-!^jxta z)#)30a2(4X+Abd#dYT@|@h^PL25>_8qOk9g;RmR1m-7%j$9>oJUgYm2gx%VJC=M&*OUJ#|Lon7Yg*4= zXIeitt`aV;CQ|=1?=_ue=%Y71*eMxDQ0^BGNHO^mDpXRIH50H%nn`U%qcA5ZTy=>2 zGFj8+qhPJIGFc?H%D{5gHo49m`{I%%$TAIe`gTlZ2nLMi~%L;#BMj&3K zr{hAZ?n2>X!;o)MYM>5AQc7h=)&Yc(XB=)7q)1bP9V-w}RM#&oU7BJ@u!L_6X^E_j(cW02$s;vBix-NJ)gWDr4LY0SFR)i!&bW$z63(k_n`1jlWD=idA`< z*AGGf@w^0-8A1hgD5+nHM1tS=3Xx2>6T2FCxF}`RV#WYWZs6q;E9^3SOrQg3{QT=M zM#X-?%0-?!72Z1cha`sSecd3foaYxF{~ivg> z+VQv6jj082^|_g75rAw9c{T<6BKrhd0SoihSTM>dzcGegbsP4~C%$=*k(DDhSPZfx z9C1@=nNnF^MV;X)i|kllwWUe3yD`+O0^c}LBFj=8RT$Q8si-?rOYTOG^f0a@T(6*x zxm0I@gbve z)cg)+rQd!V$L>7bNKZs8XF>wT*CFa*9Z^2Zx8h(P$B_vX5@+|3K=|In_bwv$2F!X4 z6u}+Y?mb}pb&bL_Jl7FF`%!6QIb}|TbDoQ5q%zXQa>dzZPDJqR;se_EZugw%bWLGC zg5czS$?ou+utsQ|7j+Ip&-T;;j}Q`Oyy)87jwBT2co}nEf+jMRjYx?5qfoC6^l(4W z)XgsGLf1uJeQJ?Yu4*W~|uxOifzpwX0mYu9p0BV?=&`08Y`5 z9VZW$=z9vG>`BIdJe|#jzYo^5D8$;l>9939K|Te@7{qcI@ZQ%xiF2lY5% zP#-aNwmNaKJ@r~`2BTUU;t`51~63@T0ifBE4(?65T) zG|z0gu)6XbrN5m{!Xf339Tr5E{K|Q`jHD#|9u%C`_qz~1(DmvGlb}c_gA0Yk1Akm7 z2TeXgzyjZeX*(=)IeGNHtGqc+;SrSAG6_#iqWn16H1$}nuz;=(=C2I3}=1tJ5A z_c3$Rc4Vxg&EWA?%M1rKb7UzP0zI9A&sQz@@aO*aY$QwT^xBuDWbvS&WV%&OJo^18 zdTq?_Yv>q3kelnpF0{Og%h<-(eX2512T@-UXJd|w>ACVP{OwA~d7-vzq4qxA&qKub zD#DFj1KuveJr{t4QuopbIFu5pMP-z|1wVh@;GD^NJ9Of6Z#$k?3P5V_xfiA6&;LGM zUXtv*71NXk4XiGwO zZ}E>L2EkiLWT9HmZdw@)QbF=SzV+rlOKauWYjWNALF5X(=n|3}eJ3nLR-gmrJQmHg z(_BLZy~{B>7S6(ujqAqL81fQB7QNZbFyMyJv2ebch-?&x8DMfsqc3?=E+*_uS+ zPz;zlxntUy)N!&sW;HJK+V+|7lHX1_`rDHv(}k;Wz5Uu-`H&3K$Q*g`!K%_K?d0U- z`<&3q{1JV2H#SjNUpb7lJiL2674-D+xqWP6vb)5mgtc_e0T^9m0>Lu1(RJ`AZr=Jz z7&GHT;3TBqSq#tsY0Yh`WIkt2Vfj#>8&1z>o{@pDDQ|pVROtwbc~{Ke{2tY*$Gsbd z@F$m6DPYoIZi8e(R^URmp~UB-Gj;CdGd()OCa3y6;fO5CGm=D39A=Mscm_z2Cf_Cx z9~?$t*&ld|T|aFO>JI!IK8|}-u4F6^<2I^n$xQ0OK}Ka)B<13y;66Ke}5Kh{)mlEP1rnCMVPBR%n5?hhPHzf_+a39i=*_;Sj? z-MCvc0vn+Tc8>CdR<{V}j9iX>G83Qwi?2L`+RiJB`+$dSt1C#yvZi zZHZ(j8)CD7r`q)XARIP6SQ*)Rj!~%)Rs#VE!xz3zo_^tHdO z^UagBrgL84IadIyU_ss;hHf%laR7)4gMc5f6uFu3l%v1=B*Z)wxou8IfE8J$tR4QY7t33t8m0=^7+?o|Hy%Ffcp50cL9mv>eUnemtd?HV?yO@bU<)RlJ@&hUk+QHyeckh;%(bUDYwka0hDW~T z8Xb%^q_1EP7=4%3-mL6AMHr43#BTsutFu4PhxbOd>_Lk=q8pNCl)Y& zny)Q8{K;tG`zXy*lF%k6{s|ISrTMbn-+O+*eDPBZMgheU^8p*5mn#Uwj?AJDFGZ-Z zSrlnet(azb7hQ<~9ltBl+Qc?us;)>h7#G+npA*e(JospCH=UHn^d&Zs>4NDNDN_F! z=3O4e4h+F9g$m9zvVrK!B4NUxnHvgLzL|9jRj=;;e000^c<9n|w;<&9eK6qS`k>bHY${m)^IU-mdK2i<#!O`pH?$z_u2ic&H=H(ycc68Kl3p^ zptbT_i*LInIUsC4WGjMGSIONY3~`7AV~}Dg+|}uiT%)--GdSLxrn)>AJ2U!1vnH~! zxLmBWqn!T+4I9zu;A%Qxs@1ObJKBS;oxqJ-(ifxgK_vW0Hdzmyhh7Ieh1>) zIq*cA;Z4}}$?Y;Ww;}2PCt(ELwg)O;$4t3Jsm-z1k)%aN9F3PB^#w%A z`^|LM<~)|*-dvR3uw@EX*jusi`l=fnF*5wEN2oeZTdZ4`U19~tHThh=x5zWMyIwXA^q!r1`kA(aH>_&P<+mQ6 zVwY`uu7#WCs!#TOgSZ8x%HyZND;KKOb*wgZpMEA>T%Xav+r63`y;62t=bw)KTdb|_ znzL`B?Vop^*`GM1>U65KLqgwk*I&jI1e}R)lxy7f0eSdVU+1n(vFIRsZ1vND=y#^u zBdd=&YeO8O3k^U}Iwr+2OO^n8bf^?e6biS+VHDO3e8KdwV^rN~C>c09JsJb9*QV5C zanN!9VQV-nmcWE-MqP4Tp?;rKEyL_+m=KW*_%N<{1d|A$^Emn{UI<<=@f{lxL@|O; zjU7JtFf?L+?^q>7D}6_)m%(8z6sK*g(E_inm!9+RNTfw!B=FbExA(|n^p3lW&(2hA zMYPR_UAA%E0O*SUrAX5%GPyxeii0f?Lo(cJ|GdYMF@f)~$lTu*{fB9j@6}j`XZ^#) zrSDfEBOL}zTw0ADTjHI6)7}O2u5FTE>Rua=nM`+RNflT+>=vmwZT%g&yJQhX^qao; zLD@4aez`un7N!2g#)IwekJV!}TTiX7l_D=s#M0~IC9jLBh>W`%BK8|A7C@6(=Df)w zeaFRiB#C`?kX(dCam;nFR~h(*04^!l2ur$Z+#}Gc4Ud=7TbsvuKPmJh8ssrhmPJD| zdL8fA={>V31Hybh~rXw7+$o&bh7$d(i{)L3GGpP1x)$H{=u& zYu)>h3iv++3Gd|R*py_*=t}pyx0P*7PRSuP-#6s(0F9hyFpfwkZ7B{G(L_|PNXOD$ zvCA@4QKLV=F^;!O@p7ez3Gr~bVoR)$E26aDTl-gO=-X33<)MrV=}6i2Y+)n=s)dYh zk*A6d)MmN(VK5PK9e&o(zwe)>;c~)q0d}W^BFS1>Im6RT*D!GY5EuSX5Gy(U?Nm4F zuMNJ;p;U9wZXIUE0;>x~I&;JAcyPoeX#cFl_${oR_v=k7XU%PCIz6-dNxBNsx2M_f z!Yu*km(}+>r&U^n=1V!}wD6&qMwX72&m}L$c!k}Tmo1-wz!)Zwx=pq@yY`2J{?Qme z;pgsou(wS8wg;F$2A~?hQki2J`TR|Jh63+xdV$Yz-k%01ny7LQ8e!kDXx zUcyln4)Z*H--x0SG+=zG#ND5=w{Po|INyXA#yEnE4x2o^`tYJk8agN$z9s^`NXH*b z(jElK6%p`=ZL2cqR6OBbe&$dTUF-4lSXm=#tw9RdJJry=A4Y-rxz!`|ef;($}v z^_;s!5U$GYyrH2*|8Afh_v--3>Z7HzQJ~wbV_T?bqj}D#xo{CJ;ofI}@tpsd8EN92 z<6DEVjTk4hGj4}c(XnbVJ{DcV$A{Lja#?_5qCs`S&2qAMy_|QcgSnPUG8+}*L&6p@ zAxV7sFN{DBds%v1UDSbpNS|${x+wTtS_$9ZFpA2<3V%;^g7KJ?zOxNXwBR;%RU?GK z-8ewX)pkKap@=?3o;yd|8akB)+wHp zM=mYRb6j`pnQ@n$wwX4sY2NFm9=<>1A2H;*^sRe>IcuA46P1|_iL9Ohw3*4oLJIWu zt%(=cUYbX%UlL~IvY$hozNm7tUsTlVtwPCH@a`OgrSmRn>xd2z7E($}ql%9ZKOkwUc(HK*RM>&Lgo42uu2U&70t&U4i5_~t11s@ZdrEsPXO~2Kdehwiu=OK$IO#Co)pOYG59>9oJy)(*s=dZyX~jEV zT`ecvW-6m?J;aS&z40ian>fjmNil2hlg3{WI;HDW2Y*Bl4^IB*Mgq60OGb6S&Qm4` z57F2XB-bwpj==?-dvx3KK2cxk-xyn5<4+%*Otki@qBL>04r&&0U}XD2qNjM$)lh}e?c|_#R;q$lAT`fyNLBRLDLSCpoB9gA1ns;+wXTHUTV5l z?ozFJ%ti=N{OZ^muI3{%4_b1UvNHQ|hqnyj!cD<1=cRWBJY(PgCjR-1u3xjGR9SH1 z!M^<1hiPvwEGjh{+W{^*fB^`DkK|JicxPn)CVv5Hjknquh@V*jlzejORT0ye-uT>T zN18&jah9H1?7PssHC%8PM4 z=g;6aI*2>gX+5{-JNu>ARQH0qAjo80#A_#qZqCa;G{^;&3PgnmvK~)}j7h7hghWXS zPf{!&B86S>c235-%z#i5UssJUQNB;VTlD-g4q8Pyd@kGsR?=4Aq&ClO#@%5XlWxvw zM~Z8j%^)gr+aF8Ze?9-~)IjFxdp_JJ2C^S^86}VFwg<0qI&mHUXN>TG&j{9tH~-HF zUbnt&B_{jW#A&abN|b$Fr8Y^)aGY@?C$_BlR|U=Wka1fw5M2&zUMgx!Vl-$M>)!lc zarpW`s6z{2xlc2>PZ)7B2VES;giRfg5lV2B8z7N1J;Fd$UV4+c03iY+8XbXhx=~6# zc{-cOLt0)-$3=jmeKI5idT08}R>>)-65@#lW?y+{Huo{Qs^_uM?aFs%*vzLe7ZtO_ z#ArktN2QY|&c%mn3@P7P?F;azw?Nf?9{AJN^IE$5NK$HC(e(2*VXmfscyB5b(`Ez< z@!Mt@HngYNEj7gAmMe6@AF#LiwAz9peY=rD+ltCEBjTtgM~wzU_BSZpBP5a%QB}?` zPYn#X4@vf?O+0!XE>Xup8QvUEEi$&+<4xXg%<=a!CF&^@)whzVa!rY%(REJ_nYER% z{?e_>oRO$46EU*dJ>+bh#Lr!_4fJAUNtgvNu|rT8D6l)6dIW?Juz4|m0!oW);-O(* zlEn~5Ib@E;ibGFmu1b;64CxuDWQ za70rd%O$$TiN9U3)wMt6{YwO&ON|&Ps()Cc+`<~2`ui!mU%}j}9sib5G6_+fLcl^a zelP9UBH~_i5iEeB`s9zr8GZv1aMdBe@>QHs8u2zfqV3+W8mzW4w!PL*Y#Wo>;%<;>?S@_zmz;v zIdW4vDS!Yc1m>}28K&{HrO&if^iZL#KvyMkSUDQa_0V9K_dEg8xh149l-HyPC#0% zMYD7F{5{hNth1$OscYVIV+6zPYSp@)bgp4;B_3kOkBEz-}n3m@$>#}BUR0FrLK?WBpy=M(jz;Q&CfWXcw zpRNWS69Tt!A(?A}pg_R470Lszg>YW3560#4mmW|w)fz_wGjkRCu!MR+Nb>rE-=Q1b zUS*V3t^HD^yjOgv9)jpRY+K_C02jFWs3nvae^AroVM_0&=TM{(pYqeAnzYo7aT{%;u+s^vDy(9>?^+eO+PH$q{}iv4XM;I3aN{o-)O>Rw0tQxyS%n zOTi@}qu->7P2=S=9^4R8)Zr3R_DtA>KpB^K^Lf&?>u_jXN(^YVD2?A&xZ}!3MD6}+ z_AIYq<}=lli1KSi^)7);l1Zp0Frl#J-s$X5Qud@%wm)Qyo+aLeke1_L3zl^9?LX@; zVswq;mYbPbJu0Wc;^Z-mM3LvMoAFt)ymya1s5q|S!Ov5+-!C-_@3gzutBNP`>0Gt} z{&3oc>+4Jj9<1cadQrWJx%!1X^O1%FSj6Xi%_%LiabqKC1m6!}i2oYpR zxflxRwWXAzP@i78!WZa25#TOrPLb^~#qQm=3-3_$r(2N$)iVwFVAFz()|sR{f&lQ| zVEsF{Dc2FtyKtqwti;A7eP$x!2-T#>%Hn~i1kX1n6t5Czt_7OP5dqiE+9j%)>GNhv*fUz8u)~2lKgq8vQ?NI1HA$L=+#XStzOEG) zxC_Gzc93_s`evrrFPy3Oc2%fT`2hBH+-cIsFZPJiA`t1KGQh6QqH^gh(a4|jKgQvJ29Rg2rf{bZU8E%^E_&q3ecd9t2 z%XNF5a_K?jQ7lg1?PfA9HP1xx_JB`a9T#{vy3&maAES=0(!Lr z>N~Dt1Il4mu86O-m%B2HxlVefw@!Z_LppOl*fHG`;!Os)F#I?nlSD{A&{ks+BNGQK zEK?0mxX~*So&JH5ZvNaE6_zClNj-UpmN7&VMrG?%%n1kvb5trF{HKql ziS`%#S4rV@uDnbvvc04Ypj2KPT?x-lp%_vnM!An*%4qt@mvjcb7uS_&6Mnd25?9IK zIE@Cg5%P%OyD9gFYJI-g^cI0}$@R7-0o=54jK&ZX~_2vbm(IZJzF zr#AxNhPJfci`9<@9Pm?aQ4~D+zFeX**7AL?^M%1(RXDm7n4Hjmq~R%T(>$cVBu4sf zNjv%#63rhnVd*r`OD9RjL4>WLuy}_qV$3Hf+*SMoomF z!&YdtKC654?41M;D`A9mycCJ?4b9=lejUi`ve$~saT<@P)5ySBZDD~RGcP3;#Eqi# zk3IY)pPnS!2^Mf(xvo85^vHX)j|lkZ6qBUN3ry%EmC^a|}cMO__u)c4~@#lv{>O%Grz;?sY_BK;x^nyAf37Cn2MXX-x#OtYq zg#so*zL^)3ny_fqWbS)&^}gARlF21;InfX?{rhiaiW!mfS|*xzG6b_CVbNAu_g3| zdfG$jFJ@(~s%7Kw+wH$!Oz+&MOWf1;MwW=bpx99(R;?NI-I$OV!|1bhxmvz3J~uNX zKIROs{2o~)yhK>i=tm2jN^c84&cWZ{GpGK~+Y6%sqBtM|Rb?&9yw@L%_ld28u0SgyNvWtbTvCm22Fits zE+d2L6o(mjyE_J5Z%W9@Bg05JJjzGyPgU~V&|M@~a<7`_pTdJ^(iLz0#H$vVYcT>R za(q1e@@@RkoARRfkn^!+!IZKhuv;D+&}4STVRB8_!q^J+sCM|4ev>D+0@oD7`K?OO zkCbMBGy8hXHt5?2GbsM&X`6GW^M!^~H(}!+YPDZqzM>+8+58J?aa6G-yOLwG3yb9a z+o?i_{9yK8Swq7)P^5v_j>W$!Z6=df!e};9&&J*uQLYaL3Wj_z6lLg@W$N=ZdMrTy z6HrTWF&`%kSwSpiaabZ_+hlIZg}Tx#RshigTc>BfiWcy?NF$Ti4>_e+>>Ni%B8Qi| zh;7CMk>H}~8VJ5ac%bC31cIa?ig@BRC=>af>MPU^GQm#EyLS%esDeB|!EkfO&~rZc z^<5Qn&Hd5tbmJ3TC}6(au!j;mg;f2mT2on@#|x-NUqG1nKHd!QbaH*X&;kkadkg6M zsc-~RFOTaGC;sAtR1X?}^azUF zACPKBv0Z3j&2smert6Qgd|fFQ`(LaouZ(!Pj??vi za4@$Xj)XLUv($5#KiYu6OiG)H{93Y%ZHnn~w@{9CEZrf`6!o8EmyMI+^kuON*{0{m9t>|j?S%6K@RCWc=F-1PoF7v7FDROS21o%6mM`sLvA z?f-2XSL~U7%rum%v4{aNxUWdh*7%~Mt#G}GhuTHomDs&A$Mw$R1*VjE#}MUYcCg9x z04K8l(cv`WbyDaZSB%cE;>5B)qn)iqxdAulQi{R`AGSVe<=k}r!&96+#RI;n6+%+WTrm^!@ zn11H-R?Ns>T1?C4bQ~T;iZ?2XqT6O3XVVCi-(;P7Dw{fp#RE&WzK^s2jW~7hZY<_g{TKG!k{bLVH@?I8( zc8qzHw$Yr-ljZDmps9(#kDD8dl`u2blH1N5qKsBU+afuA)ffUy1F1Fp(~bXep$44h zZ*FG{gCe+@tYWaSJ*tV5H4}-BF3ZP+LRg^KLa5is*W96j*c|k_W9MjPW4mEL@zL~9 z!<}eYR>q}5MTZ9yY&^gRiLD zPF0Z4SaBhV+2UQb85?F=u<*e7f-)C2-U@kg8`%q=nAsW%13YX@isV47;pKCh4O{}T zG?jngva}A$uMzn>VTpLkW?+_4qSo_(7trDA!`EP;fsDXrX<3cEkSD-R;}sE1NBm^> zk9lA=UZH&PE97DJm}bA>dzNmxv*PHI5d4gHFdgD`^dUu>-s8rvDKm$nuqM_C%28V* z>*k)#!ufl97(j2MfrvwC>+Z+--ny1lLvk%DeX7glN0gdiAah{D9M)#;pW)nl_3<@ z1?DPL9f&0*2E&3BF(D`+18`OPmq2uhhMtD_j#^U=k@$10BsTAzl&UdT-?!X@c5hhb2TWnU0uN3_}^Kt zoWpm<$>BH{gx+z(ZYgL9h%_4%O%>?~(GFML1Lo1$21D9(gzwk!wYmFgvNw!me<5g` zH0YYc=xkPcI%AB2FZ;wF)rtSMs*|mB&vw8IPF7G(?l9_R(o2|It!8w1oV?i0UQ8<5 zC=wekR>u%eU6@w{SUh*67*D=qi#1#fVt+YE4e#;(`XgD4!`ou{5HZRlPjDD5^K#t0 z;fN|Lu~@4KY3xEM2{dMD1eHfHUJOsBsze&jfYc+lf_FVU3Lgwkztl5*YB?`*EAvCCX=SV!@j=wQJ==KSE$4yyAH9v zWgR78kMP%i4KuI71nc(#)bYiEmwuDo&Xdgv8VwTnv)0)7-U908nOV4epC4H#Tbajh zZ*gIZokfS~Dhfke)d3{nRixcKxuH>K$CV(9Z-*DT*6W;GNvFl?_L1;L$p(cQ{I5s? z@ZA@WDK3%>5?*IUsW=jzi##@z*o$KQeQ0Ww3F*#7=bjT+6)O{#s7?hm9`H|-tGU^p zoPIKyc~#T!!gDC&G)45wkXnU-M%~EES9XX3Mks!)<}6VY%UOpT*e=mP!GS?n*gIDK z)(IGSb7EZzuUCk@S$}`g7I4p{7k4h*Xnh$C=ZPL)J`3G*92MrRN5 z%svH3f!!cxZ9lv?bufJUO2-7o{9UQ>c8Wst(SazT$-HxTLqQu22#=)?Jrexb`WN@v zA91b3Q+Y~(8&%8DTttO~Vh#?K>I7 zqG<@#0vx1mAnlt(G8k>v_~&EN^eqMguK3(oJt#8A7hs%a!x1MVB?47wL!~>;X$DMN zJ0ut&tpVn5Qi(%UT`N{f*4cp)s`b>Co~tqP@_EH>CwM(^MNh9s8_RbZ*6O#5F!Z&D zxtHOKt(1%4Z7kw+-m@;wnIFFfW}ZPlJraGl@y)4$B@m7bt45pK|Y9e9}0vbp{vbp18?3+y`))! zRWd57@=W9u@$%GBs>6!pt;F5>Vp9&AEn}6dbWMO&VjkGczYjtguZw^&vt>?GHs|E^ z^AmwJi@;FFQLa;~%b4)%Frr-lVt6=ks3TulE_senY zw%-Sd+$MF{j?FLDPP?6973xd(yhunA6IHm7Bv&@D^^*nfXs{Na7UqrvE$FXjPVlZT zexJJ%V}V3%Zf_GO+rIf+ImO|BgzV=l!IS35l$lF~0sKq**jCewUB1r(8^D1aUCIW&A+%l}hze08!5yh*6uUzMof+)+2q!O`~b@j0dPh})hX&dX6m0!(vKC6s7jptPzsGpUb{G}t*tK*K`Rc~_| zxPUqTrwt?*w)}J@D(YY;DCg=Pj^?Yxtq(ij`N`$V^&mk{vHTNZN*_7_$E^WW%+GS} zRhEu`&<01Z7hjKOkC`tV;R$M&O;|vDXm*5d)mnenVlxKRv-2t{Nb zT|yK(0?i=w6g_@I>8>tnYHiWgTi|}O(IEIw%9Z+!$6x5S+|K1{FwO`Ir|Ls=bg?3Hmhw{KnK%?LUMjxfaP-E9perz zeBi|`sy_#&c~zm!ROG7&C;`L`?@dg^O(DW5W52Qepaaa`f(WXew))1sph5D-~ zjI84R^cDw!8t9HN0Ur7I&bL|MUTEFODf9!mFzv{w#<*1cbU2`A5%*a8;yee5N4W|wr^)10|{0h}cHDI_X zf)J!uG9#>aJdmzpj{Kl`w);N+{JQ#%?dwroeqZS<(eYR~V3g#j@~ih@&S)Ma93rup zJ*0^{0du{2ue{Uf+-KMfwC6 zTsv!pr+gVD(;g>Gu63*0Z7CklQPDh?12vHtJsX0xgK9`dO6ku_BsPvfbs!XL^RrR-9?exy*m`s;(oCxneCZYxI8VnE?7Yz{?J8Pb z_<+|55~N6-*lQ)qsGXXz89`vfl)qee>8mE>d0Odav^yG4^fK$v;G==Zuw?mSVX)vHa~05V^&BLtr{saw zn2U7IfPQKtM-S_~V+iueiC+tJG7x&XjN(IkE_SEox%UX(axa)v@j27Z2Bs##gzUo);dk5eNpxl-Dr)=#Z3VNf|*SK3c0MmMA7pL807R&RWL zmX{9VWz;wJ+Z9aItdBwQuHp zd~t2d3R=@xze35*X@*d8o-^O}$^DKzQjNF&T}N>;x=&6lJvlI*qgxCbok+zZA3)k(k8us;_p%{X&@P*(M;8Gxjpm^5?p2kAsgxj|_lTa*ha zEcADVrlr`^8~xPJC%??4v2W>;(jL|ZyFHlh6j1(~e{`K!J>2c2D!sdVowiDIvyUl) zUq%-KEmGyQF)z`2TRsCRW(tfA4PW$;n&tnlZJeEHyS+>i_*itiEhXL^D`X1O@onPm zX7{I$4@JQ#a#2f%@eY^sE${hYtD$4tMseT442w%%LNwok7GvQ}sIXy6NmIwDjWGO{ z`6F6RoK%h?EIACx4J|N9q!y(3hN$>cZw=uL{_0o3dXAN^ z?PSkdv)h!9y7*AH#>q#Be*BF#cTteb|6FL|V`IiS&0|?W6IZBhp-qpBRSashYCAye!ORMCxTqX~^5@d!q@7JZ#j~ zL_(7^-F57A!TY(745xIIt5nom5qZSb03a14i%ctIq;qTi0I0ICtE;v226Oh&J(01a zsp)2!PZg2-i5*@t0Xw6yf5%R z!8`K-=A3)(IWu#A_ugr#dbu90UJCzO;Nkf4I^&PNQOh#A1M%*9yp0=y>f71;8SH2C z+Ajshf8#U%k=Jyu8--b7>QI%kpuNO$)Pvu-dRu7=KPj^r>A0C)HlP@84T-YIOt;f+ zg(i=CBSN%IGF+y5PtHnBw3DM)2m80qGd#YfFS(XcTR+P zvOL9vX9e{G#1TQ{uxuw`HTS>kg&Z4TzJx9C;-POS>WoNH;&yWRgOEyX{uUaFfW%g3R%fx3=(2eT93gN5w-d&|@bZ4M$(b zaS(w}=&8S&Rc}7yhP~-MkokT%HvRS*8_N`}W9eg9{(@b5 zl*^WiWc1jW&(EKepdUhQ7(>C&I6$%&!AlJ3iI_KWR5c2sSH8I}y`JM)&{2D@)dV}V z%ohG|Bg8w`=6*k{_32mv!V2R0N{eTOUUjjZa2IcUXFR7%50~yOHK@Tt_22!d%?Ll_ z>}uMKgAQ1o_KSo)hkHta`a+gQ{*6hQca?u*_|*1BI`<=<^lG6Q-wOaCS=$d{>LfJ= z>Uj~2*k9&(Nf$ zTS>nhY-Qg|%aa}hcJ1bnq@9Dr&*p!fJ}g(Y0N(T1s;??at|biK9k4&|hd+ExEIZq5 zsf4^`rc0pVr|ttk+PN9Gi`;K78cTMnI6o-iSQCue|>-m*jc%@Dcky05be3>t{ zU#eN)+vgsT`37S`|B(x@7byE^19g{|UV49ObeU*nag*Iz)q<8pW!{EvPp`Lj^Yj8- z1gTG-qWf{)-v0ch@NF<$5}5U-nIryVreBcf>YWdqFtE~3!>cE%||$?D(y@$X+Xv7fAI zx(fJpaxnA z(5puw-npZ_kp;Co7ce9w^igbn6+#P4MQag=G&wQIb|0}!O4qNNBh`umL!=8y+y%Bi zu#u5DG_ECOV&b_CJ4U{uYp@G)*+gF2tz>MJDA{l*Z~^VL8_()F;oYx&yvw4D(Oe$H z>nfsm69G$xR>5@SrxqdT!R79NTkA~5*ol8pv{vUFLH~B@VR_PmbM@!dtowww#pAfl z$cn)Ou2yB9J!tU}PS+7i};;N$h7jA8Bb? z7N@xp+r$sxShB*#VfGtt&Q~?K;8k&xIbLK;8>|a_Pnt#CTwvDA5U=b3>Fw2mP6$!Y zV1H=TP_9l+mn*luTpzm&mMQ3?1{qrV8#ruWWUC)~g7g^K6$E~%nkDc8U$^EScnFki z4))Yqv{h)=d`^oD`dd{TZvXFa3lg~as|>iZCnni)Z=;=W$oPWu`pR@k;mrwUb7ty0 zb~UklA-4+{!8W5WJ!7{zxmDYwsJJ_pWf^JD3O_5QL`C6C>aa5-8v`~)GP%RHFNYsP z**w1Es(&29%6$P>P}JS1C;gbbVAX@Kf;S01)aaEo$Vuc>n~(hSl@K?Nt6Vg5AsVSX zsA0?EjyL)JC7Z$>)3YzVDP_gH+R`*wEqOo9w3F>0w@l-#G+dpBn6wA;e_$c*ESBUO(%>JyM964@<)ppola zsK!|YT9}BCQN*FEW52J4kT09Afeb2*8FNQQuen(vFH;fiQ_PUg(6#^ z@{nHy=T+T>mKwf=Y^>WmjezN)3y%a{O0{ag2G^;^ zNPHi_42G-wy4B`1ddLq4yP#$yRcCZJ!GhtXB?!^5bn0;syU;wT4w$%kAy)X7qq;Y8 zinM|KHRG=!4qdg~BSzzSGE!xI0*?)AsWIH^vzTVRIqDs0nx^JdT|7qRV%>DQ?@a4m*pq{YJ<~wzq|Xm;>!e z%l|D3rFwRv{U$%l+>uh8rwN~*hU4v)=1KhA*}$ZJ zs!&j%+~@d|t;qhbg;V6K>y-IZ4V!{bCc0mQ>c4NaL0nq9(gaC64r1y@zvfnA!OtFhq;XkyYxD-^rPhCF z5e}~4VHNWp_&6CYoN1Onlt8 zMu(5Ot(is-<@jjl4&CTHNpye?r1FEwf!R6h_7x+}q+-`+3|vKM9-R43Rgq2wd|q!A z2~*V{dd65G04$77oRyCU-{?(toCbUmANJdPVJv(Tmdg{N6k~*-IA0mhewyeT_cy~(|~=pzEJlhB&Cwuy3QGd0Dt zNIQ|M6KzjSz83w*$UB4|I|smI^q(=@k<%{nXHQkV?$=Cu+eR4P@%Lr5VsvWo<`1O< z=b^ZlH%kGlwirF9FR%t-%ONWLI&^T20|pbvR55c99o%CaQ|QCg(zUV6p_bRjCtAS) zF1#(r#lg{rU1j__Kci~H7hk0s3DoTuBW;KpJ`WW>q{I!wgb4vxy7ap-Tn4pH%LLLJ zl|y(j#Zl7-k zCWU@gJm%D8R#2PuaGurodEKK5{eGGI0cj{zvOM>6r>WM@?A+7?rz&{YIR7+wU#+r| zdWSCTlqx@`nvdxVFwdxwdXnfT2fsK$1kFDcxH7ZVSOcO0ZkM-saSdhU>C>v634B3J z8T9zban8$B4H)ll13hdr(^cD4uSGL3zF8!0d z0hIiFQzu}ed|Zj`-!&9ktvDjCfG%XR@=5M$Nhke>R+qmi~8QpUaG1%TXQ&hFjtnB?x>f_)?nOFvJSLog2#cX-s#$*`sD*G=V6l* zQZpPItm%Z5&?9>w=xX7QWTd~BUoxWE@6}B)h+%G3|8w)h<$bf5;)i|_KFMMCi7RWu z19@N10)I|3hSLg3+6_Ua(p)HcQK2&AY-j%%G26ITaXm6?i54J)roR}EUzY1>maPot z?iSy2tqIWSx_eT&_pPE#foact>y%DD0%EW5jdP(XFA4QX_<0H{5md2|n zL)<1_R4EbmU7xn67bZx$S?Fi>O>604s&PBT)uwo%C5#YI++h#fR}q(WW=|dxAKjz3 zlwqt*%eAHup=c|cn2m9s9CyeTt$x($^xfAqHH?063Ant!hw1g9L~ia!DOtwX*Jex3 zzCNRyad=z)uGI>Mk>8zu?M-)thlQPez5O^l+vCMsDiH8q|5I3{XU37vp8kD}3}R1l zD-wJu=)_QKQZTby?MZCN3HHcRWb<}apFHUMVrhXgENU>hnM}^_B{;jZcEs{6Ijg^g zUI+I-q*O)Irk&P|6icqrHjRe1z;vUTicdr{Hfh(Bzy z$QRBwhg4g-P62P99JAIn{aYn+f+FpxHO$tA0*X9@!N6(9hT{sC_Kfg%*91X8-l z=PZcV?|=jxI}X2j*ZhNoIP~u$ru7!UGo8HG`7{JjVQ3NYt`HWcq+IA&g6xOU6wLH2 zBOZ^G7Fv5n34xOzRbn@cnh%u%S`zEwJ%4WqqMq{feZvGb{tn02#z<63pDWePDjTLD z1%QgJ=}<`TAhJa<_HI8bpRo%gXLGui5%9G4wo>84x}X5{9o$~%-2Tej$%5+6bu!ys z;*o}RhsuLvCiy3kucJWfdy3mzN#CiAD)FV9FsLZ1OB*?f4Vo-p7+lvQ=!82bCfspj$Bo(2w8(fk-B<^X91A*2R*-jc%V1ZOXilG~2`cpD9-B{G>+;2$aVcU5BcrlJr*9EqV zZLn4Q=Iv3htz8JjzrDe@U`a1FOv_IaWBSO%&d6w_Cw3Yx$oWc`;^^)c!e!G$iO{ggA)?L1BRiNM6=&TpwMd4pJXs{?uH+ zdq>q=X;KmseG3R30Hr#ZApmWJUUBTK;-Er)!biBfS@60DsaKDuK``O}=f(R@;+JQGokD zkSaN&Hm4RrJYC#jQ-r|LhdI`7qcN-q(pl^mRApajC|t^aU0hx0>QxC9AVqKH97Q@b z{`r$Yv_=ZwWQE6dzIqFDY&CV$fh z0$^=7k+VYfD1b3i(B_n!fxfFv%GK=1Dv*mUID10J;Wu+}p{|mrujVs7+_SidywR`` z=(%FWcQd0>LY^-)G|%xm6E$aXFr4l*{W;7Q^d^=x%rkL#4gu7yN9636Zre3swQ-|b z$HALgg&P;ecCw_0(gnGFE_VcePfrR=GY+`W1Au#3DC%rm4K<6;1JzMx(+-Gck4wfIN@l9z5L+b z3_*KsA5MY%Y5-rmRe$V;nBoLT_hQp170YQQ^cwtKv|l@sz#s%PcLZ+6(F(LcpagWA zYo_h_CNuL;pj-?d6A>!XbMVI6I?cX#*@aP;2@)|{6OnZy zVeAB66jK1_%TQYqs~cH`Gm;S^&A+U8`t(%iu5N$-g9(lFOsmWgimpTQ~uJYq^kmF-R2<1rMOVe4@kWbgr1MGCfri!;Ey?Jc>vTOA)#6PQ9VxPTe z#$hP<@fSNOifAJPjXOUW#xYv^%qhzTqvN2+t>=3c7CGhXUnt=m|B?wN4pFgNdwCXx z7?0#sx!C~^cLg_KH?F$XhJ5ry+>ouFGQR0#tlOIb{=MB7HCF5D;^gTVM28_0967cE zzm+OmP$VA5)wXU=9FH;ZERR@*`Xv%ftZ&n&y=^v93ts&m*&79e5Yrf)Os9Vd9cL0T zYY?JQr~RXe7!c258>K6kthDwBzL$d$O3muL!t|SO6tM>MH!{z%<2)~605yG)110(R zdHKQ|H$$6{jbM{+>f}hnsjbf*EiL!|{^O^ulgg3i+Rpg^n2eXo@p&Cyr(LI+t$KB^ zG`+D~KJ^6A?{mIR<)44HwRjOaG6jEe=5W!IGTE}mJph_wz>o)q_qJmU$%-U?+H)*562127c@ z&;JWYs`A#yz@s z;8<4{bt|_Jm|-mpFhW&Aj?4AzQ#Y~Wyx!7FnV6+~%Hfs^2{Gh;SItWjz{p~;+=XJ<}$^V7C~n3^-SR z4@}Q4)n$Wm@$bmiiJuHnIjZjLJn;2s`_2&HKSWEa?N+K)oHk>$w0K5Y?J<)oB-^Re zC-S;%y=Ft^O-}lM*v(xWgF|N<21WuO>r?3YE&Gb_8O)8Affk<{Pv#<$6LB{ARRZzx zy~D@VSqBetSK}O&8H0vu82}2-2#Bkr(+1M_Mnxj=lmW@d=}z8tju~p3Z&irX)m$(0 zWKhX?@Gj?tE|Iy|Di0n_#;u(qUUy=KU>}|y+j!5@O=mL54&K-l(Bk1RRjF*m<&o*C zk@K1U^qF+8x=NExf$`l+8f9mcoL8$v@NoQD&fJ2t!hQ^nQ> zn_e_6ANgj?X}b-U^nmQoB9jvvL=-Be ze*92)3MQtbuZ4fT=dEzoy2ehDsQ+p3&BEBY-C5(GXl+EYP0sDnmnv$+%ojy~0XB`v zMG4C|<;Km$1A1UfLV|2X#L)MRs89HkNdp$(5ItNc2zB@Jy%6_>M584$e_%L`vB0=( zP9?Uyf_qzOm0T9H$rV3mWPw*d97~`L!bC0>D@08|hj4$-5JjVe9A*zakY=5e%ZVGq z#_rlM!DpM96JJaaU+99jtR~Uct1QpM&+OF<>Z;%s1cnk|OG@6H>`ALH{yIBJ&~A1qr?nsI1o zelar6O?7Vy3gAejr*SAgvle@$YyK)$#fiR z`P!VGqTL>)M7n6;?-%O{{Kg~5x@-wkd+7rA&L>wMDvq;Pz0ih4vy02tk^niwhtlS< zNz`Tc2Ux1|Q%Ttd{FolJqnX$E=1cYZQhHbdJyS@C>AIX|$LCnO%jVPOh#I~7Gj0NC zX~gJ3r=PX+yk+(^LP^5Ev#AP+N959$q9<|a-4~rC6H#fd+9|2l4w%o;GFLSD<*L*MYL?&e(bOluPX>HFQ=-1tO=O+l@W=Oc5& z@I*IHusNC-u+nYVF~4%VN_;o|_ull*^4F~}J{#`**;Wo&YR8T6F-E*I&g+iFw79)G zazx1y;&#Oz4m}WzUO!pU?Y!t0$12nFaFIR~iz`en5hz_3(%a-^KHJLkQnrWxf?gE3THwGnnHMvR|v!MS0)^L>$ literal 0 HcmV?d00001 From 12c626a614d7183786915381d47c6c744a5b7207 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 13:52:04 +0100 Subject: [PATCH 3/8] [ldap-user-sync] Fix CodeQL findings in vendored ldap3 Stop passing an explicit TLS version into ldap3's Tls() so it takes the hardened ssl.create_default_context() path (TLS 1.2+ floor) instead of a manual SSLContext with no such floor - this plugin's own choice was what triggered ldap3's py/insecure-protocol-flagged branch. Remove the lazily-imported, never-used ntlm.py (only reached via explicit NTLM bind, which this plugin never performs), and suppress the one unavoidable weak-hashing finding in digestMd5.py with an inline codeql[] comment plus an explanation: MD5 there implements the DIGEST-MD5 SASL mechanism's RFC 2831 challenge-response computation, not password storage, and the function is kept only because core/connection.py imports it unconditionally. --- plugins/ldap-user-sync/README.md | 28 +- plugins/ldap-user-sync/ldap_client.py | 7 +- .../vendor/ldap3/protocol/sasl/digestMd5.py | 9 +- .../ldap-user-sync/vendor/ldap3/utils/ntlm.py | 505 ------------------ 4 files changed, 36 insertions(+), 513 deletions(-) delete mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py diff --git a/plugins/ldap-user-sync/README.md b/plugins/ldap-user-sync/README.md index 0240339f..f4a0dac2 100644 --- a/plugins/ldap-user-sync/README.md +++ b/plugins/ldap-user-sync/README.md @@ -56,8 +56,8 @@ mirroring: Dispatcharr plugins run inside the app's existing Python environment with no dependency-installation step, and neither `ldap3` nor -`python-ldap` ships with Dispatcharr. This plugin vendors, unmodified, -as plain Python source under `vendor/`: +`python-ldap` ships with Dispatcharr. This plugin vendors, as plain +Python source under `vendor/`: - [`ldap3`](https://pypi.org/project/ldap3/) 2.9.1 — LGPL-3.0-only. Full license text: `vendor/licenses/ldap3/`. @@ -65,10 +65,26 @@ as plain Python source under `vendor/`: Full license text: `vendor/licenses/pyasn1/LICENSE.rst`. Both are pure Python with no compiled extensions. They are vendored as -clearly-separable, unmodified source trees with their original license -text preserved, satisfying LGPL's combination terms. This plugin's own -code is MIT-licensed; the vendored libraries keep their original -licenses regardless. +clearly-separable source trees with their original license text +preserved, satisfying LGPL's combination terms. This plugin's own code +is MIT-licensed; the vendored libraries keep their original licenses +regardless. + +Two small, deliberate deviations from the unmodified upstream `ldap3` +source, both driven by static-analysis findings against SASL/NTLM code +paths this plugin never exercises (it only ever performs SIMPLE bind): + +- `vendor/ldap3/utils/ntlm.py` is removed entirely. It's only reached + via a lazy `import` inside `Connection.do_ntlm_bind()`, which this + plugin never calls, so removing it doesn't affect SIMPLE-bind/search + functionality at all. +- `vendor/ldap3/protocol/sasl/digestMd5.py`'s `md5_h()` has an inline + `# codeql[py/weak-sensitive-data-hashing]` suppression comment. MD5 + there implements the DIGEST-MD5 SASL mechanism's RFC 2831 + challenge-response computation (mandated by the protocol spec, not a + password-storage weakness), and the function is kept only because + `core/connection.py` and the strategy modules import it + unconditionally — this plugin never selects DIGEST-MD5 authentication. ## Settings reference diff --git a/plugins/ldap-user-sync/ldap_client.py b/plugins/ldap-user-sync/ldap_client.py index 62c2e678..ace87067 100644 --- a/plugins/ldap-user-sync/ldap_client.py +++ b/plugins/ldap-user-sync/ldap_client.py @@ -50,9 +50,14 @@ def _build_server(settings): tls = None if encryption in ("starttls", "ldaps"): ca_pem = (settings.get("ldap_ca_cert_pem") or "").strip() or None + # Deliberately leave `version` unset (None): ldap3's Tls.wrap_socket() + # only calls Python's own ssl.create_default_context() - which + # enforces a TLS 1.2+ floor - when version is None. Passing an + # explicit version (e.g. PROTOCOL_TLS_CLIENT) makes it fall through + # to a manual SSLContext(self.version) path with no such floor, + # which is what CodeQL's py/insecure-protocol flags. tls = Tls( validate=ssl.CERT_REQUIRED, - version=ssl.PROTOCOL_TLS_CLIENT, ca_certs_data=ca_pem, ) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py index 9fa4ae82..99de4b56 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py @@ -39,7 +39,14 @@ def md5_h(value): if not isinstance(value, bytes): value = value.encode() - return hashlib.md5(value).digest() + # MD5 here implements the DIGEST-MD5 SASL mechanism's challenge-response + # computation per RFC 2831, not password storage/verification - the + # protocol itself mandates MD5, so this cannot be swapped for a stronger + # hash without breaking DIGEST-MD5 interoperability. The LDAP User Sync + # plugin never selects DIGEST-MD5 (SIMPLE bind only); this function is + # kept only because core/connection.py and the strategy modules import + # it unconditionally. + return hashlib.md5(value).digest() # codeql[py/weak-sensitive-data-hashing] def md5_kd(k, s): diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py b/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py deleted file mode 100644 index 78a4c19b..00000000 --- a/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py +++ /dev/null @@ -1,505 +0,0 @@ -""" -""" - -# Created on 2015.04.02 -# -# 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 . - -# NTLMv2 authentication as per [MS-NLMP] (https://msdn.microsoft.com/en-us/library/cc236621.aspx) - -from struct import pack, unpack -from platform import system, version -from socket import gethostname -from time import time -import hmac -import hashlib -import binascii -from os import urandom - -try: - from locale import getpreferredencoding - oem_encoding = getpreferredencoding() -except Exception: - oem_encoding = 'utf-8' - -from ..protocol.formatters.formatters import format_ad_timestamp - -NTLM_SIGNATURE = b'NTLMSSP\x00' -NTLM_MESSAGE_TYPE_NTLM_NEGOTIATE = 1 -NTLM_MESSAGE_TYPE_NTLM_CHALLENGE = 2 -NTLM_MESSAGE_TYPE_NTLM_AUTHENTICATE = 3 - -FLAG_NEGOTIATE_56 = 31 # W -FLAG_NEGOTIATE_KEY_EXCH = 30 # V -FLAG_NEGOTIATE_128 = 29 # U -FLAG_NEGOTIATE_VERSION = 25 # T -FLAG_NEGOTIATE_TARGET_INFO = 23 # S -FLAG_REQUEST_NOT_NT_SESSION_KEY = 22 # R -FLAG_NEGOTIATE_IDENTIFY = 20 # Q -FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY = 19 # P -FLAG_TARGET_TYPE_SERVER = 17 # O -FLAG_TARGET_TYPE_DOMAIN = 16 # N -FLAG_NEGOTIATE_ALWAYS_SIGN = 15 # M -FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 13 # L -FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 12 # K -FLAG_NEGOTIATE_ANONYMOUS = 11 # J -FLAG_NEGOTIATE_NTLM = 9 # H -FLAG_NEGOTIATE_LM_KEY = 7 # G -FLAG_NEGOTIATE_DATAGRAM = 6 # F -FLAG_NEGOTIATE_SEAL = 5 # E -FLAG_NEGOTIATE_SIGN = 4 # D -FLAG_REQUEST_TARGET = 2 # C -FLAG_NEGOTIATE_OEM = 1 # B -FLAG_NEGOTIATE_UNICODE = 0 # A - -FLAG_TYPES = [FLAG_NEGOTIATE_56, - FLAG_NEGOTIATE_KEY_EXCH, - FLAG_NEGOTIATE_128, - FLAG_NEGOTIATE_VERSION, - FLAG_NEGOTIATE_TARGET_INFO, - FLAG_REQUEST_NOT_NT_SESSION_KEY, - FLAG_NEGOTIATE_IDENTIFY, - FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY, - FLAG_TARGET_TYPE_SERVER, - FLAG_TARGET_TYPE_DOMAIN, - FLAG_NEGOTIATE_ALWAYS_SIGN, - FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, - FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED, - FLAG_NEGOTIATE_ANONYMOUS, - FLAG_NEGOTIATE_NTLM, - FLAG_NEGOTIATE_LM_KEY, - FLAG_NEGOTIATE_DATAGRAM, - FLAG_NEGOTIATE_SEAL, - FLAG_NEGOTIATE_SIGN, - FLAG_REQUEST_TARGET, - FLAG_NEGOTIATE_OEM, - FLAG_NEGOTIATE_UNICODE] - -AV_END_OF_LIST = 0 -AV_NETBIOS_COMPUTER_NAME = 1 -AV_NETBIOS_DOMAIN_NAME = 2 -AV_DNS_COMPUTER_NAME = 3 -AV_DNS_DOMAIN_NAME = 4 -AV_DNS_TREE_NAME = 5 -AV_FLAGS = 6 -AV_TIMESTAMP = 7 -AV_SINGLE_HOST_DATA = 8 -AV_TARGET_NAME = 9 -AV_CHANNEL_BINDINGS = 10 - -AV_TYPES = [AV_END_OF_LIST, - AV_NETBIOS_COMPUTER_NAME, - AV_NETBIOS_DOMAIN_NAME, - AV_DNS_COMPUTER_NAME, - AV_DNS_DOMAIN_NAME, - AV_DNS_TREE_NAME, - AV_FLAGS, - AV_TIMESTAMP, - AV_SINGLE_HOST_DATA, - AV_TARGET_NAME, - AV_CHANNEL_BINDINGS] - -AV_FLAG_CONSTRAINED = 0 -AV_FLAG_INTEGRITY = 1 -AV_FLAG_TARGET_SPN_UNTRUSTED = 2 - -AV_FLAG_TYPES = [AV_FLAG_CONSTRAINED, - AV_FLAG_INTEGRITY, - AV_FLAG_TARGET_SPN_UNTRUSTED] - - -def pack_windows_version(debug=False): - if debug: - if system().lower() == 'windows': - try: - major_release, minor_release, build = version().split('.') - major_release = int(major_release) - minor_release = int(minor_release) - build = int(build) - except Exception: - major_release = 5 - minor_release = 1 - build = 2600 - else: - major_release = 5 - minor_release = 1 - build = 2600 - else: - major_release = 0 - minor_release = 0 - build = 0 - - return pack(' Date: Sun, 2 Aug 2026 14:05:47 +0100 Subject: [PATCH 4/8] [ldap-user-sync] Actually eliminate remaining CodeQL findings The previous fix didn't hold: CodeQL's py/insecure-protocol query flags tls.py's own permissiveness (its SSLContext(self.version) branch enforces no minimum version by default) regardless of what any specific caller passes in, and the inline `codeql[]` suppression comment on digestMd5.py's md5_h() was not honored by this repo's SARIF-parsing report step. Fix both properly instead of relying on caller behavior or suppression: - tls.py: explicitly set minimum_version = TLSv1_2 on that branch, so the library itself can no longer negotiate an old protocol version. - digestMd5.py: stub md5_h/md5_kd/md5_hex/md5_hmac to raise NotImplementedError, removing every hashlib.md5 call from the file instead of just commenting around it. core/connection.py and the strategy modules still import these names fine; DIGEST-MD5 SASL auth (which is all that ever calls them) is simply unsupported by this vendored copy, matching the ntlm.py removal in the previous commit. --- plugins/ldap-user-sync/README.md | 28 +++++--- .../ldap-user-sync/vendor/ldap3/core/tls.py | 7 ++ .../vendor/ldap3/protocol/sasl/digestMd5.py | 68 +++++++------------ 3 files changed, 49 insertions(+), 54 deletions(-) diff --git a/plugins/ldap-user-sync/README.md b/plugins/ldap-user-sync/README.md index f4a0dac2..3c9f9132 100644 --- a/plugins/ldap-user-sync/README.md +++ b/plugins/ldap-user-sync/README.md @@ -70,21 +70,29 @@ preserved, satisfying LGPL's combination terms. This plugin's own code is MIT-licensed; the vendored libraries keep their original licenses regardless. -Two small, deliberate deviations from the unmodified upstream `ldap3` -source, both driven by static-analysis findings against SASL/NTLM code -paths this plugin never exercises (it only ever performs SIMPLE bind): +A few small, deliberate deviations from the unmodified upstream `ldap3` +source, all driven by static-analysis findings against SASL/NTLM/legacy-TLS +code paths this plugin never exercises (it only ever performs SIMPLE bind +over a TLS 1.2+ connection): - `vendor/ldap3/utils/ntlm.py` is removed entirely. It's only reached via a lazy `import` inside `Connection.do_ntlm_bind()`, which this plugin never calls, so removing it doesn't affect SIMPLE-bind/search functionality at all. -- `vendor/ldap3/protocol/sasl/digestMd5.py`'s `md5_h()` has an inline - `# codeql[py/weak-sensitive-data-hashing]` suppression comment. MD5 - there implements the DIGEST-MD5 SASL mechanism's RFC 2831 - challenge-response computation (mandated by the protocol spec, not a - password-storage weakness), and the function is kept only because - `core/connection.py` and the strategy modules import it - unconditionally — this plugin never selects DIGEST-MD5 authentication. +- `vendor/ldap3/protocol/sasl/digestMd5.py`'s `md5_h`/`md5_kd`/`md5_hex`/ + `md5_hmac` helpers are stubbed to raise `NotImplementedError` instead of + computing an RFC 2831 DIGEST-MD5 challenge-response with `hashlib.md5`. + `core/connection.py` and the strategy modules import this module's + names unconditionally, so the functions have to stay importable, but + this plugin never selects DIGEST-MD5 authentication, so the stub is + never reached in practice. +- `vendor/ldap3/core/tls.py`'s `Tls.wrap_socket()` explicitly sets + `ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2` on the + `SSLContext(self.version)` branch, which otherwise enforces no floor + of its own (unlike the `version=None` branch, which already goes + through Python's own `ssl.create_default_context()`). This plugin + never requests an old protocol version, but the library's own API + allowed one to be requested; this patch closes that off unconditionally. ## Settings reference diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py index ca8592b3..ac482912 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -180,6 +180,13 @@ def wrap_socket(self, connection, do_handshake=False): cadata=self.ca_certs_data) else: # code from create_default_context in the Python standard library 3.5.1, creates a ssl context with the specificd protocol version ssl_context = ssl.SSLContext(self.version) + # Unlike create_default_context() above, a bare SSLContext(version) + # enforces no minimum protocol version on its own - explicitly floor + # it at TLS 1.2 (LDAP User Sync plugin patch) so this branch can't be + # used to negotiate SSLv3/TLSv1/TLSv1.1 regardless of what `version` + # was requested. + if hasattr(ssl_context, "minimum_version") and hasattr(ssl, "TLSVersion"): + ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 if self.ca_certs_file or self.ca_certs_path or self.ca_certs_data: ssl_context.load_verify_locations(self.ca_certs_file, self.ca_certs_path, self.ca_certs_data) elif self.validate != ssl.CERT_NONE: diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py index 99de4b56..a76348a7 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py @@ -23,10 +23,6 @@ # along with ldap3 in the COPYING and COPYING.LESSER files. # If not, see . -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 @@ -34,46 +30,30 @@ STATE_KEY = 0 STATE_VALUE = 1 - -def md5_h(value): - if not isinstance(value, bytes): - value = value.encode() - - # MD5 here implements the DIGEST-MD5 SASL mechanism's challenge-response - # computation per RFC 2831, not password storage/verification - the - # protocol itself mandates MD5, so this cannot be swapped for a stronger - # hash without breaking DIGEST-MD5 interoperability. The LDAP User Sync - # plugin never selects DIGEST-MD5 (SIMPLE bind only); this function is - # kept only because core/connection.py and the strategy modules import - # it unconditionally. - return hashlib.md5(value).digest() # codeql[py/weak-sensitive-data-hashing] - - -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() +# The LDAP User Sync plugin only ever performs SIMPLE bind - it never +# selects DIGEST-MD5 SASL authentication. core/connection.py and the +# strategy modules import this module's names unconditionally though, so +# it must stay importable. Rather than keep the actual RFC 2831 +# challenge-response implementation (which necessarily calls hashlib.md5 +# on password-derived material - CodeQL's py/weak-sensitive-data-hashing +# flags this as insecure password hashing even though it's a +# protocol-mandated keyed digest, not credential storage), these helpers +# are stubbed out: calling them raises NotImplementedError instead of +# silently doing the wrong thing, since this vendored copy is not meant +# to support DIGEST-MD5. + + +def _digest_md5_unsupported(*_args, **_kwargs): + raise NotImplementedError( + "DIGEST-MD5 SASL authentication is not supported by this vendored " + "ldap3 copy (LDAP User Sync plugin only uses SIMPLE bind)." + ) + + +md5_h = _digest_md5_unsupported +md5_kd = _digest_md5_unsupported +md5_hex = _digest_md5_unsupported +md5_hmac = _digest_md5_unsupported def sasl_digest_md5(connection, controls): From 4722aad1e5f39efacd2d720687da2690ad4e65e2 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 14:16:45 +0100 Subject: [PATCH 5/8] [ldap-user-sync] Reject insecure TLS protocol versions at the source The previous minimum_version fix ran too late: SSLContext(self.version) can pin the context to a single legacy protocol before that line ever executes, so setting minimum_version afterward doesn't undo it - CodeQL correctly kept flagging this as reachable. Validate `version` in Tls.__init__ instead and raise LDAPSSLConfigurationError for any SSLv2/SSLv3/TLSv1/TLSv1.1/SSLv23 constant, checked defensively via hasattr since several no longer exist on newer Python. This plugin never passes an explicit version at all (defaults to None, i.e. ssl.create_default_context()), so this only ever closes off a capability nothing here uses. Keeps the earlier minimum_version assignment as defense in depth. --- plugins/ldap-user-sync/vendor/ldap3/core/tls.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py index ac482912..95828a05 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -54,6 +54,18 @@ from os import path +# LDAP User Sync plugin patch: block insecure protocol versions outright +# rather than relying on ssl.SSLContext(self.version) to make them safe +# after the fact - some of these constants pin the context to that single +# legacy protocol, which a later minimum_version assignment can't undo. +# Checked defensively since several of these names no longer exist on +# newer Python (they were removed from the ssl module entirely). +_INSECURE_TLS_PROTOCOL_VALUES = { + getattr(ssl, name) + for name in ('PROTOCOL_SSLv2', 'PROTOCOL_SSLv3', 'PROTOCOL_TLSv1', 'PROTOCOL_TLSv1_1', 'PROTOCOL_SSLv23') + if hasattr(ssl, name) +} + # noinspection PyProtectedMember class Tls(object): @@ -129,6 +141,10 @@ def __init__(self, else: self.private_key_password = None + if version is not None and version in _INSECURE_TLS_PROTOCOL_VALUES: + if log_enabled(ERROR): + log(ERROR, 'insecure TLS/SSL protocol version requested') + raise LDAPSSLConfigurationError('insecure TLS/SSL protocol version requested; use TLS 1.2 or newer') self.version = version self.private_key_file = local_private_key_file self.certificate_file = local_certificate_file From c128fb87a5ab7447965eddb0ddff61e304ee6d44 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 15:24:55 +0100 Subject: [PATCH 6/8] [ldap-user-sync] Remove the SSLContext(version) branch entirely Third attempt at the same finding: CodeQL's py/insecure-protocol flags the mere existence of ssl.SSLContext(self.version) feeding a wrap_socket() call, regardless of runtime validation on `version` (the previous commit's __init__ guard didn't change the result). Delete that branch outright and always build the context via create_default_context() (TLS 1.2+ floor, verified certs) - this plugin never passes an explicit `version` at all, so nothing depends on the removed path. --- .../ldap-user-sync/vendor/ldap3/core/tls.py | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py index 95828a05..078cfe51 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -189,24 +189,19 @@ def wrap_socket(self, connection, do_handshake=False): Adds TLS to the connection socket """ if use_ssl_context: - if self.version is None: # uses the default ssl context for reasonable security - ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH, - cafile=self.ca_certs_file, - capath=self.ca_certs_path, - cadata=self.ca_certs_data) - else: # code from create_default_context in the Python standard library 3.5.1, creates a ssl context with the specificd protocol version - ssl_context = ssl.SSLContext(self.version) - # Unlike create_default_context() above, a bare SSLContext(version) - # enforces no minimum protocol version on its own - explicitly floor - # it at TLS 1.2 (LDAP User Sync plugin patch) so this branch can't be - # used to negotiate SSLv3/TLSv1/TLSv1.1 regardless of what `version` - # was requested. - if hasattr(ssl_context, "minimum_version") and hasattr(ssl, "TLSVersion"): - ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 - if self.ca_certs_file or self.ca_certs_path or self.ca_certs_data: - ssl_context.load_verify_locations(self.ca_certs_file, self.ca_certs_path, self.ca_certs_data) - elif self.validate != ssl.CERT_NONE: - ssl_context.load_default_certs(Purpose.SERVER_AUTH) + # LDAP User Sync plugin patch: always build the SSLContext via + # create_default_context() (TLS 1.2+ floor, verified certs), + # never via a bare SSLContext(self.version). CodeQL's + # py/insecure-protocol flags the latter's mere existence in the + # file regardless of what `version` was already validated to be + # in __init__ above (which now rejects every legacy SSL/TLS + # constant outright). This plugin never passes an explicit + # `version` at all, so nothing here depends on the removed + # branch - `self.version` is only ever None in practice. + ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH, + cafile=self.ca_certs_file, + capath=self.ca_certs_path, + cadata=self.ca_certs_data) if self.certificate_file: ssl_context.load_cert_chain(self.certificate_file, keyfile=self.private_key_file, password=self.private_key_password) From 6fe25195d4b75e64d3247fde7f48c691cb6921d9 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sun, 2 Aug 2026 15:50:55 +0100 Subject: [PATCH 7/8] [ldap-user-sync] Explicitly floor create_default_context() at TLS 1.2 CodeQL's py/insecure-protocol treats create_default_context() itself as not guaranteed to exclude TLSv1/TLSv1.1 unless the returned context also has minimum_version set explicitly - the previous commit removed the custom-version branch but didn't set this on the remaining create_default_context() path. Add it there too. --- plugins/ldap-user-sync/vendor/ldap3/core/tls.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py index 078cfe51..0b234cdf 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -202,6 +202,12 @@ def wrap_socket(self, connection, do_handshake=False): cafile=self.ca_certs_file, capath=self.ca_certs_path, cadata=self.ca_certs_data) + # CodeQL's py/insecure-protocol models create_default_context() + # as not guaranteed to exclude TLSv1/TLSv1.1 on its own - set an + # explicit floor on the returned context too, not just on the + # now-removed custom-version branch. + if hasattr(ssl_context, "minimum_version") and hasattr(ssl, "TLSVersion"): + ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 if self.certificate_file: ssl_context.load_cert_chain(self.certificate_file, keyfile=self.private_key_file, password=self.private_key_password) From bc1e176cecaba88a22a49e8e3827e2e60fc71b6e Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Mon, 3 Aug 2026 15:49:29 +0100 Subject: [PATCH 8/8] [ldap-user-sync] Revert to unmodified vendored ldap3, use codeql[] comments A maintainer pointed out the inline suppression comment needs to be on its own line above the flagged statement, not a trailing same-line comment - that's why it wasn't honored before. Revert all of the previous commits' vendored-source modifications (ntlm.py deletion, digestMd5.py stubbing, tls.py SSLContext rewrite) back to byte-identical upstream, and instead annotate the actual flagged lines in place with correctly-formatted `codeql[]` comments plus an explanation of why each is a protocol-mandated construct this plugin never exercises (SIMPLE bind only, no DIGEST-MD5/NTLM, no explicit TLS version). --- plugins/ldap-user-sync/README.md | 44 +- .../ldap-user-sync/vendor/ldap3/core/tls.py | 53 +- .../vendor/ldap3/protocol/sasl/digestMd5.py | 68 ++- .../ldap-user-sync/vendor/ldap3/utils/ntlm.py | 515 ++++++++++++++++++ 4 files changed, 592 insertions(+), 88 deletions(-) create mode 100644 plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py diff --git a/plugins/ldap-user-sync/README.md b/plugins/ldap-user-sync/README.md index 3c9f9132..f096bac4 100644 --- a/plugins/ldap-user-sync/README.md +++ b/plugins/ldap-user-sync/README.md @@ -64,35 +64,21 @@ Python source under `vendor/`: - [`pyasn1`](https://pypi.org/project/pyasn1/) 0.6.4 — BSD-2-Clause. Full license text: `vendor/licenses/pyasn1/LICENSE.rst`. -Both are pure Python with no compiled extensions. They are vendored as -clearly-separable source trees with their original license text -preserved, satisfying LGPL's combination terms. This plugin's own code -is MIT-licensed; the vendored libraries keep their original licenses -regardless. - -A few small, deliberate deviations from the unmodified upstream `ldap3` -source, all driven by static-analysis findings against SASL/NTLM/legacy-TLS -code paths this plugin never exercises (it only ever performs SIMPLE bind -over a TLS 1.2+ connection): - -- `vendor/ldap3/utils/ntlm.py` is removed entirely. It's only reached - via a lazy `import` inside `Connection.do_ntlm_bind()`, which this - plugin never calls, so removing it doesn't affect SIMPLE-bind/search - functionality at all. -- `vendor/ldap3/protocol/sasl/digestMd5.py`'s `md5_h`/`md5_kd`/`md5_hex`/ - `md5_hmac` helpers are stubbed to raise `NotImplementedError` instead of - computing an RFC 2831 DIGEST-MD5 challenge-response with `hashlib.md5`. - `core/connection.py` and the strategy modules import this module's - names unconditionally, so the functions have to stay importable, but - this plugin never selects DIGEST-MD5 authentication, so the stub is - never reached in practice. -- `vendor/ldap3/core/tls.py`'s `Tls.wrap_socket()` explicitly sets - `ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2` on the - `SSLContext(self.version)` branch, which otherwise enforces no floor - of its own (unlike the `version=None` branch, which already goes - through Python's own `ssl.create_default_context()`). This plugin - never requests an old protocol version, but the library's own API - allowed one to be requested; this patch closes that off unconditionally. +Both are pure Python with no compiled extensions. They are vendored +unmodified as clearly-separable source trees with their original +license text preserved, satisfying LGPL's combination terms. This +plugin's own code is MIT-licensed; the vendored libraries keep their +original licenses regardless. + +CodeQL (which scans this vendored source like any other Python in the +PR) flags a handful of lines in `ldap3`'s optional DIGEST-MD5/NTLM SASL +mechanisms and TLS-version handling — code this plugin never exercises, +since it only ever performs a SIMPLE bind over a connection whose TLS +version is never explicitly set (so it always goes through +`ssl.create_default_context()`'s TLS 1.2+ floor). Those specific lines +carry inline `codeql[]` suppression comments with an +explanation of why each is a protocol-mandated construct rather than a +real weakness, rather than modifying the vendored source itself. ## Settings reference diff --git a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py index 0b234cdf..a205d35a 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/core/tls.py +++ b/plugins/ldap-user-sync/vendor/ldap3/core/tls.py @@ -54,18 +54,6 @@ from os import path -# LDAP User Sync plugin patch: block insecure protocol versions outright -# rather than relying on ssl.SSLContext(self.version) to make them safe -# after the fact - some of these constants pin the context to that single -# legacy protocol, which a later minimum_version assignment can't undo. -# Checked defensively since several of these names no longer exist on -# newer Python (they were removed from the ssl module entirely). -_INSECURE_TLS_PROTOCOL_VALUES = { - getattr(ssl, name) - for name in ('PROTOCOL_SSLv2', 'PROTOCOL_SSLv3', 'PROTOCOL_TLSv1', 'PROTOCOL_TLSv1_1', 'PROTOCOL_SSLv23') - if hasattr(ssl, name) -} - # noinspection PyProtectedMember class Tls(object): @@ -141,10 +129,6 @@ def __init__(self, else: self.private_key_password = None - if version is not None and version in _INSECURE_TLS_PROTOCOL_VALUES: - if log_enabled(ERROR): - log(ERROR, 'insecure TLS/SSL protocol version requested') - raise LDAPSSLConfigurationError('insecure TLS/SSL protocol version requested; use TLS 1.2 or newer') self.version = version self.private_key_file = local_private_key_file self.certificate_file = local_certificate_file @@ -189,25 +173,17 @@ def wrap_socket(self, connection, do_handshake=False): Adds TLS to the connection socket """ if use_ssl_context: - # LDAP User Sync plugin patch: always build the SSLContext via - # create_default_context() (TLS 1.2+ floor, verified certs), - # never via a bare SSLContext(self.version). CodeQL's - # py/insecure-protocol flags the latter's mere existence in the - # file regardless of what `version` was already validated to be - # in __init__ above (which now rejects every legacy SSL/TLS - # constant outright). This plugin never passes an explicit - # `version` at all, so nothing here depends on the removed - # branch - `self.version` is only ever None in practice. - ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH, - cafile=self.ca_certs_file, - capath=self.ca_certs_path, - cadata=self.ca_certs_data) - # CodeQL's py/insecure-protocol models create_default_context() - # as not guaranteed to exclude TLSv1/TLSv1.1 on its own - set an - # explicit floor on the returned context too, not just on the - # now-removed custom-version branch. - if hasattr(ssl_context, "minimum_version") and hasattr(ssl, "TLSVersion"): - ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 + if self.version is None: # uses the default ssl context for reasonable security + ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH, + cafile=self.ca_certs_file, + capath=self.ca_certs_path, + cadata=self.ca_certs_data) + else: # code from create_default_context in the Python standard library 3.5.1, creates a ssl context with the specificd protocol version + ssl_context = ssl.SSLContext(self.version) + if self.ca_certs_file or self.ca_certs_path or self.ca_certs_data: + ssl_context.load_verify_locations(self.ca_certs_file, self.ca_certs_path, self.ca_certs_data) + elif self.validate != ssl.CERT_NONE: + ssl_context.load_default_certs(Purpose.SERVER_AUTH) if self.certificate_file: ssl_context.load_cert_chain(self.certificate_file, keyfile=self.private_key_file, password=self.private_key_password) @@ -222,9 +198,16 @@ def wrap_socket(self, connection, do_handshake=False): except ssl.SSLError: pass + # This plugin never passes an explicit `version` to Tls(), so + # `ssl_context` here always comes from the version-is-None + # branch above (ssl.create_default_context(), which already + # enforces a TLS 1.2+ floor) - it never reaches this call via + # the caller-suppliable-version branch. if self.sni: + # codeql[py/insecure-protocol] wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake, server_hostname=self.sni) else: + # codeql[py/insecure-protocol] wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake) if log_enabled(NETWORK): log(NETWORK, 'socket wrapped with SSL using SSLContext for <%s>', connection) diff --git a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py index a76348a7..0f1798dd 100644 --- a/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py +++ b/plugins/ldap-user-sync/vendor/ldap3/protocol/sasl/digestMd5.py @@ -23,6 +23,10 @@ # along with ldap3 in the COPYING and COPYING.LESSER files. # If not, see . +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 @@ -30,30 +34,46 @@ STATE_KEY = 0 STATE_VALUE = 1 -# The LDAP User Sync plugin only ever performs SIMPLE bind - it never -# selects DIGEST-MD5 SASL authentication. core/connection.py and the -# strategy modules import this module's names unconditionally though, so -# it must stay importable. Rather than keep the actual RFC 2831 -# challenge-response implementation (which necessarily calls hashlib.md5 -# on password-derived material - CodeQL's py/weak-sensitive-data-hashing -# flags this as insecure password hashing even though it's a -# protocol-mandated keyed digest, not credential storage), these helpers -# are stubbed out: calling them raises NotImplementedError instead of -# silently doing the wrong thing, since this vendored copy is not meant -# to support DIGEST-MD5. - - -def _digest_md5_unsupported(*_args, **_kwargs): - raise NotImplementedError( - "DIGEST-MD5 SASL authentication is not supported by this vendored " - "ldap3 copy (LDAP User Sync plugin only uses SIMPLE bind)." - ) - - -md5_h = _digest_md5_unsupported -md5_kd = _digest_md5_unsupported -md5_hex = _digest_md5_unsupported -md5_hmac = _digest_md5_unsupported + +def md5_h(value): + if not isinstance(value, bytes): + value = value.encode() + + # MD5 here implements the DIGEST-MD5 SASL mechanism's RFC 2831 + # challenge-response computation, not password storage/verification - + # the protocol itself mandates MD5. The LDAP User Sync plugin never + # selects DIGEST-MD5 (SIMPLE bind only); this function is kept only + # because core/connection.py and the strategy modules import it + # unconditionally. + # codeql[py/weak-sensitive-data-hashing] + 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): diff --git a/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py b/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py new file mode 100644 index 00000000..6b35fd2e --- /dev/null +++ b/plugins/ldap-user-sync/vendor/ldap3/utils/ntlm.py @@ -0,0 +1,515 @@ +""" +""" + +# Created on 2015.04.02 +# +# 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 . + +# NTLMv2 authentication as per [MS-NLMP] (https://msdn.microsoft.com/en-us/library/cc236621.aspx) + +from struct import pack, unpack +from platform import system, version +from socket import gethostname +from time import time +import hmac +import hashlib +import binascii +from os import urandom + +try: + from locale import getpreferredencoding + oem_encoding = getpreferredencoding() +except Exception: + oem_encoding = 'utf-8' + +from ..protocol.formatters.formatters import format_ad_timestamp + +NTLM_SIGNATURE = b'NTLMSSP\x00' +NTLM_MESSAGE_TYPE_NTLM_NEGOTIATE = 1 +NTLM_MESSAGE_TYPE_NTLM_CHALLENGE = 2 +NTLM_MESSAGE_TYPE_NTLM_AUTHENTICATE = 3 + +FLAG_NEGOTIATE_56 = 31 # W +FLAG_NEGOTIATE_KEY_EXCH = 30 # V +FLAG_NEGOTIATE_128 = 29 # U +FLAG_NEGOTIATE_VERSION = 25 # T +FLAG_NEGOTIATE_TARGET_INFO = 23 # S +FLAG_REQUEST_NOT_NT_SESSION_KEY = 22 # R +FLAG_NEGOTIATE_IDENTIFY = 20 # Q +FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY = 19 # P +FLAG_TARGET_TYPE_SERVER = 17 # O +FLAG_TARGET_TYPE_DOMAIN = 16 # N +FLAG_NEGOTIATE_ALWAYS_SIGN = 15 # M +FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 13 # L +FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 12 # K +FLAG_NEGOTIATE_ANONYMOUS = 11 # J +FLAG_NEGOTIATE_NTLM = 9 # H +FLAG_NEGOTIATE_LM_KEY = 7 # G +FLAG_NEGOTIATE_DATAGRAM = 6 # F +FLAG_NEGOTIATE_SEAL = 5 # E +FLAG_NEGOTIATE_SIGN = 4 # D +FLAG_REQUEST_TARGET = 2 # C +FLAG_NEGOTIATE_OEM = 1 # B +FLAG_NEGOTIATE_UNICODE = 0 # A + +FLAG_TYPES = [FLAG_NEGOTIATE_56, + FLAG_NEGOTIATE_KEY_EXCH, + FLAG_NEGOTIATE_128, + FLAG_NEGOTIATE_VERSION, + FLAG_NEGOTIATE_TARGET_INFO, + FLAG_REQUEST_NOT_NT_SESSION_KEY, + FLAG_NEGOTIATE_IDENTIFY, + FLAG_NEGOTIATE_EXTENDED_SESSIONSECURITY, + FLAG_TARGET_TYPE_SERVER, + FLAG_TARGET_TYPE_DOMAIN, + FLAG_NEGOTIATE_ALWAYS_SIGN, + FLAG_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, + FLAG_NEGOTIATE_OEM_DOMAIN_SUPPLIED, + FLAG_NEGOTIATE_ANONYMOUS, + FLAG_NEGOTIATE_NTLM, + FLAG_NEGOTIATE_LM_KEY, + FLAG_NEGOTIATE_DATAGRAM, + FLAG_NEGOTIATE_SEAL, + FLAG_NEGOTIATE_SIGN, + FLAG_REQUEST_TARGET, + FLAG_NEGOTIATE_OEM, + FLAG_NEGOTIATE_UNICODE] + +AV_END_OF_LIST = 0 +AV_NETBIOS_COMPUTER_NAME = 1 +AV_NETBIOS_DOMAIN_NAME = 2 +AV_DNS_COMPUTER_NAME = 3 +AV_DNS_DOMAIN_NAME = 4 +AV_DNS_TREE_NAME = 5 +AV_FLAGS = 6 +AV_TIMESTAMP = 7 +AV_SINGLE_HOST_DATA = 8 +AV_TARGET_NAME = 9 +AV_CHANNEL_BINDINGS = 10 + +AV_TYPES = [AV_END_OF_LIST, + AV_NETBIOS_COMPUTER_NAME, + AV_NETBIOS_DOMAIN_NAME, + AV_DNS_COMPUTER_NAME, + AV_DNS_DOMAIN_NAME, + AV_DNS_TREE_NAME, + AV_FLAGS, + AV_TIMESTAMP, + AV_SINGLE_HOST_DATA, + AV_TARGET_NAME, + AV_CHANNEL_BINDINGS] + +AV_FLAG_CONSTRAINED = 0 +AV_FLAG_INTEGRITY = 1 +AV_FLAG_TARGET_SPN_UNTRUSTED = 2 + +AV_FLAG_TYPES = [AV_FLAG_CONSTRAINED, + AV_FLAG_INTEGRITY, + AV_FLAG_TARGET_SPN_UNTRUSTED] + + +def pack_windows_version(debug=False): + if debug: + if system().lower() == 'windows': + try: + major_release, minor_release, build = version().split('.') + major_release = int(major_release) + minor_release = int(minor_release) + build = int(build) + except Exception: + major_release = 5 + minor_release = 1 + build = 2600 + else: + major_release = 5 + minor_release = 1 + build = 2600 + else: + major_release = 0 + minor_release = 0 + build = 0 + + return pack('