summaryrefslogtreecommitdiff
path: root/ldap3/utils/config.py
blob: e3edbf8cdc2baa264147505269a3937b86aea4b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
"""
"""

# 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 <http://www.gnu.org/licenses/>.

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 = 3  # 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

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'
              ]


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]

    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
    else:
        raise LDAPConfigurationParameterError('unable to set configuration parameter %s' % parameter)