def dn_exists(self, dn): mapping_location = self.get_backend_location_for_dn(dn) if mapping_location in (BackendTypes.MYSQL, BackendTypes.PGSQL): base.logIt("Querying RDBM for dn {}".format(dn)) result = self.get_sqlalchObj_for_dn(dn) if result: return result.__dict__ return elif mapping_location == BackendTypes.LDAP: base.logIt("Querying LDAP for dn {}".format(dn)) result = self.ldap_conn.search(search_base=dn, search_filter='(objectClass=*)', search_scope=ldap3.BASE, attributes=['*']) if result: key, document = ldif_utils.get_document_from_entry(self.ldap_conn.response[0]['dn'], self.ldap_conn.response[0]['attributes']) return document else: bucket = self.get_bucket_for_dn(dn) key = ldif_utils.get_key_from(dn) n1ql = 'SELECT * FROM `{}` USE KEYS "{}"'.format(bucket, key) result = self.cbm.exec_query(n1ql) if result.ok: data = result.json() if data.get('results'): return data['results'][0][bucket] return
def get_backend_location_for_dn(self, dn): key = ldif_utils.get_key_from(dn) group = self.get_group_for_key(key) if Config.mappingLocations[group] == 'ldap': return static.BackendTypes.LDAP if Config.mappingLocations[group] == 'couchbase': return static.BackendTypes.COUCHBASE
def get_backend_location_for_dn(self, dn): key = ldif_utils.get_key_from(dn) group = self.get_group_for_key(key) if Config.mappingLocations[group] == 'ldap': return static.BackendTypes.LDAP if Config.mappingLocations[group] == 'rdbm': if Config.rdbm_type == 'mysql': return static.BackendTypes.MYSQL elif Config.rdbm_type == 'pgsql': return static.BackendTypes.PGSQL if Config.mappingLocations[group] == 'couchbase': return static.BackendTypes.COUCHBASE
def search(self, search_base, search_filter='(objectClass=*)', search_scope=ldap3.LEVEL): base.logIt("Searching database for dn {} with filter {}".format( search_base, search_filter)) backend_location = self.get_backend_location_for_dn(search_base) if backend_location == BackendTypes.LDAP: if self.ldap_conn.search(search_base=search_base, search_filter=search_filter, search_scope=search_scope, attributes=['*']): key, document = ldif_utils.get_document_from_entry( self.ldap_conn.response[0]['dn'], self.ldap_conn.response[0]['attributes']) return document if backend_location == BackendTypes.COUCHBASE: key = ldif_utils.get_key_from(search_base) bucket = self.get_bucket_for_key(key) if search_scope == ldap3.BASE: n1ql = 'SELECT * FROM `{}` USE KEYS "{}"'.format(bucket, key) else: parsed_dn = dnutils.parse_dn( search_filter.strip('(').strip(')')) attr = parsed_dn[0][0] val = parsed_dn[0][1] if '*' in val: search_clause = 'LIKE "{}"'.format(val.replace('*', '%')) else: search_clause = '="{}"'.format(val.replace('*', '%')) n1ql = 'SELECT * FROM `{}` WHERE `{}` {}'.format( bucket, attr, search_clause) result = self.cbm.exec_query(n1ql) if result.ok: data = result.json() if data.get('results'): return data['results'][0][bucket]
def search(self, search_base, search_filter='(objectClass=*)', search_scope=ldap3.LEVEL, fetchmany=False): base.logIt("Searching database for dn {} with filter {}".format(search_base, search_filter)) backend_location = self.get_backend_location_for_dn(search_base) if backend_location == BackendTypes.LDAP: if self.ldap_conn.search(search_base=search_base, search_filter=search_filter, search_scope=search_scope, attributes=['*']): if not fetchmany: key, document = ldif_utils.get_document_from_entry(self.ldap_conn.response[0]['dn'], self.ldap_conn.response[0]['attributes']) return document documents = [] for result in self.ldap_conn.response: key, document = ldif_utils.get_document_from_entry(result['dn'], result['attributes']) documents.append((key, document)) return documents if backend_location in (BackendTypes.MYSQL, BackendTypes.PGSQL, BackendTypes.SPANNER): if backend_location != BackendTypes.SPANNER and self.Base is None: self.rdm_automapper() s_table = None where_clause = '' search_list = [] if '&' in search_filter: re_match = re.match('\(&\((.*?)=(.*?)\)\((.*?)=(.*?)\)', search_filter) if re_match: re_list = re_match.groups() search_list.append((re_list[0], re_list[1])) search_list.append((re_list[2], re_list[3])) else: re_match = re.match('\((.*?)=(.*?)\)', search_filter) if re_match: re_list = re_match.groups() search_list.append((re_list[0], re_list[1])) for col, val in search_list: if col.lower() == 'objectclass': s_table = val break if not s_table: return if backend_location == BackendTypes.SPANNER: if fetchmany: retVal = [] else: retVal = {} for col, val in search_list: if val == '*': continue if col.lower() == 'objectclass': s_table = val else: val = val.replace('*', '%') q_operator = 'LIKE' if '%' in val else '=' where_clause = 'AND {} {} "{}"'.format(col, q_operator, val) if not s_table: return retVal if search_scope == ldap3.BASE: dn_clause = 'dn = "{}"'.format(search_base) else: dn_clause = 'dn LIKE "%{}"'.format(search_base) sql_cmd = 'SELECT * FROM {} WHERE ({}) {}'.format(s_table, dn_clause, where_clause) data = self.spanner.exec_sql(sql_cmd) if not data.get('rows'): return retVal n = len(data['rows']) if fetchmany else 1 for j in range(n): row = data['rows'][j] row_dict = {} for i, field in enumerate(data['fields']): val = row[i] if val: if field['type'] == 'INT64': val = int(val) row_dict[field['name']] = val if fetchmany: retVal.append(row_dict) else: retVal = row_dict break return retVal sqlalchemy_table = self.Base.classes[s_table] sqlalchemyQueryObject = self.session.query(sqlalchemy_table) for col, val in search_list: if val == '*': continue if col.lower() != 'objectclass': val = val.replace('*', '%') sqlalchemyCol = getattr(sqlalchemy_table, col) if '%' in val: sqlalchemyQueryObject = sqlalchemyQueryObject.filter(sqlalchemyCol.like(val)) else: sqlalchemyQueryObject = sqlalchemyQueryObject.filter(sqlalchemyCol == val) if search_scope == ldap3.BASE: sqlalchemyQueryObject = sqlalchemyQueryObject.filter(sqlalchemy_table.dn == search_base) else: sqlalchemyQueryObject = sqlalchemyQueryObject.filter(sqlalchemy_table.dn.like('%'+search_base)) if fetchmany: result = sqlalchemyQueryObject.all() return [ item.__dict__ for item in result ] else: result = sqlalchemyQueryObject.first() if result: return result.__dict__ if backend_location == BackendTypes.COUCHBASE: key = ldif_utils.get_key_from(search_base) bucket = self.get_bucket_for_key(key) if search_scope == ldap3.BASE: n1ql = 'SELECT * FROM `{}` USE KEYS "{}"'.format(bucket, key) else: if '&' in search_filter: re_match = re.match('\(&\((.*?)\)\((.*?)\)\)', search_filter) if re_match: re_list = re_match.groups() dn_to_parse = re_list[0] if 'objectclass' in re_list[1].lower() else re_list[1] else: dn_to_parse = search_filter.strip('(').strip(')') parsed_dn = dnutils.parse_dn(dn_to_parse) attr = parsed_dn[0][0] val = parsed_dn[0][1] if '*' in val: search_clause = 'LIKE "{}"'.format(val.replace('*', '%')) else: search_clause = '="{}"'.format(val.replace('*', '%')) n1ql = 'SELECT * FROM `{}` WHERE `{}` {}'.format(bucket, attr, search_clause) result = self.cbm.exec_query(n1ql) if result.ok: data = result.json() if data.get('results'): if fetchmany: return [ item[bucket] for item in data['results'] ] else: return data['results'][0][bucket]
def get_bucket_for_dn(self, dn): key = ldif_utils.get_key_from(dn) return self.get_bucket_for_key(key)