web2ldap  1.7.7
About: web2ldap is a full-featured web-based LDAPv3 client.
  Fossies Dox: web2ldap-1.7.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

quirks.py
Go to the documentation of this file.
1# -*- coding: ascii -*-
2"""
3Special syntax and attribute type registrations for enforcing
4standard-compliant behaviour even if current subschema of
5a server is erroneous or could not be retrieved.
6"""
7
8import ldap0.ldapurl
9
10from ..searchform import SEARCH_SCOPE_STR_ONELEVEL
11from ..schema.syntaxes import (
12 syntax_registry,
13 Audio,
14 AuthzDN,
15 Binary,
16 Boolean,
17 CountryString,
18 DirectoryString,
19 DistinguishedName,
20 DomainComponent,
21 Integer,
22 JPEGImage,
23 LDAPUrl,
24 OctetString,
25 OID,
26 PhotoG3Fax,
27 PostalAddress,
28 RFC822Address,
29 Uri,
30 UTCTime,
31 ObjectClassDescription,
32 AttributeTypeDescription,
33 MatchingRuleDescription,
34 MatchingRuleUseDescription,
35 LDAPSyntaxDescription,
36 DITContentRuleDescription,
37 DITStructureRuleDescription,
38 NameFormDescription,
39)
40
41
42syntax_registry.reg_at(
43 ObjectClassDescription.oid,
44 [
45 '2.5.21.6', 'objectClasses',
46 ]
47)
48
49syntax_registry.reg_at(
50 AttributeTypeDescription.oid,
51 [
52 '2.5.21.5', 'attributeTypes',
53 ]
54)
55
56syntax_registry.reg_at(
57 MatchingRuleDescription.oid,
58 [
59 '2.5.21.4', 'matchingRules',
60 ]
61)
62
63syntax_registry.reg_at(
64 MatchingRuleUseDescription.oid,
65 [
66 '2.5.21.8', 'matchingRuleUse',
67 ]
68)
69
70syntax_registry.reg_at(
71 LDAPSyntaxDescription.oid,
72 [
73 '1.3.6.1.4.1.1466.101.120.16', 'ldapSyntaxes',
74 ]
75)
76
77syntax_registry.reg_at(
78 DITContentRuleDescription.oid,
79 [
80 '2.5.21.2', 'dITContentRules',
81 ]
82)
83
84syntax_registry.reg_at(
85 DITStructureRuleDescription.oid,
86 [
87 '2.5.21.1', 'dITStructureRules',
88 ]
89)
90
91syntax_registry.reg_at(
92 NameFormDescription.oid,
93 [
94 '2.5.21.7', 'nameForms',
95 ]
96)
97
98syntax_registry.reg_at(
99 OID.oid,
100 [
101 '1.2.826.0.1050.11.0', 'ogSupportedProfile',
102 '1.3.6.1.4.1.1466.101.120.13', 'supportedControl',
103 '1.3.6.1.4.1.1466.101.120.7', 'supportedExtension',
104 '1.3.6.1.4.1.4203.1.3.5', 'supportedFeatures',
105 'supportedCapabilities',
106 ]
107)
108
109syntax_registry.reg_at(
110 RFC822Address.oid,
111 [
112 '0.9.2342.19200300.100.1.3', # mail, rfc822Mailbox
113 '2.16.840.1.113730.3.1.13', # mailLocalAddress
114 '2.16.840.1.113730.3.1.17', # mailForwardingAddress
115 '2.16.840.1.113730.3.1.30', # mgrpRFC822MailMember
116 '1.3.6.1.4.1.42.2.27.2.1.15', # rfc822MailMember
117 '2.16.840.1.113730.3.1.47', # mailRoutingAddress
118 '1.2.840.113549.1.9.1', # email, emailAddress, pkcs9email
119 ]
120)
121
122syntax_registry.reg_at(
123 DirectoryString.oid, [
124 'supportedSASLMechanisms',
125 ]
126)
127
128syntax_registry.reg_at(
129 Integer.oid, [
130 'supportedLDAPVersion ',
131 ]
132)
133
134syntax_registry.reg_at(
135 JPEGImage.oid,
136 [
137 '0.9.2342.19200300.100.1.60', # jpegPhoto
138 ]
139)
140
141syntax_registry.reg_at(
142 Audio.oid,
143 [
144 '0.9.2342.19200300.100.1.55', # audio
145 ]
146)
147
148syntax_registry.reg_at(
149 PhotoG3Fax.oid,
150 [
151 '0.9.2342.19200300.100.1.7', # photo
152 ]
153)
154
155syntax_registry.reg_at(
156 Uri.oid, [
157 '1.3.6.1.4.1.250.1.57', # labeledURI
158 ]
159)
160
161syntax_registry.reg_at(
162 Boolean.oid, [
163 '2.5.18.9', # hasSubordinates
164 ]
165)
166
167syntax_registry.reg_at(
168 PostalAddress.oid, [
169 '2.5.4.16', # postalAddress
170 '2.5.4.26', # registeredAddress
171 '0.9.2342.19200300.100.1.39', # homePostalAddress
172 ]
173)
174
175syntax_registry.reg_at(
176 LDAPUrl.oid, [
177 '2.16.840.1.113730.3.1.34', # ref
178 ]
179)
180
181syntax_registry.reg_at(
182 UTCTime.oid, [
183 '2.5.18.1', # createTimestamp
184 '2.5.18.2', # modifyTimestamp
185 'createtimestamp-oid', # createtimestamp on Netscape DS 4.x
186 'modifytimestamp-oid', # modifytimestamp on Netscape DS 4.x
187 ]
188)
189
190syntax_registry.reg_at(
191 CountryString.oid, [
192 'c',
193 'countryName',
194 '2.5.4.6', # c
195 ]
196)
197
198# Some LDAP servers (e.g. MS AD) declare these attributes with OctetString
199# syntax but Binary syntax is more suitable
200syntax_registry.reg_at(
201 Binary.oid, [
202 '2.16.840.1.113730.3.1.216', # userPKCS12
203 '2.16.840.1.113730.3.140', # userSMIMECertificate
204 ]
205)
206
207syntax_registry.reg_at(
208 AuthzDN.oid, [
209 '2.5.18.3', # creatorsName
210 '2.5.18.4', # modifiersName
211 ]
212)
213
214syntax_registry.reg_at(
215 DomainComponent.oid, [
216 '0.9.2342.19200300.100.1.25', # dc (alias domainComponent)
217 'dc',
218 'domainComponent',
219 ]
220)
221
222
224 """
225 Attribute userPassword can be textual or arbitrary octet strings.
226 This plugin displays textual passwords as readable text.
227 """
228 oid: str = 'UserPassword-oid'
229
230 def display(self, vidx, links) -> str:
231 try:
232 result = DirectoryString.display(self, vidx, links)
233 except UnicodeDecodeError:
234 result = OctetString.display(self, vidx, links)
235 return result
236
237syntax_registry.reg_at(
238 UserPassword.oid, [
239 '2.5.4.35', # userPassword
240 ]
241)
242
243
245 """
246 Plugin class for attribute namingContexts present in rootDSE
247 https://datatracker.ietf.org/doc/html/rfc4512#section-5.1.2
248 """
249 oid: str = 'NamingContexts-oid'
250 desc: str = 'Naming contexts in rootDSE'
251 ldap_url = 'ldap:///cn=cn=config?olcSuffix?one?(objectClass=olcDatabaseConfig)'
252
253 def _config_link(self):
254 config_context = None
255 config_scope_str = None
256 config_filter = None
257 # Check for OpenLDAP's config context attribute
258 try:
259 config_context = self._app.ls.uc_decode(self._app.ls.root_dse['configContext'][0])[0]
260 except KeyError:
261 # Check for OpenDJ's config context attribute
262 try:
263 _ = self._app.ls.root_dse['ds-private-naming-contexts']
264 except KeyError:
265 pass
266 else:
267 config_context = 'cn=Backends,cn=config'
268 config_filter = '(&(objectClass=ds-cfg-backend)(ds-cfg-base-dn=%s))' % (self.av_u)
269 config_scope_str = SEARCH_SCOPE_STR_ONELEVEL
270 else:
271 config_filter = '(&(objectClass=olcDatabaseConfig)(olcSuffix=%s))' % (self.av_u)
272 config_scope_str = SEARCH_SCOPE_STR_ONELEVEL
273 if config_context and config_scope_str and config_filter:
274 return self._app.anchor(
275 'search', 'Config',
276 (
277 ('dn', config_context),
278 ('scope', config_scope_str),
279 ('filterstr', config_filter),
280 ),
281 title='Search for configuration entry below %s' % (config_context),
282 )
283 return None
284
285 def _monitor_link(self):
286 monitor_context = None
287 monitor_scope_str = None
288 monitor_filter = None
289 # Check for OpenLDAP's config context attribute
290 try:
291 _ = self._app.ls.root_dse['monitorContext']
292 except KeyError:
293 # Check for OpenDJ's config context attribute
294 try:
295 _ = self._app.ls.root_dse['ds-private-naming-contexts']
296 except KeyError:
297 pass
298 else:
299 monitor_context = 'cn=monitor'
300 monitor_filter = (
301 '(&'
302 '(objectClass=ds-backend-monitor-entry)'
303 '(ds-backend-base-dn=%s)'
304 ')'
305 ) % (
306 self.av_u
307 )
308 monitor_scope_str = SEARCH_SCOPE_STR_ONELEVEL
309 else:
310 monitor_context = 'cn=Databases,cn=Monitor'
311 monitor_filter = '(&(objectClass=monitoredObject)(namingContexts=%s))' % (self.av_u)
312 monitor_scope_str = SEARCH_SCOPE_STR_ONELEVEL
313 if monitor_context and monitor_scope_str and monitor_filter:
314 return self._app.anchor(
315 'search', 'Monitor',
316 (
317 ('dn', monitor_context),
318 ('scope', monitor_scope_str),
319 ('filterstr', monitor_filter),
320 ),
321 title='Search for monitoring entry below %s' % (monitor_context),
322 )
323 return None
324
326 res = DistinguishedName._additional_links(self)
327 res.append(self._app.anchor(
328 'search', 'Down',
329 (
330 ('dn', self.av_u),
331 ('scope', SEARCH_SCOPE_STR_ONELEVEL),
332 ('filterstr', '(objectClass=*)'),
333 )
334 ))
335 res.append(self._app.anchor(
336 'dit', 'Tree',
337 (('dn', self.av_u),),
338 ))
339 config_link = self._config_link()
340 if config_link:
341 res.append(config_link)
342 monitor_link = self._monitor_link()
343 if monitor_link:
344 res.append(monitor_link)
345 return res
346
347syntax_registry.reg_at(
348 NamingContexts.oid, [
349 'namingContexts',
350 '1.3.6.1.4.1.1466.101.120.5', # namingContexts
351 ]
352)
353
354
356 """
357 Plugin class for attribute altServer optionally present in rootDSE
358 https://datatracker.ietf.org/doc/html/rfc4512#section-5.1.1
359 """
360 oid: str = 'AltServer-oid'
361 desc: str = 'LDAP URIs of alternative server(s)'
362
363 def _command_ldap_url(self, ldap_url):
364 ldap_url_obj = ldap0.ldapurl.LDAPUrl(ldapUrl=ldap_url)
365 ldap_url_obj.who = self._app.ls.who
366 ldap_url_obj.scope = ldap0.ldapurl.LDAP_SCOPE_BASE
367 ldap_url_obj.cred = None
368 return ldap_url_obj
369
370syntax_registry.reg_at(
371 AltServer.oid, [
372 'altServer',
373 '1.3.6.1.4.1.1466.101.120.6', # altServer
374 ]
375)
376
377
378# Register all syntax classes in this module
379syntax_registry.reg_syntaxes(__name__)
def _command_ldap_url(self, ldap_url)
Definition: quirks.py:363
str display(self, vidx, links)
Definition: quirks.py:230