def setUp(self): self.ldap = LDAPObject(self.server.ldap_uri, bytes_mode=False) self.ldap.protocol_version = 3 self.ldap.set_option(ldap.OPT_REFERRALS, 0) self.ldap.simple_bind_s( self.server.root_dn, self.server.root_pw )
def initialize(uri, trace_level=0, trace_file=sys.stdout, trace_stack_limit=None, bytes_mode=None, raise_for_result=RAISE_ALL, **kwargs): """ Return LDAPObject instance by opening LDAP connection to LDAP host specified by LDAP URL Parameters: uri LDAP URL containing at least connection scheme and hostport, e.g. ldap://localhost:389 trace_level If non-zero a trace output of LDAP calls is generated. trace_file File object where to write the trace output to. Default is to use stdout. bytes_mode Whether to enable :ref:`bytes_mode` for backwards compatibility under Py2. Additional keyword arguments (such as ``bytes_strictness``) are passed to ``LDAPObject``. """ return LDAPObject(uri, trace_level, trace_file, trace_stack_limit, bytes_mode, raise_for_result, **kwargs)
def _get_bytes_ldapobject(self, explicit=True): if explicit: kwargs = {'bytes_mode': True} else: kwargs = {} l = LDAPObject(server.get_url(), **kwargs) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(self.server.get_root_dn().encode('utf-8'), self.server.get_root_password().encode('utf-8')) return l
def initialize(uri,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None): """ Return LDAPObject instance by opening LDAP connection to LDAP host specified by LDAP URL Parameters: uri LDAP URL containing at least connection scheme and hostport, e.g. ldap://localhost:389 trace_level If non-zero a trace output of LDAP calls is generated. trace_file File object where to write the trace output to. Default is to use stdout. """ return LDAPObject(uri,trace_level,trace_file,trace_stack_limit)
def _get_bytes_ldapobject(self, explicit=True): if explicit: kwargs = {'bytes_mode': True} else: kwargs = {} l = LDAPObject(server.get_url(), **kwargs) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) l.simple_bind_s(self.server.get_root_dn().encode('utf-8'), self.server.get_root_password().encode('utf-8')) return l
class Add(object): ''' Description: -------------------------------------------------------- Add a user to a group -------------------------------------------------------- ''' def __init__(self, server, user_email, password, dc, port = 389): self.dc = dc self.server = server self.port = port self.user_email = user_email self.pwd = password self.logger = logging.getLogger("ADQueryLogger") self.uri = 'ldap://' + self.server + ':' + str(self.port) def __connect(self): self.ldap_obj = LDAPObject(self.uri) self.ldap_obj.protocol_version = ldap.VERSION3 self.ldap_obj.set_option(ldap.OPT_REFERRALS,0) self.ldap_obj.simple_bind_s(self.user_email, self.pwd) def __disconnect(self): self.ldap_obj.unbind_ext_s() def add_group(self, gp_dn, user_dn): self.__connect() attrib = ([(ldap.MOD_ADD,'member', user_dn)]) success = False print type(gp_dn), gp_dn print type(user_dn), user_dn try: self.ldap_obj.modify_s(gp_dn, attrib) success = True except Exception, e: print e finally:
def setUp(self): global server if server is None: server = SlapdObject() server.start() base = server.suffix suffix_dc = base.split(',')[0][3:] # insert some Foo* objects via ldapadd server.ldapadd("\n".join([ 'dn: ' + server.suffix, 'objectClass: dcObject', 'objectClass: organization', 'dc: ' + suffix_dc, 'o: ' + suffix_dc, '', 'dn: ' + server.root_dn, 'objectClass: applicationProcess', 'cn: ' + server.root_cn, '', "dn: cn=Foo1," + base, "objectClass: organizationalRole", "cn: Foo1", "", "dn: cn=Foo2," + base, "objectClass: organizationalRole", "cn: Foo2", "", "dn: cn=Foo3," + base, "objectClass: organizationalRole", "cn: Foo3", "", "dn: ou=Container," + base, "objectClass: organizationalUnit", "ou: Container", "", "dn: cn=Foo4,ou=Container," + base, "objectClass: organizationalRole", "cn: Foo4", "", ]) + "\n") l = LDAPObject(server.ldap_uri, bytes_mode=False) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(server.root_dn, server.root_pw) self.ldap = l self.server = server
def search_ext(self, base, scope, filterstr='(objectClass=*)', attrlist=None, attrsonly=0, serverctrls=None, clientctrls=None, timeout=-1, sizelimit=0, offset=None, length=None, ordering=None, context_id=None): assert not (offset and length) or ordering, 'if VLV is used ordering is mandatory' assert not ((offset is not None) ^ (length is not None)), 'offset and length must be set on unset at the same time' serverctrls = serverctrls or [] clientctrls = [] if ordering: serverctrls.append(SSSRequestControl(ordering, criticality=True)) if offset is not None: serverctrls.append(VLVRequestControl(offset=offset, after_count=length, content_count=0, criticality=True, context_id=context_id)) self.vlv = True result = LDAPObject.search_ext(self, base, scope, filterstr, attrlist, attrsonly, serverctrls, clientctrls, timeout, sizelimit) del self.vlv return result
def initialize(uri, trace_level=0, trace_file=sys.stdout, trace_stack_limit=None, bytes_mode=None): """ Return LDAPObject instance by opening LDAP connection to LDAP host specified by LDAP URL Parameters: uri LDAP URL containing at least connection scheme and hostport, e.g. ldap://localhost:389 trace_level If non-zero a trace output of LDAP calls is generated. trace_file File object where to write the trace output to. Default is to use stdout. bytes_mode Whether to enable :ref:`bytes_mode` for backwards compatibility under Py2. """ return LDAPObject(uri, trace_level, trace_file, trace_stack_limit, bytes_mode)
def search_ext(self, base, scope, filterstr='(objectClass=*)', attrlist=None, attrsonly=0, serverctrls=None, clientctrls=None, timeout=-1, sizelimit=0, offset=None, length=None, ordering=None, context_id=None): assert not (offset and length) or ordering, 'if VLV is used ordering is mandatory' assert not ( (offset is not None) ^ (length is not None) ), 'offset and length must be set on unset at the same time' serverctrls = serverctrls or [] clientctrls = [] if ordering: serverctrls.append(SSSRequestControl(ordering, criticality=True)) if offset is not None: serverctrls.append( VLVRequestControl(offset=offset, after_count=length, content_count=0, criticality=True, context_id=context_id)) self.vlv = True result = LDAPObject.search_ext(self, base, scope, filterstr, attrlist, attrsonly, serverctrls, clientctrls, timeout, sizelimit) del self.vlv return result
def setUp(self): global server if server is None: server = slapd.Slapd() server.start() base = server.get_dn_suffix() # insert some Foo* objects via ldapadd server.ldapadd("\n".join([ "dn: cn=Foo1,"+base, "objectClass: organizationalRole", "cn: Foo1", "", "dn: cn=Foo2,"+base, "objectClass: organizationalRole", "cn: Foo2", "", "dn: cn=Foo3,"+base, "objectClass: organizationalRole", "cn: Foo3", "", "dn: ou=Container,"+base, "objectClass: organizationalUnit", "ou: Container", "", "dn: cn=Foo4,ou=Container,"+base, "objectClass: organizationalRole", "cn: Foo4", "", ])+"\n") l = LDAPObject(server.get_url()) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) l.simple_bind_s(server.get_root_dn(), server.get_root_password()) self.ldap = l self.server = server
def __connect(self): self.ldap_obj = LDAPObject(self.uri) self.ldap_obj.protocol_version = ldap.VERSION3 self.ldap_obj.set_option(ldap.OPT_REFERRALS,0) self.ldap_obj.simple_bind_s(self.user_email, self.pwd)
def main(): adhost = 'w2k8x8664.testdomain.com' adport = 389 aduri = "ldap://%s:%d/" % (adhost, adport) suffix = "DC=testdomain,DC=com" name = sys.argv[1] pwd = sys.argv[2] # adroot = "cn=Dirsync User,cn=users," + suffix # adrootpw = "Secret123" adroot = "cn=%s,cn=users,%s" % (name, suffix) adrootpw = pwd verbose = False # ldap.set_option(ldap.OPT_DEBUG_LEVEL, 15) ad = LDAPObject(aduri) ad.simple_bind_s(adroot, adrootpw) # do initial dirsync search to get entries and the initial dirsync # cookie scope = ldap.SCOPE_SUBTREE filt = '(objectclass=*)' attrlist = None dirsyncctrl = DirSyncCtrl() page_size = 1000 lc = SimplePagedResultsControl( ldap.LDAP_CONTROL_PAGE_OID,True,(page_size,'') ) serverctrls = [dirsyncctrl, lc] msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) initiallist = {} # the dirsync control is returned with the LDAP_RES_SEARCH_RESULT # def result3(self,msgid=_ldap.RES_ANY,all=1,timeout=None): while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) for dn, ent in rdata: print "dn: ", dn if verbose: pprint.pprint(ent) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break # now search again with the updated dirsync control # we should get back no results since nothing in AD # has changed msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) if len(rdata) > 0: print "Nothing changed but something was returned????" pprint.pprint(rdata) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break print "Change something on the AD side, and press Enter" sys.stdin.readline() print "Searching for changes . . ." msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) for dn, ent in rdata: print "dn: ", dn pprint.pprint(ent) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break
'who':'bindname', 'cred':'X-BINDPW', 'start_tls':'startTLS', 'trace_level':'trace', } ldap_url = MyLDAPUrl(sys.argv[1]) trace_level = int(ldap_url.trace_level or '0') print '***trace_level',trace_level ldap.trace_level = trace_level l = LDAPObject( ldap_url.initializeUrl(), trace_level=trace_level, ) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) l.simple_bind_s((ldap_url.who or ''),(ldap_url.cred or '')) msgid = l.search( ldap_url.dn, ldap_url.scope or ldap.SCOPE_SUBTREE, ldap_url.filterstr or '(objectClass=*)', ldap_url.attrs or ['*'] ) print "msgid=",msgid count = 0
import sys,os,time,ldap from ldap.ldapobject import LDAPObject from ldapurl import LDAPUrl try: ldap_url = LDAPUrl(sys.argv[1]) num_tests = int(sys.argv[2]) except IndexError: print 'Usage: pref_test.py <LDAP URL> <number of tests>' sys.exit(1) iter = num_tests start_time = time.time() l = LDAPObject(ldap_url.initializeUrl(),trace_level=0) l.protocol_version = 3 l.simple_bind_s(ldap_url.who or '',ldap_url.cred or '') while iter: l.search_s( ldap_url.dn, ldap_url.scope or ldap.SCOPE_BASE, ldap_url.filterstr or '(objectClass=*)', ldap_url.attrs or ['*'] ) iter -= 1 end_time = time.time()
def main(): adhost = 'w2k8x8664.testdomain.com' adport = 389 aduri = "ldap://%s:%d/" % (adhost, adport) suffix = "DC=testdomain,DC=com" name = sys.argv[1] pwd = sys.argv[2] # adroot = "cn=Dirsync User,cn=users," + suffix # adrootpw = "Secret123" adroot = "cn=%s,cn=users,%s" % (name, suffix) adrootpw = pwd verbose = False # ldap.set_option(ldap.OPT_DEBUG_LEVEL, 15) ad = LDAPObject(aduri) ad.simple_bind_s(adroot, adrootpw) # do initial dirsync search to get entries and the initial dirsync # cookie scope = ldap.SCOPE_SUBTREE filt = '(objectclass=*)' attrlist = None dirsyncctrl = DirSyncCtrl() page_size = 1000 lc = SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True, (page_size, '')) serverctrls = [dirsyncctrl, lc] msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) initiallist = {} # the dirsync control is returned with the LDAP_RES_SEARCH_RESULT # def result3(self,msgid=_ldap.RES_ANY,all=1,timeout=None): while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) for dn, ent in rdata: print "dn: ", dn if verbose: pprint.pprint(ent) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break # now search again with the updated dirsync control # we should get back no results since nothing in AD # has changed msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) if len(rdata) > 0: print "Nothing changed but something was returned????" pprint.pprint(rdata) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break print "Change something on the AD side, and press Enter" sys.stdin.readline() print "Searching for changes . . ." msgid = ad.search_ext(suffix, scope, filt, attrlist, 0, serverctrls) while True: (rtype, rdata, rmsgid, decoded_serverctrls) = ad.result3(msgid) print "Search returned %d results" % len(rdata) for dn, ent in rdata: print "dn: ", dn pprint.pprint(ent) if rtype == ldap.RES_SEARCH_RESULT: dirsyncctrl.update(decoded_serverctrls) break
def main(): uri = os.environ["URI1"] managerdn = os.environ['MANAGERDN'] passwd = os.environ['PASSWD'] babsdn = os.environ['BABSDN'] babspw = b"bjensen" bjornsdn = os.environ['BJORNSDN'] bjornspw = b"bjorn" connection = LDAPObject(uri) start = time.time() connection.bind_s(managerdn, passwd) end = time.time() if end - start > 1: print( "It takes more than a second to connect and bind, " "skipping potentially unstable test", file=sys.stderr) raise SystemExit(0) dn, token_entry = get_token_for(connection, babsdn) paramsdn = token_entry['oathTOTPParams'][0].decode() result = connection.search_s(paramsdn, ldap.SCOPE_BASE) _, attrs = result[0] params = CIDict(attrs) secret = token_entry['oathSecret'][0] period = int(params['oathTOTPTimeStepPeriod'][0].decode()) bind_conn = LDAPObject(uri) interval_no = get_interval(period) token = get_hotp_token(secret, interval_no - 3) print("Testing old tokens are not useable") bind_conn.bind_s(babsdn, babspw + token) try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: pass else: raise SystemExit("Bind with an old token should have failed") interval_no = get_interval(period) token = get_hotp_token(secret, interval_no) print("Testing token can only be used once") bind_conn.bind_s(babsdn, babspw + token) try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: pass else: raise SystemExit("Bind with a reused token should have failed") token = get_hotp_token(secret, interval_no + 1) try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: raise SystemExit("Bind should have succeeded") dn, token_entry = get_token_for(connection, babsdn) last = int(token_entry['oathTOTPLastTimeStep'][0].decode()) if last != interval_no + 1: SystemExit("Unexpected counter value %d (expected %d)" % (last, interval_no + 1)) print("Resetting counter and testing secret sharing between accounts") connection.modify_s(dn, [(ldap.MOD_REPLACE, 'oathTOTPLastTimeStep', [])]) interval_no = get_interval(period) token = get_hotp_token(secret, interval_no) try: bind_conn.bind_s(bjornsdn, bjornspw + token) except ldap.INVALID_CREDENTIALS: raise SystemExit("Bind should have succeeded") try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: pass else: raise SystemExit("Bind with a reused token should have failed") print("Testing token is retired even with a wrong password") connection.modify_s(dn, [(ldap.MOD_REPLACE, 'oathTOTPLastTimeStep', [])]) interval_no = get_interval(period) token = get_hotp_token(secret, interval_no) try: bind_conn.bind_s(babsdn, b"not the password" + token) except ldap.INVALID_CREDENTIALS: pass else: raise SystemExit("Bind with an incorrect password should have failed") try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: pass else: raise SystemExit("Bind with a reused token should have failed") token = get_hotp_token(secret, interval_no + 1) try: bind_conn.bind_s(babsdn, babspw + token) except ldap.INVALID_CREDENTIALS: raise SystemExit("Bind should have succeeded")
def __init__(self, uri, base_dn, bind_dn, pw): self.base_dn = base_dn self._ldap = LDAPObject(uri) self._ldap.bind_s(bind_dn, pw)
class EditionTests(SlapdTestCase): @classmethod def setUpClass(cls): super().setUpClass() base = cls.server.suffix suffix_dc = base.split(',')[0][3:] # insert some Foo* objects via ldapadd cls.server.ldapadd("\n".join([ 'dn: '+cls.server.suffix, 'objectClass: dcObject', 'objectClass: organization', 'dc: '+suffix_dc, 'o: '+suffix_dc, '', 'dn: '+cls.server.root_dn, 'objectClass: applicationProcess', 'cn: '+cls.server.root_cn, '', "dn: cn=Foo1,"+base, "objectClass: organizationalRole", "cn: Foo1", "", "dn: cn=Foo2,"+base, "objectClass: organizationalRole", "cn: Foo2", "", "dn: cn=Foo3,"+base, "objectClass: organizationalRole", "cn: Foo3", "", "dn: ou=Container,"+base, "objectClass: organizationalUnit", "ou: Container", "", "dn: cn=Foo4,ou=Container,"+base, "objectClass: organizationalRole", "cn: Foo4", "", ])+"\n") def setUp(self): self.ldap = LDAPObject(self.server.ldap_uri, bytes_mode=False) self.ldap.protocol_version = 3 self.ldap.set_option(ldap.OPT_REFERRALS, 0) self.ldap.simple_bind_s( self.server.root_dn, self.server.root_pw ) def tearDown(self): self.ldap.unbind() def test_add_object(self): base = self.server.suffix dn = "cn=Added,ou=Container," + base self.ldap.add_ext_s(dn, [ ("objectClass", [b'organizationalRole']), ("cn", [b'Added']), ]) # Lookup the object result = self.ldap.search_s(base, ldap.SCOPE_SUBTREE, '(cn=Added)', ['*']) self.assertEqual(result, [ ("cn=Added,ou=Container," + base, {'cn': [b'Added'], 'objectClass': [b'organizationalRole']}), ]) # Delete object self.ldap.delete_s(dn) result = self.ldap.search_s( base, ldap.SCOPE_SUBTREE, '(cn=Added)', ['*'] ) self.assertEqual(result, [])
'who': 'bindname', 'cred': 'X-BINDPW', 'start_tls': 'startTLS', 'trace_level': 'trace', } ldap_url = MyLDAPUrl(sys.argv[1]) trace_level = int(ldap_url.trace_level or '0') print('***trace_level', trace_level) ldap.trace_level = trace_level l = LDAPObject( ldap_url.initializeUrl(), trace_level=trace_level, ) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s((ldap_url.who or ''), (ldap_url.cred or '')) result = l.search_s(ldap_url.dn, ldap_url.scope or ldap.SCOPE_SUBTREE, ldap_url.filterstr or '(objectClass=*)', ldap_url.attrs or ['*']) pprint.pprint(result) print('***DIAGNOSTIC_MESSAGE', repr(l.get_option(ldap.OPT_DIAGNOSTIC_MESSAGE))) l.unbind_s()
'who':'bindname', 'cred':'X-BINDPW', 'start_tls':'startTLS', 'trace_level':'trace', } ldap_url = MyLDAPUrl(sys.argv[1]) trace_level = int(ldap_url.trace_level or '0') print('***trace_level',trace_level) ldap.trace_level = trace_level l = LDAPObject( ldap_url.initializeUrl(), trace_level=trace_level, ) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) l.simple_bind_s((ldap_url.who or ''),(ldap_url.cred or '')) result = l.search_s( ldap_url.dn, ldap_url.scope or ldap.SCOPE_SUBTREE, ldap_url.filterstr or '(objectClass=*)', ldap_url.attrs or ['*'] ) pprint.pprint(result)
def _get_ldapobject(self, bytes_mode=None): l = LDAPObject(self.server.ldap_uri, bytes_mode=bytes_mode) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS,0) return l
import sys, os, time, ldap from ldap.ldapobject import LDAPObject from ldapurl import LDAPUrl try: ldap_url = LDAPUrl(sys.argv[1]) num_tests = int(sys.argv[2]) except IndexError: print 'Usage: pref_test.py <LDAP URL> <number of tests>' sys.exit(1) iter = num_tests start_time = time.time() l = LDAPObject(ldap_url.initializeUrl(), trace_level=0) l.protocol_version = 3 l.simple_bind_s(ldap_url.who or '', ldap_url.cred or '') while iter: l.search_s(ldap_url.dn, ldap_url.scope or ldap.SCOPE_BASE, ldap_url.filterstr or '(objectClass=*)', ldap_url.attrs or ['*']) iter -= 1 end_time = time.time() l.unbind_s() del l print 'Reusing connection:', end_time - start_time
class Directory(object): """XXX: this could be without base_dn, not supporting iteration """ def __init__(self, uri, base_dn, bind_dn, pw): self.base_dn = base_dn self._ldap = LDAPObject(uri) self._ldap.bind_s(bind_dn, pw) def __contains__(self, dn): try: return dn == self._ldap.search_s(dn, SCOPE_BASE, attrlist=[''])[0][0] except ldap.NO_SUCH_OBJECT: return False def __getitem__(self, dn): try: entry = self._ldap.search_s(dn, SCOPE_BASE)[0] except ldap.NO_SUCH_OBJECT: raise KeyError(dn) node = Node(name=dn, attrs=entry[1], ldap=self._ldap) return node def __setitem__(self, dn, node): addlist = node.attrs.items() try: self._ldap.add_s(dn, addlist) except ldap.ALREADY_EXISTS: del self[dn] self._ldap.add_s(dn, addlist) def __delitem__(self, dn): try: self._ldap.delete_s(dn) except ldap.NO_SUCH_OBJECT: raise KeyError(dn) def __iter__(self): return (x[0][0] for x in self._search(self.base_dn, SCOPE_SUBTREE) if x[0][0] != self.base_dn) def _search(self, base, scope, filterstr='(objectClass=*)', attrlist=None, timeout=-1): """asynchronous ldap search returning a generator """ msgid = self._ldap.search(base, scope, filterstr=filterstr, attrlist=attrlist) rtype = ldap.RES_SEARCH_ENTRY while rtype is ldap.RES_SEARCH_ENTRY: # Fetch results single file, the final result (usually) # has an empty field. <sigh> (rtype, data) = self._ldap.result(msgid=msgid, all=0, timeout=timeout) if rtype is ldap.RES_SEARCH_ENTRY or data: yield data def items(self): return ItemsView(dictionary=self) def keys(self): return KeysView(dictionary=self) def values(self): return ValuesView(dictionary=self) def __len__(self): return sum(1 for node in iter(self)) def clear(self): for dn in self.keys(): del self[dn] def copy(self): return copy.copy(self) def get(self, dn, default=None): try: return self[dn] except KeyError: return default def pop(self, dn, default=None): try: node = self[dn] del self[dn] except KeyError: if default is None: raise KeyError(dn) return default return node def popitem(self): if not self: raise KeyError dn = next(iter(self)) node = self[dn] del self[dn] return (dn, node) def setdefault(self, dn, default=None): try: return self[dn] except KeyError: self[default.name] = default return default def update(self, other): try: items = other.items() except AttributeError: items = other for dn, node in items: self[dn] = node return None iterkeys = __iter__ def itervalues(self): return (Node(name=x[0][0], attrs=x[0][1], ldap=self._ldap) for x in self._search(self.base_dn, ldap.SCOPE_SUBTREE, attrlist=['']) if x[0][0] != self.base_dn) def iteritems(self): return ((node.name, node) for node in ValuesView(self))