def clear(agent_id=None, all_agents=False): """ Clears the database. :param agent_id: For an agent. :param all_agents: For all agents. :return: Message. """ # Clear DB if int(all_agents): db_agents = glob('{0}/*-*.db'.format(common.database_path_agents)) else: Agent(agent_id).get_basic_information() # check if the agent exists db_agents = glob('{0}/{1}-*.db'.format(common.database_path_agents, agent_id)) if not db_agents: raise WazuhException(1600) for db_agent in db_agents: conn = Connection(db_agent) conn.begin() try: conn.execute('DELETE FROM pm_event') except WazuhException as e: raise e except Exception as exception: conn.commit() conn.vacuum() raise WazuhException(1654, exception) else: conn.commit() conn.vacuum() # Clear OSSEC info if int(all_agents): rootcheck_files = glob('{0}/queue/rootcheck/*'.format( common.ossec_path)) else: if agent_id == "000": rootcheck_files = [ '{0}/queue/rootcheck/rootcheck'.format(common.ossec_path) ] else: agent_info = Agent(agent_id).get_basic_information() rootcheck_files = glob( '{0}/queue/rootcheck/({1}) {2}->rootcheck'.format( common.ossec_path, agent_info['name'], agent_info['ip'])) for rootcheck_file in rootcheck_files: if path.exists(rootcheck_file): remove(rootcheck_file) return "Rootcheck database deleted"
def clear(agent_id=None, all_agents=False): """ Clears the database. :param agent_id: For an agent. :param all_agents: For all agents. :return: Message. """ # Clear DB if int(all_agents): db_agents = glob('{0}/*-*.db'.format(common.database_path_agents)) else: db_agents = glob('{0}/{1}-*.db'.format(common.database_path_agents, agent_id)) if not db_agents: raise WazuhException(1600) for db_agent in db_agents: conn = Connection(db_agent) conn.begin() try: conn.execute('DELETE FROM fim_event') conn.execute('DELETE FROM fim_file') except Exception as exception: raise exception finally: conn.commit() conn.vacuum() # Clear OSSEC info if int(all_agents): syscheck_files = glob('{0}/queue/syscheck/*'.format(common.ossec_path)) else: if agent_id == "000": syscheck_files = ['{0}/queue/syscheck/syscheck'.format(common.ossec_path)] else: agent_info = Agent(agent_id).get_basic_information() syscheck_files = glob('{0}/queue/syscheck/({1}) {2}->syscheck'.format(common.ossec_path, agent_info['name'], agent_info['ip'])) for syscheck_file in syscheck_files: if path.exists(syscheck_file): remove(syscheck_file) return "Syscheck database deleted"
def clear_local(agent_id=None, all_agents=False): # Clear DB if int(all_agents): db_agents = glob('{0}/*-*.db'.format(common.database_path_agents)) else: db_agents = glob('{0}/{1}-*.db'.format(common.database_path_agents, agent_id)) if not db_agents: raise WazuhException(1600) for db_agent in db_agents: conn = Connection(db_agent) conn.begin() try: conn.execute('DELETE FROM fim_event') conn.execute('DELETE FROM fim_file') except Exception as exception: raise exception finally: conn.commit() conn.vacuum() # Clear OSSEC info if int(all_agents): syscheck_files = glob('{0}/queue/syscheck/*'.format(common.ossec_path)) else: if agent_id == "000": syscheck_files = [ '{0}/queue/syscheck/syscheck'.format(common.ossec_path) ] else: agent_info = Agent(agent_id).get_basic_information() syscheck_files = glob( '{0}/queue/syscheck/({1}) {2}->syscheck'.format( common.ossec_path, agent_info['name'], agent_info['ip'])) for syscheck_file in syscheck_files: if path.exists(syscheck_file): remove(syscheck_file) return "Syscheck database deleted"
def remove_bulk_agents(agent_ids_list: KeysView, logger): """ Removes files created by agents in worker nodes. This function doesn't remove agents from client.keys since the client.keys file is overwritten by the master node. :param agent_ids_list: List of agents ids to remove. :param logger: Logger to use :return: None. """ def remove_agent_file_type(agent_files: List[str]): """ Removes files if they exist :param agent_files: Path regexes of the files to remove :return: None """ for filetype in agent_files: filetype_glob = filetype.format(ossec_path=common.ossec_path, id='*', name='*', ip='*') filetype_agent = { filetype.format(ossec_path=common.ossec_path, id=a['id'], name=a['name'], ip=a['ip']) for a in agent_info } for agent_file in set( glob.iglob(filetype_glob)) & filetype_agent: logger.debug2("Removing {}".format(agent_file)) if os.path.isdir(agent_file): shutil.rmtree(agent_file) else: os.remove(agent_file) if not agent_ids_list: return # the function doesn't make sense if there is no agents to remove logger.info("Removing files from {} agents".format( len(agent_ids_list))) logger.debug("Agents to remove: {}".format(', '.join(agent_ids_list))) # the agents must be removed in groups of 997: 999 is the limit of SQL variables per query. Limit and offset are # always included in the SQL query, so that leaves 997 variables as limit. for agents_ids_sublist in itertools.zip_longest(*itertools.repeat( iter(agent_ids_list), 997), fillvalue='0'): agents_ids_sublist = list( filter(lambda x: x != '0', agents_ids_sublist)) # Get info from DB agent_info = Agent.get_agents_overview( q=",".join(["id={}".format(i) for i in agents_ids_sublist]), select={'fields': ['ip', 'id', 'name']}, limit=None)['items'] logger.debug2("Removing files from agents {}".format( ', '.join(agents_ids_sublist))) files_to_remove = [ '{ossec_path}/queue/agent-info/{name}-{ip}', '{ossec_path}/queue/rootcheck/({name}) {ip}->rootcheck', '{ossec_path}/queue/diff/{name}', '{ossec_path}/queue/agent-groups/{id}', '{ossec_path}/queue/rids/{id}', '{ossec_path}/var/db/agents/{name}-{id}.db' ] remove_agent_file_type(files_to_remove) logger.debug2("Removing agent group assigments from database") # remove agent from groups db_global = glob.glob(common.database_path_global) if not db_global: raise WazuhException(1600) conn = Connection(db_global[0]) agent_ids_db = { 'id_agent{}'.format(i): int(i) for i in agents_ids_sublist } conn.execute( 'delete from belongs where {}'.format(' or '.join([ 'id_agent = :{}'.format(i) for i in agent_ids_db.keys() ])), agent_ids_db) conn.commit() # Tell wazuhbd to delete agent database wdb_conn = WazuhDBConnection() wdb_conn.delete_agents_db(agents_ids_sublist) logger.info("Agent files removed")
def remove_bulk_agents(agent_ids_list, logger): """ Removes files created by agents in worker nodes. This function doesn't remove agents from client.keys since the client.keys file is overwritten by the master node. :param agent_ids_list: List of agents ids to remove. :return: None. """ def remove_agent_file_type(glob_args, agent_args, agent_files): for filetype in agent_files: for agent_file in set(glob.iglob(filetype.format(common.ossec_path, *glob_args))) & \ {filetype.format(common.ossec_path, *(a[arg] for arg in agent_args)) for a in agent_info}: logger.debug2("Removing {}".format(agent_file)) if os.path.isdir(agent_file): shutil.rmtree(agent_file) else: os.remove(agent_file) if not agent_ids_list: return # the function doesn't make sense if there is no agents to remove logger.info("Removing files from {} agents".format( len(agent_ids_list))) logger.debug("Agents to remove: {}".format(', '.join(agent_ids_list))) # the agents must be removed in groups of 997: 999 is the limit of SQL variables per query. Limit and offset are # always included in the SQL query, so that leaves 997 variables as limit. for agents_ids_sublist in itertools.zip_longest(*itertools.repeat( iter(agent_ids_list), 997), fillvalue='0'): agents_ids_sublist = list( filter(lambda x: x != '0', agents_ids_sublist)) # Get info from DB agent_info = Agent.get_agents_overview( q=",".join(["id={}".format(i) for i in agents_ids_sublist]), select={'fields': ['ip', 'id', 'name']}, limit=None)['items'] logger.debug2("Removing files from agents {}".format( ', '.join(agents_ids_sublist))) # Remove agent files that need agent name and ip agent_files = [ '{}/queue/agent-info/{}-{}', '{}/queue/rootcheck/({}) {}->rootcheck' ] remove_agent_file_type(('*', '*'), ('name', 'ip'), agent_files) # remove agent files that need agent name agent_files = ['{}/queue/diff/{}'] remove_agent_file_type(('*', ), ('name', ), agent_files) # Remove agent files that only need agent id agent_files = [ '{}/queue/agent-groups/{}', '{}/queue/rids/{}', '{}/queue/db/{}.db', '{}/queue/db/{}.db-wal', '{}/queue/db/{}.db-shm' ] remove_agent_file_type(('*', ), ('id', ), agent_files) # remove agent files that need agent name and id agent_files = ['{}/var/db/agents/{}-{}.db'] remove_agent_file_type(('*', '*'), ('id', 'name'), agent_files) # remove agent from groups db_global = glob.glob(common.database_path_global) if not db_global: raise WazuhException(1600) conn = Connection(db_global[0]) agent_ids_db = { 'id_agent{}'.format(i): int(i) for i in agents_ids_sublist } conn.execute( 'delete from belongs where {}'.format(' or '.join([ 'id_agent = :{}'.format(i) for i in agent_ids_db.keys() ])), agent_ids_db) conn.commit() logger.info("Agent files removed")