|
31 |
# <http://www.gnu.org/licenses/>. |
31 |
# <http://www.gnu.org/licenses/>. |
32 |
|
32 |
|
33 |
import re |
33 |
import re |
34 |
import types |
|
|
35 |
import univention.admin.uexceptions |
34 |
import univention.admin.uexceptions |
36 |
|
35 |
|
|
|
36 |
|
37 |
def escapeForLdapFilter(txt): |
37 |
def escapeForLdapFilter(txt): |
38 |
"""Escape LDAP filter value. |
38 |
"""Escape LDAP filter value. |
39 |
Bug #19976: According to RFC2254 [*()\\\0] must be \\%02x encoded. |
39 |
Bug #19976: According to RFC2254 [*()\\\0] must be \\%02x encoded. |
Lines 141-146
def parse(filter_s, begin=0, end=-1):
|
Link Here
|
---|
|
141 |
>> parse('(&(key=va\\)!\\(ue))') |
141 |
>> parse('(&(key=va\\)!\\(ue))') |
142 |
conjunction('&', [expression('key', 'va)!(ue', '=')]) |
142 |
conjunction('&', [expression('key', 'va)!(ue', '=')]) |
143 |
""" |
143 |
""" |
|
|
144 |
# filter is already parsed |
145 |
if not isinstance(filter_s, basestring): |
146 |
return filter_s |
147 |
|
144 |
def split(str): |
148 |
def split(str): |
145 |
expressions=[] |
149 |
expressions=[] |
146 |
depth=0 |
150 |
depth=0 |
Lines 159-168
def parse(filter_s, begin=0, end=-1):
|
Link Here
|
---|
|
159 |
i+=1 |
163 |
i+=1 |
160 |
return expressions |
164 |
return expressions |
161 |
|
165 |
|
162 |
# filter is already parsed |
|
|
163 |
if type(filter_s) == types.InstanceType: |
164 |
return filter_s |
165 |
|
166 |
if end == -1: |
166 |
if end == -1: |
167 |
end=len(filter_s)-1 |
167 |
end=len(filter_s)-1 |
168 |
|
168 |
|
Lines 187-192
def parse(filter_s, begin=0, end=-1):
|
Link Here
|
---|
|
187 |
variable, value=filter_s[begin:end+1].split('=', 1) |
187 |
variable, value=filter_s[begin:end+1].split('=', 1) |
188 |
return expression(variable, value) |
188 |
return expression(variable, value) |
189 |
|
189 |
|
|
|
190 |
|
190 |
def walk(filter, expression_walk_function=None, conjunction_walk_function=None, arg=None): |
191 |
def walk(filter, expression_walk_function=None, conjunction_walk_function=None, arg=None): |
191 |
"""Walk LDAP filter expression tree. |
192 |
"""Walk LDAP filter expression tree. |
192 |
|
193 |
|
Lines 211-241
def walk(filter, expression_walk_function=None, conjunction_walk_function=None,
|
Link Here
|
---|
|
211 |
if expression_walk_function: |
212 |
if expression_walk_function: |
212 |
expression_walk_function(filter, arg) |
213 |
expression_walk_function(filter, arg) |
213 |
|
214 |
|
214 |
FQDN_REGEX = re.compile( '^(.*?)\(?fqdn=([^)]+)\)?(.*)$' ) |
215 |
|
215 |
def replace_fqdn_filter( filter_s ): |
216 |
FQDN_REGEX = re.compile(r'(?:^|\()fqdn=([^)]+)(?:\)|$)') |
|
|
217 |
|
218 |
|
219 |
def replace_fqdn_filter(filter_s): |
216 |
''' |
220 |
''' |
217 |
Replaces a filter expression for the read-only attribute fqdn. If no |
221 |
Replaces a filter expression for the read-only attribute fqdn. If no |
218 |
such expression can be found the unmodified filter is returned. |
222 |
such expression can be found the unmodified filter is returned. |
219 |
|
223 |
|
220 |
fqdn=host.doain.tld -> (&(cn=host)(associatedDomain=domain.tld)) |
224 |
>>> replace_fqdn_filter('fqdn=host.domain.tld') |
|
|
225 |
'(&(cn=host)(associatedDomain=domain.tld))' |
226 |
>>> replace_fqdn_filter('(fqdn=host.domain.tld)') |
227 |
'(&(cn=host)(associatedDomain=domain.tld))' |
228 |
>>> replace_fqdn_filter('fqdn=domain') |
229 |
'(|(cn=domain)(associatedDomain=domain))' |
230 |
>>> replace_fqdn_filter('(|(fqdn=host.domain.tld)(fqdn=other.domain.tld2))') |
231 |
'(|(&(cn=host)(associatedDomain=domain.tld))(&(cn=other)(associatedDomain=domain.tld2)))' |
221 |
''' |
232 |
''' |
222 |
if not isinstance( filter_s, basestring ): |
233 |
if not isinstance(filter_s, basestring): |
223 |
return filter_s |
234 |
return filter_s |
224 |
if filter_s.find( 'fqdn=' ) != -1: |
235 |
return FQDN_REGEX.sub(_replace_fqdn_filter, filter_s) |
225 |
match = FQDN_REGEX.match( str( filter_s ) ) |
236 |
|
226 |
if match: |
237 |
|
227 |
prefix, value, suffix = match.groups() |
238 |
def _replace_fqdn_filter(match): |
228 |
if value.find( '.' ) >= 0: |
239 |
value, = match.groups() |
229 |
host, domain = value.split( '.', 1 ) |
240 |
try: |
230 |
operator = '&' |
241 |
host, domain = value.split('.', 1) |
231 |
else: |
242 |
operator = '&' |
232 |
host = value |
243 |
except ValueError: |
233 |
domain = value |
244 |
host = domain = value |
234 |
operator = '|' |
245 |
operator = '|' |
235 |
fqdn_filter = '(%s(cn=%s)(associatedDomain=%s))' % ( operator, host, domain ) |
246 |
return '(%s(cn=%s)(associatedDomain=%s))' % (operator, host, domain) |
236 |
return prefix + fqdn_filter + suffix |
247 |
|
237 |
|
|
|
238 |
return filter_s |
239 |
|
248 |
|
240 |
if __name__ == '__main__': |
249 |
if __name__ == '__main__': |
241 |
import doctest |
250 |
import doctest |