|
Lines 31-39
Link Here
|
| 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 |