0
# Configuration and Utilities
1
2
Configuration parameters, constants, exception handling, utility functions, and protocol information classes.
3
4
## Capabilities
5
6
### Configuration Management
7
8
Global configuration parameters that control LDAP3 library behavior.
9
10
```python { .api }
11
def get_config_parameter(parameter):
12
"""
13
Get current value of configuration parameter.
14
15
Args:
16
parameter (str): Parameter name
17
18
Returns:
19
Configuration parameter value
20
21
Raises:
22
LDAPConfigurationParameterError: If parameter name is invalid
23
"""
24
25
def set_config_parameter(parameter, value):
26
"""
27
Set configuration parameter value.
28
29
Args:
30
parameter (str): Parameter name
31
value: New parameter value
32
33
Raises:
34
LDAPConfigurationParameterError: If parameter name is invalid
35
"""
36
```
37
38
**Available Configuration Parameters**:
39
- `CASE_INSENSITIVE_ATTRIBUTE_NAMES` (bool): Case insensitive attribute names (default: True)
40
- `CASE_INSENSITIVE_SCHEMA_NAMES` (bool): Case insensitive schema names (default: True)
41
- `ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIX` (str): Operational attribute prefix (default: 'OPER_')
42
- `POOLING_LOOP_TIMEOUT` (int): Pool loop timeout in seconds (default: 10)
43
- `RESPONSE_SLEEPTIME` (float): Response sleep time in seconds (default: 0.05)
44
- `RESPONSE_WAITING_TIMEOUT` (int): Response waiting timeout in seconds (default: 20)
45
- `SOCKET_SIZE` (int): Socket buffer size in bytes (default: 4096)
46
- `CHECK_AVAILABILITY_TIMEOUT` (float): Availability check timeout in seconds (default: 2.5)
47
- `RESTARTABLE_SLEEPTIME` (int): Restartable sleep time in seconds (default: 2)
48
- `RESTARTABLE_TRIES` (int): Number of restartable tries (default: 30)
49
- `REUSABLE_THREADED_POOL_SIZE` (int): Reusable thread pool size (default: 10)
50
- `REUSABLE_THREADED_LIFETIME` (int): Reusable thread lifetime in seconds (default: 3600)
51
- `DEFAULT_THREADED_POOL_NAME` (str): Default thread pool name (default: 'reusable_default_pool')
52
53
### Protocol Information Classes
54
55
Classes for handling LDAP server and schema information.
56
57
```python { .api }
58
class DsaInfo:
59
def __init__(self, attributes, raw_attributes):
60
"""
61
Directory Service Agent information from server's DSE.
62
63
Args:
64
attributes (dict): Processed DSE attributes
65
raw_attributes (dict): Raw DSE attributes from server
66
"""
67
68
@staticmethod
69
def from_json(json_info):
70
"""
71
Create DsaInfo from JSON data.
72
73
Args:
74
json_info (str or dict): JSON string or dictionary
75
76
Returns:
77
DsaInfo: DSA information object
78
"""
79
80
@staticmethod
81
def from_file(json_file):
82
"""
83
Create DsaInfo from JSON file.
84
85
Args:
86
json_file (str): Path to JSON file
87
88
Returns:
89
DsaInfo: DSA information object
90
"""
91
92
def to_json(self):
93
"""
94
Convert DSA info to JSON string.
95
96
Returns:
97
str: JSON representation
98
"""
99
100
def to_file(self, json_file):
101
"""
102
Save DSA info to JSON file.
103
104
Args:
105
json_file (str): Target file path
106
"""
107
```
108
109
**DsaInfo Properties**:
110
- `alt_servers`: Alternative servers list
111
- `naming_contexts`: Naming contexts list
112
- `supported_controls`: Supported LDAP controls
113
- `supported_extensions`: Supported extended operations
114
- `supported_features`: Supported LDAP features
115
- `supported_ldap_versions`: Supported LDAP versions
116
- `supported_sasl_mechanisms`: Supported SASL mechanisms
117
- `vendor_name`: LDAP server vendor name
118
- `vendor_version`: LDAP server version
119
- `schema_entry`: Schema entry DN
120
- `other`: Other DSE attributes
121
122
```python { .api }
123
class SchemaInfo:
124
def __init__(self, schema_dn, attributes, raw_attributes):
125
"""
126
LDAP schema information from server.
127
128
Args:
129
schema_dn (str): Schema entry DN
130
attributes (dict): Processed schema attributes
131
raw_attributes (dict): Raw schema attributes from server
132
"""
133
134
@staticmethod
135
def from_json(json_schema):
136
"""
137
Create SchemaInfo from JSON data.
138
139
Args:
140
json_schema (str or dict): JSON string or dictionary
141
142
Returns:
143
SchemaInfo: Schema information object
144
"""
145
146
@staticmethod
147
def from_file(json_file):
148
"""
149
Create SchemaInfo from JSON file.
150
151
Args:
152
json_file (str): Path to JSON file
153
154
Returns:
155
SchemaInfo: Schema information object
156
"""
157
158
def to_json(self):
159
"""
160
Convert schema info to JSON string.
161
162
Returns:
163
str: JSON representation
164
"""
165
166
def to_file(self, json_file):
167
"""
168
Save schema info to JSON file.
169
170
Args:
171
json_file (str): Target file path
172
"""
173
```
174
175
**SchemaInfo Properties**:
176
- `schema_dn`: Schema entry distinguished name
177
- `attribute_types`: LDAP attribute type definitions
178
- `object_classes`: LDAP object class definitions
179
- `ldap_syntaxes`: LDAP syntax definitions
180
- `matching_rules`: LDAP matching rule definitions
181
- `matching_rule_uses`: Matching rule usage definitions
182
- `dit_content_rules`: DIT content rule definitions
183
- `dit_structure_rules`: DIT structure rule definitions
184
- `name_forms`: Name form definitions
185
- `other`: Other schema attributes
186
187
### Exception Hierarchy
188
189
Comprehensive exception classes for different types of LDAP errors.
190
191
```python { .api }
192
# Base exceptions
193
class LDAPException(Exception):
194
"""Base class for all LDAP exceptions."""
195
196
class LDAPOperationResult(LDAPException):
197
"""Base class for LDAP operation result exceptions."""
198
199
# Configuration exceptions
200
class LDAPConfigurationError(LDAPException):
201
"""LDAP configuration error."""
202
203
class LDAPDefinitionError(LDAPException):
204
"""LDAP definition error."""
205
206
class LDAPConfigurationParameterError(LDAPException):
207
"""Invalid configuration parameter error."""
208
209
class LDAPUnknownStrategyError(LDAPException):
210
"""Unknown client strategy error."""
211
212
class LDAPUnknownAuthenticationMethodError(LDAPException):
213
"""Unknown authentication method error."""
214
215
# Connection exceptions
216
class LDAPBindError(LDAPException):
217
"""LDAP bind operation error."""
218
219
class LDAPInvalidServerError(LDAPException):
220
"""Invalid LDAP server specification error."""
221
222
class LDAPConnectionIsReadOnlyError(LDAPException):
223
"""Connection is read-only error."""
224
225
class LDAPCommunicationError(LDAPException):
226
"""Base LDAP communication error."""
227
228
class LDAPSocketOpenError(LDAPCommunicationError):
229
"""Socket open error."""
230
231
class LDAPSocketCloseError(LDAPCommunicationError):
232
"""Socket close error."""
233
234
class LDAPSocketReceiveError(LDAPCommunicationError):
235
"""Socket receive error."""
236
237
class LDAPSocketSendError(LDAPCommunicationError):
238
"""Socket send error."""
239
240
# SSL/TLS exceptions
241
class LDAPSSLConfigurationError(LDAPException):
242
"""SSL/TLS configuration error."""
243
244
class LDAPSSLNotSupportedError(LDAPException):
245
"""SSL not supported error."""
246
247
class LDAPStartTLSError(LDAPException):
248
"""Start TLS operation error."""
249
250
class LDAPCertificateError(LDAPException):
251
"""Certificate validation error."""
252
253
# Operation exceptions
254
class LDAPInvalidFilterError(LDAPException):
255
"""Invalid LDAP search filter error."""
256
257
class LDAPInvalidScopeError(LDAPException):
258
"""Invalid search scope error."""
259
260
class LDAPControlsError(LDAPException):
261
"""LDAP controls error."""
262
263
class LDAPExtensionError(LDAPException):
264
"""LDAP extended operation error."""
265
266
class LDAPResponseTimeoutError(LDAPException):
267
"""Response timeout error."""
268
269
class LDAPTransactionError(LDAPException):
270
"""LDAP transaction error."""
271
272
# Abstract layer exceptions
273
class LDAPAttributeError(LDAPException, KeyError, AttributeError):
274
"""LDAP attribute error."""
275
276
class LDAPEntryError(LDAPException):
277
"""LDAP entry error."""
278
279
class LDAPReaderError(LDAPException):
280
"""LDAP reader error."""
281
282
class LDAPObjectError(LDAPException):
283
"""LDAP object definition error."""
284
285
class LDAPTypeError(LDAPException):
286
"""LDAP type error."""
287
288
# Result code exceptions (selected examples)
289
class LDAPInvalidCredentialsResult(LDAPOperationResult):
290
"""Invalid credentials result (49)."""
291
292
class LDAPInsufficientAccessRightsResult(LDAPOperationResult):
293
"""Insufficient access rights result (50)."""
294
295
class LDAPTimeLimitExceededResult(LDAPOperationResult):
296
"""Time limit exceeded result (3)."""
297
298
class LDAPSizeLimitExceededResult(LDAPOperationResult):
299
"""Size limit exceeded result (4)."""
300
```
301
302
### Constants and Enumerations
303
304
Important constants used throughout the library.
305
306
```python { .api }
307
# Result codes (selected)
308
RESULT_SUCCESS = 0
309
RESULT_OPERATIONS_ERROR = 1
310
RESULT_PROTOCOL_ERROR = 2
311
RESULT_TIME_LIMIT_EXCEEDED = 3
312
RESULT_SIZE_LIMIT_EXCEEDED = 4
313
RESULT_COMPARE_FALSE = 5
314
RESULT_COMPARE_TRUE = 6
315
RESULT_INVALID_CREDENTIALS = 49
316
RESULT_INSUFFICIENT_ACCESS_RIGHTS = 50
317
318
# Authentication methods
319
ANONYMOUS = 'ANONYMOUS'
320
SIMPLE = 'SIMPLE'
321
SASL = 'SASL'
322
NTLM = 'NTLM'
323
324
# Client strategies
325
SYNC = 'SYNC'
326
ASYNC = 'ASYNC'
327
LDIF = 'LDIF'
328
RESTARTABLE = 'RESTARTABLE'
329
REUSABLE = 'REUSABLE'
330
MOCK_SYNC = 'MOCK_SYNC'
331
MOCK_ASYNC = 'MOCK_ASYNC'
332
333
# Search scopes
334
BASE = 'BASE'
335
LEVEL = 'LEVEL'
336
SUBTREE = 'SUBTREE'
337
338
# Search attributes
339
ALL_ATTRIBUTES = '*'
340
NO_ATTRIBUTES = '1.1'
341
ALL_OPERATIONAL_ATTRIBUTES = '+'
342
343
# Modify operations
344
MODIFY_ADD = 'MODIFY_ADD'
345
MODIFY_DELETE = 'MODIFY_DELETE'
346
MODIFY_REPLACE = 'MODIFY_REPLACE'
347
MODIFY_INCREMENT = 'MODIFY_INCREMENT'
348
349
# Hash algorithms
350
HASHED_NONE = 'PLAIN'
351
HASHED_SHA = 'SHA'
352
HASHED_SHA256 = 'SHA256'
353
HASHED_MD5 = 'MD5'
354
HASHED_SALTED_SHA = 'SALTED_SHA'
355
HASHED_SALTED_MD5 = 'SALTED_MD5'
356
```
357
358
## Usage Examples
359
360
### Configuration Management
361
362
```python
363
import ldap3
364
365
# Get current configuration values
366
case_insensitive = ldap3.get_config_parameter('CASE_INSENSITIVE_ATTRIBUTE_NAMES')
367
response_timeout = ldap3.get_config_parameter('RESPONSE_WAITING_TIMEOUT')
368
369
print(f"Case insensitive attributes: {case_insensitive}")
370
print(f"Response timeout: {response_timeout} seconds")
371
372
# Modify configuration
373
ldap3.set_config_parameter('RESPONSE_WAITING_TIMEOUT', 30)
374
ldap3.set_config_parameter('SOCKET_SIZE', 8192)
375
376
# Configuration affects all subsequent connections
377
server = ldap3.Server('ldap://ldap.example.com')
378
conn = ldap3.Connection(server, 'cn=user,dc=example,dc=com', 'password')
379
# This connection will use the modified timeout and socket size
380
```
381
382
### Working with Server Information
383
384
```python
385
# Get server information during connection
386
server = ldap3.Server('ldap://ldap.example.com', get_info=ldap3.ALL)
387
conn = ldap3.Connection(server, 'cn=user,dc=example,dc=com', 'password', auto_bind=True)
388
389
# Access DSA information
390
dsa_info = server.info
391
print(f"Server vendor: {dsa_info.vendor_name}")
392
print(f"Server version: {dsa_info.vendor_version}")
393
print(f"Supported LDAP versions: {dsa_info.supported_ldap_versions}")
394
print(f"Supported SASL mechanisms: {dsa_info.supported_sasl_mechanisms}")
395
print(f"Naming contexts: {dsa_info.naming_contexts}")
396
397
# Save server info to file
398
dsa_info.to_file('/tmp/server_info.json')
399
400
# Load server info from file later
401
loaded_dsa = ldap3.DsaInfo.from_file('/tmp/server_info.json')
402
```
403
404
### Working with Schema Information
405
406
```python
407
# Get schema information
408
server = ldap3.Server('ldap://ldap.example.com', get_info=ldap3.ALL)
409
conn = ldap3.Connection(server, 'cn=user,dc=example,dc=com', 'password', auto_bind=True)
410
411
schema = server.schema
412
if schema:
413
print(f"Schema DN: {schema.schema_dn}")
414
415
# Explore object classes
416
print("Available object classes:")
417
for oc_name, oc_def in schema.object_classes.items():
418
print(f" {oc_name}: {oc_def.description}")
419
420
# Explore attribute types
421
print("Available attribute types:")
422
for attr_name, attr_def in schema.attribute_types.items():
423
print(f" {attr_name}: {attr_def.description}")
424
425
# Save schema to file
426
schema.to_file('/tmp/schema_info.json')
427
428
# Check specific object class
429
if 'inetOrgPerson' in schema.object_classes:
430
inet_org_person = schema.object_classes['inetOrgPerson']
431
print(f"inetOrgPerson must attributes: {inet_org_person.must_contain}")
432
print(f"inetOrgPerson may attributes: {inet_org_person.may_contain}")
433
```
434
435
### Exception Handling
436
437
```python
438
import ldap3
439
440
try:
441
server = ldap3.Server('ldap://invalid.server.com')
442
conn = ldap3.Connection(server, 'cn=user,dc=example,dc=com', 'password')
443
conn.bind()
444
445
# Perform operations
446
conn.search('dc=example,dc=com', '(objectClass=person)')
447
448
except ldap3.LDAPInvalidServerError as e:
449
print(f"Invalid server: {e}")
450
451
except ldap3.LDAPBindError as e:
452
print(f"Bind failed: {e}")
453
454
except ldap3.LDAPInvalidCredentialsResult as e:
455
print(f"Invalid credentials: {e}")
456
457
except ldap3.LDAPSocketOpenError as e:
458
print(f"Cannot connect to server: {e}")
459
460
except ldap3.LDAPCommunicationError as e:
461
print(f"Communication error: {e}")
462
463
except ldap3.LDAPInvalidFilterError as e:
464
print(f"Invalid search filter: {e}")
465
466
except ldap3.LDAPException as e:
467
print(f"General LDAP error: {e}")
468
```
469
470
### Advanced Configuration for Performance
471
472
```python
473
# Optimize for high-performance scenarios
474
ldap3.set_config_parameter('SOCKET_SIZE', 16384) # Larger socket buffer
475
ldap3.set_config_parameter('RESPONSE_WAITING_TIMEOUT', 60) # Longer timeout
476
ldap3.set_config_parameter('RESPONSE_SLEEPTIME', 0.01) # Faster polling
477
478
# Configure thread pool for reusable connections
479
ldap3.set_config_parameter('REUSABLE_THREADED_POOL_SIZE', 20)
480
ldap3.set_config_parameter('REUSABLE_THREADED_LIFETIME', 7200) # 2 hours
481
482
# Create high-performance connection pool
483
servers = [
484
ldap3.Server('ldap1.example.com'),
485
ldap3.Server('ldap2.example.com')
486
]
487
server_pool = ldap3.ServerPool(servers, ldap3.ROUND_ROBIN, active=True)
488
489
conn = ldap3.Connection(
490
server_pool,
491
'cn=user,dc=example,dc=com',
492
'password',
493
client_strategy=ldap3.REUSABLE,
494
pool_name='high_perf_pool',
495
pool_size=10,
496
pool_lifetime=3600,
497
auto_bind=True,
498
fast_decoder=True
499
)
500
```
501
502
### Custom Exception Handling
503
504
```python
505
def safe_ldap_operation(connection, operation_func, *args, **kwargs):
506
"""
507
Safely execute LDAP operation with comprehensive error handling.
508
"""
509
try:
510
return operation_func(*args, **kwargs)
511
512
except ldap3.LDAPInvalidCredentialsResult:
513
print("Authentication failed - check username/password")
514
return None
515
516
except ldap3.LDAPInsufficientAccessRightsResult:
517
print("Insufficient permissions for operation")
518
return None
519
520
except ldap3.LDAPTimeLimitExceededResult:
521
print("Operation timed out - try with smaller scope")
522
return None
523
524
except ldap3.LDAPSizeLimitExceededResult:
525
print("Too many results - use paged search")
526
return None
527
528
except ldap3.LDAPSocketOpenError:
529
print("Cannot connect to LDAP server")
530
return None
531
532
except ldap3.LDAPCommunicationError as e:
533
print(f"Network communication error: {e}")
534
return None
535
536
except ldap3.LDAPOperationResult as e:
537
print(f"LDAP operation failed with result {e.result}: {e.description}")
538
return None
539
540
except ldap3.LDAPException as e:
541
print(f"Unexpected LDAP error: {e}")
542
return None
543
544
# Usage
545
result = safe_ldap_operation(
546
conn,
547
conn.search,
548
'dc=example,dc=com',
549
'(objectClass=person)',
550
attributes=['cn', 'mail']
551
)
552
```
553
554
### Offline Schema Usage
555
556
```python
557
# Use predefined offline schemas for testing
558
offline_schemas = {
559
ldap3.OFFLINE_AD_2012_R2: "Active Directory 2012 R2",
560
ldap3.OFFLINE_EDIR_8_8_8: "Novell eDirectory 8.8.8",
561
ldap3.OFFLINE_SLAPD_2_4: "OpenLDAP slapd 2.4",
562
ldap3.OFFLINE_DS389_1_3_3: "389 Directory Server 1.3.3"
563
}
564
565
# Create server with offline schema
566
server = ldap3.Server('ldap://test.example.com', get_info=ldap3.OFFLINE_AD_2012_R2)
567
568
# Schema information is available without connecting
569
print(f"Using offline schema: {offline_schemas[ldap3.OFFLINE_AD_2012_R2]}")
570
print(f"Object classes available: {len(server.schema.object_classes)}")
571
print(f"Attribute types available: {len(server.schema.attribute_types)}")
572
```
573
574
### Configuration File Management
575
576
```python
577
import json
578
579
def save_ldap_config():
580
"""Save current LDAP3 configuration to file."""
581
config = {}
582
583
config_params = [
584
'CASE_INSENSITIVE_ATTRIBUTE_NAMES',
585
'CASE_INSENSITIVE_SCHEMA_NAMES',
586
'RESPONSE_WAITING_TIMEOUT',
587
'SOCKET_SIZE',
588
'RESTARTABLE_TRIES',
589
'REUSABLE_THREADED_POOL_SIZE'
590
]
591
592
for param in config_params:
593
try:
594
config[param] = ldap3.get_config_parameter(param)
595
except ldap3.LDAPConfigurationParameterError:
596
pass
597
598
with open('/tmp/ldap3_config.json', 'w') as f:
599
json.dump(config, f, indent=2)
600
601
def load_ldap_config():
602
"""Load LDAP3 configuration from file."""
603
try:
604
with open('/tmp/ldap3_config.json', 'r') as f:
605
config = json.load(f)
606
607
for param, value in config.items():
608
try:
609
ldap3.set_config_parameter(param, value)
610
print(f"Set {param} = {value}")
611
except ldap3.LDAPConfigurationParameterError as e:
612
print(f"Cannot set {param}: {e}")
613
614
except FileNotFoundError:
615
print("Configuration file not found")
616
617
# Usage
618
save_ldap_config()
619
# ... modify configuration in another session
620
load_ldap_config()
621
```