summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipaserver/ipaldap.py138
-rw-r--r--ipaserver/plugins/ldap2.py122
2 files changed, 139 insertions, 121 deletions
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 20da44188..db5fc9880 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -32,6 +32,7 @@ from decimal import Decimal
import ldap
import ldap as _ldap
import ldap.sasl
+import ldap.filter
from ldap.controls import LDAPControl
from ldap.ldapobject import SimpleLDAPObject
import ldapurl
@@ -782,6 +783,16 @@ class LDAPConnection(object):
subclasses, IPAdmin or the ldap2 plugin.
"""
+ # rules for generating filters from entries
+ MATCH_ANY = '|' # (|(filter1)(filter2))
+ MATCH_ALL = '&' # (&(filter1)(filter2))
+ MATCH_NONE = '!' # (!(filter1)(filter2))
+
+ # search scope for find_entries()
+ SCOPE_BASE = _ldap.SCOPE_BASE
+ SCOPE_ONELEVEL = _ldap.SCOPE_ONELEVEL
+ SCOPE_SUBTREE = _ldap.SCOPE_SUBTREE
+
def __init__(self, ldap_uri):
self.ldap_uri = ldap_uri
self.log = log_mgr.get_logger(self)
@@ -940,6 +951,133 @@ class LDAPConnection(object):
parent_dn = self.normalize_dn(parent_dn)
return DN((primary_key, entry_attrs[primary_key]), parent_dn)
+ # generating filters for find_entry
+ # some examples:
+ # f1 = ldap2.make_filter_from_attr(u'firstName', u'Pavel')
+ # f2 = ldap2.make_filter_from_attr(u'lastName', u'Zuna')
+ # f = ldap2.combine_filters([f1, f2], ldap2.MATCH_ALL)
+ # # f should be (&(firstName=Pavel)(lastName=Zuna))
+ # # it should be equivalent to:
+ # entry_attrs = {u'firstName': u'Pavel', u'lastName': u'Zuna'}
+ # f = ldap2.make_filter(entry_attrs, rules=ldap2.MATCH_ALL)
+
+ def combine_filters(self, filters, rules='|'):
+ """
+ Combine filters into one for ldap2.find_entries.
+
+ Keyword arguments:
+ rules -- see ldap2.make_filter
+ """
+
+ assert isinstance(filters, (list, tuple))
+
+ filters = [f for f in filters if f]
+ if filters and rules == self.MATCH_NONE: # unary operator
+ return '(%s%s)' % (self.MATCH_NONE,
+ self.combine_filters(filters, self.MATCH_ANY))
+
+ if len(filters) > 1:
+ flt = '(%s' % rules
+ else:
+ flt = ''
+ for f in filters:
+ if not f.startswith('('):
+ f = '(%s)' % f
+ flt = '%s%s' % (flt, f)
+ if len(filters) > 1:
+ flt = '%s)' % flt
+ return flt
+
+ def make_filter_from_attr(
+ self, attr, value, rules='|', exact=True,
+ leading_wildcard=True, trailing_wildcard=True):
+ """
+ Make filter for ldap2.find_entries from attribute.
+
+ Keyword arguments:
+ rules -- see ldap2.make_filter
+ exact -- boolean, True - make filter as (attr=value)
+ False - make filter as (attr=*value*)
+ leading_wildcard -- boolean:
+ True - allow heading filter wildcard when exact=False
+ False - forbid heading filter wildcard when exact=False
+ trailing_wildcard -- boolean:
+ True - allow trailing filter wildcard when exact=False
+ False - forbid trailing filter wildcard when exact=False
+ """
+ if isinstance(value, (list, tuple)):
+ if rules == self.MATCH_NONE:
+ make_filter_rules = self.MATCH_ANY
+ else:
+ make_filter_rules = rules
+ flts = [
+ self.make_filter_from_attr(
+ attr, v, exact=exact,
+ leading_wildcard=leading_wildcard,
+ trailing_wildcard=trailing_wildcard)
+ for v in value
+ ]
+ return self.combine_filters(flts, rules)
+ elif value is not None:
+ value = ldap.filter.escape_filter_chars(value_to_utf8(value))
+ if not exact:
+ template = '%s'
+ if leading_wildcard:
+ template = '*' + template
+ if trailing_wildcard:
+ template = template + '*'
+ value = template % value
+ if rules == self.MATCH_NONE:
+ return '(!(%s=%s))' % (attr, value)
+ return '(%s=%s)' % (attr, value)
+ return ''
+
+ def make_filter(
+ self, entry_attrs, attrs_list=None, rules='|', exact=True,
+ leading_wildcard=True, trailing_wildcard=True):
+ """
+ Make filter for ldap2.find_entries from entry attributes.
+
+ Keyword arguments:
+ attrs_list -- list of attributes to use, all if None (default None)
+ rules -- specifies how to determine a match (default ldap2.MATCH_ANY)
+ exact -- boolean, True - make filter as (attr=value)
+ False - make filter as (attr=*value*)
+ leading_wildcard -- boolean:
+ True - allow heading filter wildcard when exact=False
+ False - forbid heading filter wildcard when exact=False
+ trailing_wildcard -- boolean:
+ True - allow trailing filter wildcard when exact=False
+ False - forbid trailing filter wildcard when exact=False
+
+ rules can be one of the following:
+ ldap2.MATCH_NONE - match entries that do not match any attribute
+ ldap2.MATCH_ALL - match entries that match all attributes
+ ldap2.MATCH_ANY - match entries that match any of attribute
+ """
+ if rules == self.MATCH_NONE:
+ make_filter_rules = self.MATCH_ANY
+ else:
+ make_filter_rules = rules
+ flts = []
+ if attrs_list is None:
+ for (k, v) in entry_attrs.iteritems():
+ flts.append(
+ self.make_filter_from_attr(
+ k, v, make_filter_rules, exact,
+ leading_wildcard, trailing_wildcard)
+ )
+ else:
+ for a in attrs_list:
+ value = entry_attrs.get(a, None)
+ if value is not None:
+ flts.append(
+ self.make_filter_from_attr(
+ a, value, make_filter_rules, exact,
+ leading_wildcard, trailing_wildcard)
+ )
+ return self.combine_filters(flts, rules)
+
class IPAdmin(LDAPConnection):
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index fbcad9678..a75e6bbc5 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -39,8 +39,7 @@ import ldap.filter as _ldap_filter
from ipapython.dn import DN, RDN
from ipaserver.ipaldap import (
- SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject,
- LDAPConnection)
+ SASL_AUTH, unicode_from_utf8, IPASimpleLDAPObject, LDAPConnection)
try:
@@ -75,16 +74,6 @@ class ldap2(LDAPConnection, CrudBackend):
# only MOD_REPLACE operations are generated for them
_FORCE_REPLACE_ON_UPDATE_ATTRS = []
- # rules for generating filters from entries
- MATCH_ANY = '|' # (|(filter1)(filter2))
- MATCH_ALL = '&' # (&(filter1)(filter2))
- MATCH_NONE = '!' # (!(filter1)(filter2))
-
- # search scope for find_entries()
- SCOPE_BASE = _ldap.SCOPE_BASE
- SCOPE_ONELEVEL = _ldap.SCOPE_ONELEVEL
- SCOPE_SUBTREE = _ldap.SCOPE_SUBTREE
-
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
schema=None):
try:
@@ -236,115 +225,6 @@ class ldap2(LDAPConnection, CrudBackend):
except _ldap.LDAPError, e:
self.handle_errors(e)
- # generating filters for find_entry
- # some examples:
- # f1 = ldap2.make_filter_from_attr(u'firstName', u'Pavel')
- # f2 = ldap2.make_filter_from_attr(u'lastName', u'Zuna')
- # f = ldap2.combine_filters([f1, f2], ldap2.MATCH_ALL)
- # # f should be (&(firstName=Pavel)(lastName=Zuna))
- # # it should be equivalent to:
- # entry_attrs = {u'firstName': u'Pavel', u'lastName': u'Zuna'}
- # f = ldap2.make_filter(entry_attrs, rules=ldap2.MATCH_ALL)
-
- def combine_filters(self, filters, rules='|'):
- """
- Combine filters into one for ldap2.find_entries.
-
- Keyword arguments:
- rules -- see ldap2.make_filter
- """
-
- assert isinstance(filters, (list, tuple))
-
- filters = [f for f in filters if f]
- if filters and rules == self.MATCH_NONE: # unary operator
- return '(%s%s)' % (self.MATCH_NONE,
- self.combine_filters(filters, self.MATCH_ANY))
-
- if len(filters) > 1:
- flt = '(%s' % rules
- else:
- flt = ''
- for f in filters:
- if not f.startswith('('):
- f = '(%s)' % f
- flt = '%s%s' % (flt, f)
- if len(filters) > 1:
- flt = '%s)' % flt
- return flt
-
- def make_filter_from_attr(self, attr, value, rules='|', exact=True,
- leading_wildcard=True, trailing_wildcard=True):
- """
- Make filter for ldap2.find_entries from attribute.
-
- Keyword arguments:
- rules -- see ldap2.make_filter
- exact -- boolean, True - make filter as (attr=value)
- False - make filter as (attr=*value*)
- leading_wildcard -- boolean, True - allow heading filter wildcard when exact=False
- False - forbid heading filter wildcard when exact=False
- trailing_wildcard -- boolean, True - allow trailing filter wildcard when exact=False
- False - forbid trailing filter wildcard when exact=False
- """
- if isinstance(value, (list, tuple)):
- make_filter_rules = self.MATCH_ANY if rules == self.MATCH_NONE else rules
- flts = [ self.make_filter_from_attr(attr, v, exact=exact,
- leading_wildcard=leading_wildcard,
- trailing_wildcard=trailing_wildcard) for v in value ]
- return self.combine_filters(flts, rules)
- elif value is not None:
- value = _ldap_filter.escape_filter_chars(value_to_utf8(value))
- if not exact:
- template = '%s'
- if leading_wildcard:
- template = '*' + template
- if trailing_wildcard:
- template = template + '*'
- value = template % value
- if rules == self.MATCH_NONE:
- return '(!(%s=%s))' % (attr, value)
- return '(%s=%s)' % (attr, value)
- return ''
-
- def make_filter(self, entry_attrs, attrs_list=None, rules='|', exact=True,
- leading_wildcard=True, trailing_wildcard=True):
- """
- Make filter for ldap2.find_entries from entry attributes.
-
- Keyword arguments:
- attrs_list -- list of attributes to use, all if None (default None)
- rules -- specifies how to determine a match (default ldap2.MATCH_ANY)
- exact -- boolean, True - make filter as (attr=value)
- False - make filter as (attr=*value*)
- leading_wildcard -- boolean, True - allow heading filter wildcard when exact=False
- False - forbid heading filter wildcard when exact=False
- trailing_wildcard -- boolean, True - allow trailing filter wildcard when exact=False
- False - forbid trailing filter wildcard when exact=False
-
- rules can be one of the following:
- ldap2.MATCH_NONE - match entries that do not match any attribute
- ldap2.MATCH_ALL - match entries that match all attributes
- ldap2.MATCH_ANY - match entries that match any of attribute
- """
- make_filter_rules = self.MATCH_ANY if rules == self.MATCH_NONE else rules
- flts = []
- if attrs_list is None:
- for (k, v) in entry_attrs.iteritems():
- flts.append(
- self.make_filter_from_attr(k, v, make_filter_rules, exact,
- leading_wildcard, trailing_wildcard)
- )
- else:
- for a in attrs_list:
- value = entry_attrs.get(a, None)
- if value is not None:
- flts.append(
- self.make_filter_from_attr(a, value, make_filter_rules, exact,
- leading_wildcard, trailing_wildcard)
- )
- return self.combine_filters(flts, rules)
-
def find_entries(self, filter=None, attrs_list=None, base_dn=None,
scope=_ldap.SCOPE_SUBTREE, time_limit=None, size_limit=None,
normalize=True, search_refs=False):