def _addTreeItems(conn_str, dn, attrs=None): """ Add structure directly to the tree given a DN """ elems = explode_dn(dn) elems.reverse() if not TREE.has_key(conn_str): TREE[conn_str] = cidict() tree_pos = TREE[conn_str] for elem in elems: elem_dn = dn[dn.index(elem):] if not tree_pos.has_key(elem): tree_pos[elem] = cidict({'dn': elem_dn}) tree_pos = tree_pos[elem] if attrs is not None: rec = tree_pos rdn = elems[-1] k, v = rdn.split('=') rec[k] = [v] for key, val in attrs.items(): if isinstance(val, list): rec[key] = val else: rec[key] = [val]
def _addTreeItems(conn_str, dn, attrs=None): """ Add structure directly to the tree given a DN """ elems = explode_dn(dn) elems.reverse() if not TREE.has_key(conn_str): TREE[conn_str] = cidict() tree_pos = TREE[conn_str] for elem in elems: elem_dn = dn[dn.index(elem):] if not tree_pos.has_key(elem): tree_pos[elem] = cidict({'dn': elem_dn}) tree_pos = tree_pos[elem] if attrs is not None: rec = tree_pos rdn = elems[-1] k,v = rdn.split('=') rec[k] = [v] for key, val in attrs.items(): if isinstance(val, list): rec[key] = val else: rec[key] = [val]
def __init__(self, entrydata): """entrydata is the raw data returned from the python-ldap result method, which is: * a search result entry -> (dn, {dict...} ) * or a reference -> (None, reference) * or None. If creating a new empty entry, data is the string DN. """ self.ref = None if entrydata: if isinstance(entrydata, tuple): if entrydata[0] is None: self.ref = entrydata[1] # continuation reference else: self.dn = entrydata[0] self.data = cidict(entrydata[1]) elif isinstance(entrydata, six.string_types): if '=' not in entrydata: raise ValueError('Entry dn must contain "="') self.dn = entrydata self.data = cidict() else: self.data = cidict() self.dn = None
def __init__(self, entrydata): """entrydata is the raw data returned from the python-ldap result method, which is: * a search result entry -> (dn, {dict...} ) * or a reference -> (None, reference) * or None. If creating a new empty entry, data is the string DN. """ self.ref = None self.data = None if entrydata: if isinstance(entrydata, tuple): if entrydata[0] is None: self.ref = entrydata[1] # continuation reference else: self.dn = entrydata[0] self.data = cidict(entrydata[1]) elif isinstance(entrydata, six.string_types): if '=' not in entrydata: raise ValueError('Entry dn must contain "="') self.dn = entrydata self.data = cidict() else: self.dn = '' self.data = cidict()
def __init__(self, *args, **kwargs): # Initialise the LDAP Connection first ldap.ldapobject.ReconnectLDAPObject.__init__(self, *args, **kwargs) # Now prepare the data store self.__data = cidict() self.__data['uuids'] = cidict() # We need this for later internal use self.__presentUUIDs = cidict()
def __init__(self, dn=None, attrs=None, helper=None): self.__dict__['dn'] = dn if attrs is None: attrs = cidict() if isinstance(attrs, dict): attrs = cidict(attrs) self.__dict__['attrs'] = attrs self.__dict__['cached_attrs'] = None self.__dict__['helper'] = helper
def __init__(self, connection, user): print "LDAPUser:"******"LDAPResult:" print result if len(result) == 1: self._attrs = cidict(result[0][1])
def __init__(self, entry_tuple): (dn, attrs) = entry_tuple if dn: self.dn = dn else: return self.attrs = cidict(attrs)
def add_s(self, dn, modlist): if self.invalid: raise LDAPError('LDAP connection invalid') if self.bound is None or (_requires_auth(self.conn_str) and self.bound == 'ANONYMOUS'): raise STRONG_AUTH_REQUIRED({'info': 'modifications require authentication', 'desc': 'Strong(er) authentication required'}) elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE[self.conn_str] for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise NO_SUCH_OBJECT if tree_pos.has_key(rdn): raise ALREADY_EXISTS else: k, v = rdn.split('=') # tree_pos[rdn] = {'dn': dn, k: [v]} tree_pos[rdn] = cidict({'dn': dn, k: [v]}) rec = tree_pos[rdn] for key, val in modlist: if isinstance(val, list): rec[key] = val else: rec[key] = [val]
def _attronly(val): result = cidict() for k, v in val.items(): if k != 'dn' and not isinstance(v, (dict, cidict)): result[k] = v return result
def _attronly(val): result = cidict() for k,v in val.items(): if k != 'dn' and not isinstance(v, (dict, cidict)): result[k] = v return result
def __init__(self, entry_tuple): """Create a new LDAPSearchResult object.""" (dn, attrs) = entry_tuple if dn: self.dn = dn else: return self.attrs = cidict(attrs)
def set_attributes(self, attr_dict): """ Set the list of attributes for this record. The format of the dictionary should be string key, list of string alues. e.g. {'cn': ['M Butcher','Matt Butcher']} set_attributes(attr_dictionary) """ self.attrs = cidict(attr_dict)
def _toggle_auth_required(conn_str): if not TREE.has_key(conn_str): TREE[conn_str] = cidict() tree_pos = TREE[conn_str] if tree_pos.has_key('__auth_required__'): tree_pos['__auth_required__'] = not tree_pos['__auth_required__'] else: tree_pos['__auth_required__'] = True
def _toggle_ad_directory(conn_str): if not TREE.has_key(conn_str): TREE[conn_str] = cidict() tree_pos = TREE[conn_str] if tree_pos.has_key('__active_directory__'): tree_pos['__active_directory__'] = not tree_pos['__active_directory__'] else: tree_pos['__active_directory__'] = True
def __init__(self, entry_tuple): #Create a new LDAPSearchResult object. (dn, attrs) = entry_tuple if dn: self.dn = dn else: return self.attrs = cidict(attrs)
def find_by_iid(self, base_dn, iid): try: result = self.conn.search_s(base_dn, ldap.SCOPE_SUBTREE, '(%s=%s)' % (constants.FT_IID, iid)) except ldap.NO_SUCH_OBJECT: return None if result is not None and len(result) > 0: dn, attrs = result[0] return dn, cidict(dict(attrs)) else: return None
def __init__(self, directory): if not isinstance(directory, ldap.cidict.cidict): from . import map_keys directory = cidict(map_keys(lambda s: s.lower(), directory)) self.directory = deepcopy(directory) self.async_results = [] self.options = {} self.tls_enabled = False self.bound_as = None
def __init__(self, entry_tuple): """Create a new LDAPSearchResult object.""" (dn, attrs) = entry_tuple if dn: self.dn = dn else: return # this cause a types problem in to_dict() self.attrs = cidict(attrs)
def procesOracleContext(self): dn = "cn=oraclecontext,ou=applications,dc=apidb,dc=org" if self.host_filter is None: filterstr = "(objectclass=orclNetService)" else: filterstr = "(&(objectclass=orclNetService)(orclNetDescString=*HOST={0}*))".format( self.host_filter) scope = ldap.SCOPE_SUBTREE attrlist = ["cn", "orclnetdescstring", "description"] result_set = self.search(dn, ldap.SCOPE_ONELEVEL, attrlist, filterstr) servicename_re = re.compile(".+SERVICE_NAME=([^\)]+)\).*", re.IGNORECASE) tnsname_re = re.compile(".+HOST=([^\)]+)\).*", re.IGNORECASE) if result_set is None: return for result in result_set: tns_entries = cidict(result[1]) cn = tns_entries["cn"][0].decode("utf-8").strip() # split/join to remove all whitespace in orclNetDescString orclNetDescString = "".join( tns_entries["orclnetdescstring"][0].decode("utf-8").split()) m = re.match(servicename_re, orclNetDescString) service_name = "NA" if m is not None: service_name = m.group(1) m = re.match(tnsname_re, orclNetDescString) tns_host = "NA" if m is not None: tns_host = m.group(1) svc_name_host = ("{0} {1}".format(service_name, tns_host)).lower() if svc_name_host not in self.combined_services: self.combined_services[svc_name_host] = {} self.combined_services[svc_name_host]["cn_list"] = [] self.combined_services[svc_name_host]["cn_list"].append(cn) self.combined_services[svc_name_host]["cn_str"] = (', '.join( sorted(self.combined_services[svc_name_host]["cn_list"]))) self.combined_services[svc_name_host]["tns_host"] = tns_host self.combined_services[svc_name_host][ "service_name"] = service_name # attributes we want to copy over from OracleLsnrctlServices # for sortability. transfer_keys = [ "instance", "verified_unix_time", "verified_date_time", "created_unix_time", "created_date_time" ] for key in transfer_keys: if key not in self.combined_services[svc_name_host]: self.combined_services[svc_name_host][key] = ""
def __init__(self, entry_tuple): """Create a new LDAPSearchResult object.""" #print 'Creating LDAPSearchResult item...' (dn, attrs) = entry_tuple if dn: self.dn = dn else: self.dn = '' return self.attrs = cidict(attrs)
def syncrepl_entry(self, dn, attributes, uuid): attributes = cidict(attributes) # First we determine the type of change we have here # (and store away the previous data for later if needed) previous_attributes = cidict() if uuid in self.__data['uuids']: change_type = 'modify' previous_attributes = self.__data['uuids'][uuid] else: change_type = 'add' # Now we store our knowledge of the existence of this entry # (including the DN as an attribute for convenience) attributes['dn'] = dn self.__data['uuids'][uuid] = attributes # Debugging self.log.debug('Detected %s of entry: %s %s', change_type, dn, uuid) if change_type == 'modify': self.application_sync(uuid, dn, attributes, previous_attributes) else: self.application_add(uuid, dn, attributes)
def find_one(self, dn): """根据DN获取条目""" self.begin() try: result = self.conn.search_s(dn, ldap.SCOPE_BASE) except ldap.NO_SUCH_OBJECT: return None if result is not None and len(result) > 0: dn, attrs = result[0] return dn, cidict(dict(attrs)) else: return None
def handle(self,dn,entry): new_entry = cidict(entry) objectClass_attrvalue = cidict() for oc in new_entry['objectClass']: if self._delete_object_classes.has_key(oc.lower()): continue if self._object_class_map.has_key(oc): for oc_new in self._object_class_map[oc]: objectClass_attrvalue[oc_new] = None else: objectClass_attrvalue[oc] = None new_entry['objectClass'] = objectClass_attrvalue.keys() # Sanitize new_entry's attributes for attr_type in new_entry.keys(): # Attributes to be deleted if self._delete_attr_types.has_key(attr_type): del new_entry[attr_type] continue if self._phonenumber_syntax.has_key(attr_type): new_entry[attr_type] = map(sanitize_phonenumber,new_entry[attr_type]) # Transform attributes holding DNs if self._dn_attr_types.has_key(attr_type): new_entry[attr_type] = map(self._transform_dn,new_entry[attr_type]) # Transform attribute type names if self._attr_type_map.has_key(attr_type): mapped_attr_type = self._attr_type_map[attr_type] if new_entry.has_key(mapped_attr_type): new_entry[mapped_attr_type].extend(new_entry[attr_type]) else: new_entry[mapped_attr_type] = new_entry[attr_type] del new_entry[attr_type] entry = {} entry.update(new_entry) ldif.LDIFCopy.handle(self,self._transform_dn(dn),entry)
def set_directory(self, directory, uri=URI_DEFAULT): """ Set the mock LDAP content for a given URI. :param uri: The LDAP URI to associate this content with. :type uri: string If URI is not given, this will set the default content for all unknown URIs. """ if self.ldap_objects is not None: raise Exception("You can't add a directory after calling start().") self.directories[uri] = cidict(map_keys(lambda s: s.lower(), directory))
def __init__( self, input_file, output_file, source_namingcontext, target_namingcontext, source_charset = 'utf-8', target_charset = 'utf-8', dn_attr_types=[], delete_object_classes=[], object_class_map={}, delete_attr_types=[], attr_type_map={} ): ldif.LDIFCopy.__init__(self,input_file,output_file) self.source_charset = source_charset self.target_charset = target_charset self.source_namingcontext = unicode( normalize_dn(source_namingcontext), source_charset ).lower() self.source_namingcontext_len = len(self.source_namingcontext) self.target_namingcontext = unicode( normalize_dn(target_namingcontext), target_charset ) self._dn_attr_types=cidict(list_dict(dn_attr_types)) self._delete_object_classes=cidict(list_dict(delete_object_classes)) self._object_class_map = cidict(object_class_map) self._delete_attr_types=cidict(list_dict(delete_attr_types)) self._attr_type_map = cidict(attr_type_map) self._phonenumber_syntax=list_dict([ 'telephoneNumber','facsimileTelephoneNumber','fax', 'homePhone','homeTelephoneNumber','mobile','mobileTelephoneNumber', 'pager','pagerTelephoneNumber', ])
def ochasattr(subschema, oc, mustormay, attr, key): """See if the oc and any of its parents and ancestors have the given attr""" rc = False if not key in oc.__dict__: dd = cidict() for ii in oc.__dict__[mustormay]: dd[ii] = ii oc.__dict__[key] = dd if attr in oc.__dict__[key]: rc = True else: # look in parents for noroid in oc.sup: ocpar = subschema.get_obj(occlass, noroid) assert(ocpar) rc = ochasattr(subschema, ocpar, mustormay, attr, key) if rc: break return rc
def ochasattr(subschema, oc, mustormay, attr, key): """See if the oc and any of its parents and ancestors have the given attr""" rc = False if not key in oc.__dict__: dd = cidict() for ii in oc.__dict__[mustormay]: dd[ii] = ii oc.__dict__[key] = dd if attr in oc.__dict__[key]: rc = True else: # look in parents for noroid in oc.sup: ocpar = subschema.get_obj(occlass, noroid) assert (ocpar) rc = ochasattr(subschema, ocpar, mustormay, attr, key) if rc: break return rc
def find_all(self, base_dn, filters, limit=0, skip=0): """查询条目""" result_id = self.conn.search(base_dn, ldap.SCOPE_SUBTREE, filters) count = 0 while True: count += 1 if limit != 0 and count >= limit: break try: result_type, result_data = self.conn.result(result_id, 0) except ldap.NO_SUCH_OBJECT: break if count <= skip: continue if result_type == ldap.RES_SEARCH_ENTRY: dn = result_data[0][0] attrs = cidict(dict(result_data[0][1])) yield dn, attrs else: break
def set_directory(self, directory, uri=URI_DEFAULT): """ Set the mock LDAP content for a given URI. :param uri: The LDAP URI to associate this content with. :type uri: string If URI is not given, this will set the default content for all unknown URIs. """ if self.ldap_objects is not None: raise Exception("You can't add a directory after calling start().") for obj in directory.values(): for attr in obj.values(): if any(not isinstance(_, bytes) for _ in attr): raise TypeError("expected a byte string in the list") self.directories[uri] = cidict(map_keys(lambda s: s.lower(), directory))
def add_s(self, dn, modlist): if self.invalid: raise LDAPError('LDAP connection invalid') if self.bound is None or (_requires_auth(self.conn_str) and self.bound == 'ANONYMOUS'): raise STRONG_AUTH_REQUIRED({ 'info': 'modifications require authentication', 'desc': 'Strong(er) authentication required' }) elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE[self.conn_str] for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise NO_SUCH_OBJECT if tree_pos.has_key(rdn): raise ALREADY_EXISTS else: k, v = rdn.split('=') # tree_pos[rdn] = {'dn': dn, k: [v]} tree_pos[rdn] = cidict({'dn': dn, k: [v]}) rec = tree_pos[rdn] for key, val in modlist: if isinstance(val, list): rec[key] = val else: rec[key] = [val]
def processOracleLsnrctlServices(self): dn = "cn=OracleLsnrctlServices,ou=applications,dc=apidb,dc=org" scope = ldap.SCOPE_SUBTREE attrlist = [ "cn", "orclNetServer", "orclNetServiceName", "orclNetInstanceName", "orclVersion", "verifiedTimestamp", "createtimestamp" ] if self.host_filter is None: filterstr = "(objectclass=orclNetDescription)" else: filterstr = "(&(objectclass=orclNetDescription)(orclNetServer={0}))".format( self.host_filter) result_set = self.search(dn, ldap.SCOPE_ONELEVEL, attrlist, filterstr) if result_set is None: return for result in result_set: srvc_entries = cidict(result[1]) orclNetServiceName = srvc_entries["orclnetservicename"][0].decode( "utf-8").strip() orclNetServer = srvc_entries["orclnetserver"][0].decode( "utf-8").strip() orclNetInstanceName = srvc_entries["orclnetinstancename"][ 0].decode("utf-8").strip() svcNameHost = ("{0} {1}".format(orclNetServiceName, orclNetServer)).lower() verifiedTimestamp = srvc_entries["verifiedtimestamp"][0].decode( "utf-8") verified_date_obj = datetime.strptime(verifiedTimestamp, "%Y%m%d%H%M%SZ") verified_unix_time = (verified_date_obj - datetime(1970, 1, 1)).total_seconds() verified_date_time = self.time_since(verified_date_obj) createTimestamp = srvc_entries["createtimestamp"][0].decode( "utf-8") created_date_obj = datetime.strptime(createTimestamp, "%Y%m%d%H%M%SZ") created_date_time = datetime.strftime(created_date_obj, "%-d %b %Y") created_unix_time = (created_date_obj - datetime(1970, 1, 1)).total_seconds() #print("{0} ago".format(verified_date_time)) #print("{0}".format(svcNameHost)) self.combined_services[svcNameHost] = {} self.combined_services[svcNameHost]["cn_list"] = [] self.combined_services[svcNameHost]["tns_host"] = orclNetServer self.combined_services[svcNameHost][ "service_name"] = orclNetServiceName self.combined_services[svcNameHost][ "redmine_link"] = self.make_redmine_link(orclNetServiceName) self.combined_services[svcNameHost][ "instance"] = orclNetInstanceName self.combined_services[svcNameHost][ "created_unix_time"] = created_unix_time self.combined_services[svcNameHost][ "created_date_time"] = created_date_time self.combined_services[svcNameHost][ "verified_date_time"] = verified_date_time self.combined_services[svcNameHost][ "verified_unix_time"] = verified_unix_time # for sorting
'OPT_X_TLS_KEYFILE', 'OPT_X_TLS_NEVER', 'OPT_X_TLS_RANDOM_FILE', 'OPT_X_TLS_REQUIRE_CERT', 'OPT_X_TLS_TRY', ] for import_el in _to_import: setattr(__module__, import_el, getattr(ldap, import_el)) class modlist(object): addModlist = addModlist TREE = cidict() ########################## ### PUBLIC API ### ########################## def initialize(conn_str): """ Initialize a new connection """ return _FakeLDAPConnection(conn_str) def set_option(option, invalue): pass def explode_dn(dn, *ign, **ignored):
def set_attributes(self, attr_dict): self.attrs = cidict(attr_dict)
def query(self, query): import ldap from ldap.cidict import cidict ldap_options = cidict() attribute_map = cidict() query_map = cidict() answer = [] for k, v in self.options: ldap_options[k] = v if k.endswith('_attribute'): # dict with qery type in keys end ldap attribute in value attribute_map[k.split('_attribute')[0]] = v # vice-versa query_map[v] = k.split('_attribute')[0] if "ttl_default" not in ldap_options: self.logger.error("[LDAP] ttl_default not defined in ldap attributes mapping") sys.exit(-1) if "cname_attribute" not in ldap_options: self.logger.error("[LDAP] cname_attribute not defined in ldap attributes mapping") sys.exit(-1) try: ldap_conn = ldap.initialize(ldap_options['ldap_uri']) if ldap_options.has_key("bind") and (ldap_options['bind'] == "True" or ldap_options['bind'] == "1"): self.logger.debug("[LDAP] trying to bind to ldap server using credentials") ldap_conn.simple_bind_s(ldap_options['bind_dn'], ldap_options['bind_password']) self.logger.debug("[LDAP] bind successful") else: self.logger.debug("[LDAP] accessing to ldap server anonymously") # TODO: if 'dot_in_dn' in ldap_options: dn_token = ",%s=" % ldap_options['dot_in_dn'] q = ".%s" % query.qname qname_dn = dn_token.join(q.split(".")).lstrip(',') else: qname_dn = "UNDEFINED" ldap_base = ldap_options['base'] % ({'qname': query.qname, 'qtype': query.qtype, 'remote_ip': query.remote_ip, 'local_ip': query.local_ip, 'qname_dn': qname_dn}) self.logger.debug("formatted base: %s" % ldap_base) ldap_query = ldap_options['query'] % ({ 'qname': query.qname, 'qtype': query.qtype, 'remote_ip': query.remote_ip, 'local_ip': query.local_ip, 'rqname': query.rqname }) ldap_query = ldap_query.replace("*", "\*") self.logger.debug("[LDAP] formatted query: %s" % ldap_query) if query.qtype.lower() == "any": attributes = query_map.keys() else: if query.qtype.lower() not in attribute_map.keys(): self.logger.warning("[LDAP] attribute for query %s not found in map" % query.qtype) return answer attributes = [attribute_map[query.qtype]] attributes.append(ldap_options['ttl_attribute']) attributes.append(ldap_options['cname_attribute']) self.logger.debug("[LDAP] attributes: %s" % attributes) #TODO: scope in config file try: res = ldap_conn.search_s(ldap_base, ldap.SCOPE_SUBTREE , ldap_query, attributes) except Exception, e: self.logger.info("[LDAP] ldap query error: %s", e) return answer for entry in res: # search for ttl attribute in LDAP otherwise use default_ttl if ldap_options['ttl_attribute'] not in entry[1].keys(): self.logger.debug("[LDAP] ttl entry (%s) not found, using default: %s" % (ldap_options['ttl_attribute'], ldap_options['ttl_default'])) ttl = int(ldap_options['ttl_default']) else: ttl = int(entry[1][ldap_options['ttl_attribute']][0]) # compose the answer for attribute in entry[1].keys(): for att in entry[1][attribute]: self.logger.debug("[LDAP] found data in database: %s" % att) answer.append(DNSAnswer(query.qname, "IN", query_map[attribute].upper(), ttl, 1, att))
# ldap.cidict -> case insensitive dictionary # attrs = cidict(attrs) from ldap.cidict import cidict print cidict({'cn': 'Klaus Mustermann', 'mailAlternateAddress': '*****@*****.**'})
lobj = ldap.initialize("ldap://{}".format(random.choice(cmdlargs.c))) lobj.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) lobj.set_option(ldap.OPT_NETWORK_TIMEOUT, 5) lobj.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) # Do not chase referrals, this doesn't work with AD and slows down the search lres = None # Get rid of an IDE warning when a var can be undefined coz its first assignment is in try-block # Get RootDSE try: lres = lobj.search_s(base="", scope=ldap.SCOPE_BASE, attrlist=("defaultNamingContext", "configurationNamingContext", "domainFunctionality", "serverName", "dnsHostName")) except ldap.LDAPError: handle_ldap_exception(sys.exc_info()) rootDSE = cidict(lres[0][1]) domain_functionality = {"0":"WIN2000", "1":"WIN2003 WITH MIXED DOMAINS", "2":"WIN2003", "3":"WIN2008", "4":"WIN2008R2", "5":"WIN2012", "6":"WIN2012R2", "7":"WIN2016"} current_domain_functionality = "UNKNOWN" try: current_domain_functionality = domain_functionality[rootDSE["domainFunctionality"][0]] except KeyError: pass print "Connected to the LDAP at {}".format(rootDSE["dnsHostName"][0]) print "Current domain functionality is {}\n".format(current_domain_functionality) # Bind try: lobj.bind_s(cmdlargs.u, cmdlargs.p) except ldap.LDAPError:
'OPT_X_TLS_ALLOW', 'OPT_X_TLS_CACERTDIR', 'OPT_X_TLS_CACERTFILE', 'OPT_X_TLS_CERTFILE', 'OPT_X_TLS_CIPHER_SUITE', 'OPT_X_TLS_CRLCHECK', 'OPT_X_TLS_CRL_ALL', 'OPT_X_TLS_CRL_NONE', 'OPT_X_TLS_CRL_PEER', 'OPT_X_TLS_CTX', 'OPT_X_TLS_DEMAND', 'OPT_X_TLS_HARD', 'OPT_X_TLS_KEYFILE', 'OPT_X_TLS_NEVER', 'OPT_X_TLS_RANDOM_FILE', 'OPT_X_TLS_REQUIRE_CERT', 'OPT_X_TLS_TRY', ] for import_el in _to_import: setattr(__module__, import_el, getattr(ldap, import_el)) class modlist(object): addModlist = addModlist TREE = cidict() ########################## ### PUBLIC API ### ########################## def initialize(conn_str): """ Initialize a new connection """ return _FakeLDAPConnection(conn_str) def set_option(option, invalue): pass def explode_dn(dn, *ign, **ignored): """ Get a DN's elements """ return [x.strip() for x in dn.split(',')]