def get_agents_summary_os(agent_list=None): """Get a list of available OS. Parameters ---------- agent_list : list[str] List of agents ID's Returns ------- WazuhResult """ result = AffectedItemsWazuhResult( none_msg='Could not get the operative system of the agents', all_msg='Showing the operative system of all specified agents', some_msg='Could not get the operative system of some agents') if agent_list: rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) # We don't consider agent 000 in order to get the summary db_query = WazuhDBQueryAgents(select=['os.platform'], default_sort_field='os_platform', min_select_fields=set(), distinct=True, query="id!=000", **rbac_filters) query_data = db_query.run() query_data['items'] = [ row['os']['platform'] for row in query_data['items'] ] result.affected_items = query_data['items'] result.total_affected_items = len(result.affected_items) return result
def get_agents_summary_status(agent_list=None): """Count the number of agents by status. Parameters ---------- agent_list : list[str] List of agents ID's Returns ------- WazuhResult """ summary = { 'active': 0, 'disconnected': 0, 'never_connected': 0, 'pending': 0, 'total': 0 } if agent_list: rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) # We don't consider agent 000 in order to get the summary db_query = WazuhDBQueryAgents(limit=None, select=['status'], query="id!=000", **rbac_filters) data = db_query.run() for agent in data['items']: summary[agent['status']] += 1 summary['total'] += 1 return WazuhResult({'data': summary})
def delete_agents(agent_list=None, backup=False, purge=False, use_only_authd=False, filters=None, q=None): """Delete a list of agents. Parameters ---------- agent_list : list List of agents ID's to be deleted. backup : bool Create backup before removing the agent. purge : bool Delete definitely from key store. use_only_authd : bool Force the use of authd when adding and removing agents. filters : dict Define required field filters. Format: {"field1":"value1", "field2":["value2","value3"]} q : str Define query to filter in DB. Returns ------- result : AffectedItemsWazuhResult Result with affected agents. """ result = AffectedItemsWazuhResult(all_msg='All selected agents were deleted', some_msg='Some agents were not deleted', none_msg='No agents were deleted' ) if agent_list: system_agents = get_agents_info() rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list, filters=filters) db_query = WazuhDBQueryAgents(limit=None, select=["id"], query=q, **rbac_filters) data = db_query.run() can_purge_agents = list(map(operator.itemgetter('id'), data['items'])) for agent_id in agent_list: try: if agent_id == "000": raise WazuhError(1703) elif agent_id not in system_agents: raise WazuhResourceNotFound(1701) elif agent_id not in can_purge_agents: raise WazuhError( 1731, extra_message="some of the requirements are not met -> {}".format( ', '.join(f"{key}: {value}" for key, value in filters.items() if key != 'rbac_ids') + (f', q: {q}' if q else '') ) ) else: my_agent = Agent(agent_id) my_agent.load_info_from_db() my_agent.remove(backup=backup, purge=purge, use_only_authd=use_only_authd) result.affected_items.append(agent_id) except WazuhException as e: result.add_failed_item(id_=agent_id, error=e) result.total_affected_items = len(result.affected_items) result.affected_items.sort(key=int) return result
def get_outdated_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, q=None): """Gets the outdated agents. :param agent_list: List of agents ID's. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param search: Looks for items with the specified string. :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :param q: Defines query to filter in DB. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult(all_msg='All selected agents information was returned', some_msg='Some agents information was not returned', none_msg='No agent information was returned' ) if agent_list: # Get manager version manager = Agent(id='000') manager.load_info_from_db() select = ['version', 'id', 'name'] if select is None else select rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) db_query = WazuhDBQueryAgents(offset=offset, limit=limit, sort=sort, search=search, select=select, query=f"version!={manager.version}" + (';' + q if q else ''), **rbac_filters) data = db_query.run() result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def delete_agents(agent_list=None, backup=False, purge=False, status="all", older_than="7d", use_only_authd=False): """Deletes a list of agents. :param agent_list: List of agents ID's. :param backup: Create backup before removing the agent. :param purge: Delete definitely from key store. :param older_than: Filters out disconnected agents for longer than specified. Time in seconds | "[n_days]d" | "[n_hours]h" | "[n_minutes]m" | "[n_seconds]s". For never_connected agents, uses the register date. :param status: Filters by agent status: active, disconnected or never_connected. Multiples statuses separated by commas. :param use_only_authd: Force the use of authd when adding and removing agents. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='All selected agents were deleted', some_msg='Some agents were not deleted', none_msg='No agents were deleted') if len(agent_list) != 0: db_query = WazuhDBQueryAgents(limit=None, select=["id"], filters={ 'older_than': older_than, 'status': status, 'id': agent_list }) data = db_query.run() can_purge_agents = list(map(operator.itemgetter('id'), data['items'])) system_agents = get_agents_info() for agent_id in agent_list: try: if agent_id == "000": raise WazuhError(1703) elif agent_id not in system_agents: raise WazuhResourceNotFound(1701) else: my_agent = Agent(agent_id) my_agent.load_info_from_db() if agent_id not in can_purge_agents: raise WazuhError( 1731, extra_message= "The agent has a status different to '{0}' or the specified time " "frame 'older_than {1}' does not apply".format( status, older_than)) my_agent.remove(backup=backup, purge=purge, use_only_authd=use_only_authd) result.affected_items.append(agent_id) except WazuhException as e: result.add_failed_item(id_=agent_id, error=e) result.total_affected_items = len(result.affected_items) result.affected_items.sort(key=int) result['older_than'] = older_than return result
def get_agents_summary_os(agent_list=None): """Gets a list of available OS. :param agent_list: List of agents ID's. :return: WazuhResult. """ result = AffectedItemsWazuhResult( none_msg='Could not get the operative system of the agents', all_msg='Showing the operative system of all specified agents', some_msg='Could not get the operative system of some agents') if len(agent_list) != 0: db_query = WazuhDBQueryAgents(select=['os.platform'], filters={'id': agent_list}, default_sort_field='os_platform', min_select_fields=set(), distinct=True) query_data = db_query.run() query_data['items'] = [ row['os']['platform'] for row in query_data['items'] ] result.affected_items = query_data['items'] result.total_affected_items = len(result.affected_items) return result
def get_agents_summary_status(agent_list=None): """Counts the number of agents by status. :param agent_list: List of agents ID's. :return: WazuhResult. """ summary = { 'active': 0, 'disconnected': 0, 'never_connected': 0, 'pending': 0, 'total': 0 } if len(agent_list) != 0: rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list) db_query = WazuhDBQueryAgents(limit=None, select=['status'], **rbac_filters) data = db_query.run() for agent in data['items']: summary[agent['status']] += 1 summary['total'] += 1 return WazuhResult({'data': summary})
def run(agent_list: Union[list, None] = None) -> AffectedItemsWazuhResult: """Run a rootcheck scan in the specified agents. Parameters ---------- agent_list : Union[list, None] List of the agents IDs to run the scan for. Returns ------- result : AffectedItemsWazuhResult JSON containing the affected agents. """ result = AffectedItemsWazuhResult( all_msg='Rootcheck scan was restarted on returned agents', some_msg='Rootcheck scan was not restarted on some agents', none_msg='No rootcheck scan was restarted') system_agents = get_agents_info() rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list) agent_list = set(agent_list) not_found_agents = agent_list - system_agents # Add non existent agents to failed_items [ result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701)) for agent in not_found_agents ] # Add non eligible agents to failed_items non_eligible_agents = WazuhDBQueryAgents(limit=None, select=["id", "status"], query=f'status!=active', **rbac_filters).run()['items'] [ result.add_failed_item( id_=agent['id'], error=WazuhError(1601, extra_message=f'Status - {agent["status"]}')) for agent in non_eligible_agents ] wq = WazuhQueue(common.ARQUEUE) eligible_agents = agent_list - not_found_agents - { d['id'] for d in non_eligible_agents } for agent_id in eligible_agents: try: wq.send_msg_to_agent(WazuhQueue.HC_SK_RESTART, agent_id) result.affected_items.append(agent_id) except WazuhError as e: result.add_failed_item(id_=agent_id, error=e) wq.close() result.affected_items.sort(key=int) result.total_affected_items = len(result.affected_items) return result
def get_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters=None, q=None): """Gets a list of available agents with basic attributes. :param agent_list: List of agents ID's. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]} :param filters: Defines required field filters. Format: {"field1":"value1", "field2":["value2","value3"]} :param q: Defines query to filter in DB. :return: AffectedItemsWazuhResult. """ result = AffectedItemsWazuhResult( all_msg='All selected agents information was returned', some_msg='Some agents information was not returned', none_msg='No agent information was returned') if agent_list: if filters is None: filters = dict() system_agents = get_agents_info() for agent_id in agent_list: if agent_id not in system_agents: result.add_failed_item(id_=agent_id, error=WazuhResourceNotFound(1701)) rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list, filters=filters) db_query = WazuhDBQueryAgents(offset=offset, limit=limit, sort=sort, search=search, select=select, query=q, **rbac_filters) data = db_query.run() result.affected_items.extend(data['items']) result.total_affected_items = data['totalItems'] return result
def get_agent_by_name(name=None, select=None): """Gets an agent by its name. :param name: Agent_name. :param select: Select fields to return. Format: {"fields":["field1","field2"]}. :return: AffectedItemsWazuhResult. """ db_query = WazuhDBQueryAgents(filters={'name': name}) data = db_query.run() try: agent = data['items'][0]['id'] return get_agents(agent_list=[agent], select=select) except IndexError: raise WazuhResourceNotFound(1754) except Exception as e: if e.code == 4000: raise WazuhPermissionError(4000) raise e
def get_agents_summary_status(agent_list=None): """Counts the number of agents by status. :param agent_list: List of agents ID's. :return: WazuhResult. """ result = WazuhResult({ 'active': 0, 'disconnected': 0, 'never_connected': 0, 'pending': 0, 'total': 0 }) if len(agent_list) != 0: db_query = WazuhDBQueryAgents(limit=None, select=['status'], filters={'id': agent_list}) data = db_query.run() for agent in data['items']: result[agent['status']] += 1 result['total'] += 1 return result
def restart_agents(agent_list: list = None) -> AffectedItemsWazuhResult: """Restart a list of agents. Parameters ---------- agent_list : list List of agents IDs. Raises ------ WazuhError(1703) If the agent to be restarted is 000. WazuhError(1701) If the agent to be restarted is not in the system. WazuhError(1707) If the agent to be restarted is not active. Returns ------- AffectedItemsWazuhResult """ result = AffectedItemsWazuhResult( all_msg='Restart command was sent to all agents', some_msg='Restart command was not sent to some agents', none_msg='Restart command was not sent to any agent') agent_list = set(agent_list) # Add agent with ID 000 to failed_items try: agent_list.remove('000') result.add_failed_item('000', WazuhError(1703)) except KeyError: pass if agent_list: system_agents = get_agents_info() rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=list(agent_list)) agents_with_data = WazuhDBQueryAgents( limit=None, select=["id", "status", "version"], **rbac_filters).run()['items'] # Add non existent agents to failed_items not_found_agents = agent_list - system_agents [ result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701)) for agent in not_found_agents ] # Add non active agents to failed_items non_active_agents = [ agent for agent in agents_with_data if agent['status'] != 'active' ] [ result.add_failed_item(id_=agent['id'], error=WazuhError( 1707, extra_message=f'{agent["status"]}')) for agent in non_active_agents ] eligible_agents = [agent for agent in agents_with_data if agent not in non_active_agents] if non_active_agents \ else agents_with_data wq = WazuhQueue(common.ARQUEUE) for agent in eligible_agents: try: send_restart_command(agent['id'], agent['version'], wq) result.affected_items.append(agent['id']) except WazuhException as e: result.add_failed_item(id_=agent['id'], error=e) wq.close() result.total_affected_items = len(result.affected_items) result.affected_items.sort(key=int) return result
def clear(agent_list: list = None): """Clear the syscheck database of the specified agents. Parameters ---------- agent_list : str Agent ID. Returns ------- result : AffectedItemsWazuhResult Confirmation/Error message. """ result = AffectedItemsWazuhResult( all_msg='Syscheck database was cleared on returned agents', some_msg='Syscheck database was not cleared on some agents', none_msg="No syscheck database was cleared") system_agents = get_agents_info() not_found_agents = set(agent_list) - system_agents list( map( lambda ag: result.add_failed_item( id_=ag, error=WazuhResourceNotFound(1701)), not_found_agents)) wdb_conn = None rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list) db_query = WazuhDBQueryAgents(select=["id", "version"], **rbac_filters) data = db_query.run() for item in data['items']: agent_id = item['id'] agent_version = item.get( 'version', None) # If the value was NULL in the DB the key might not exist if agent_version is not None: if WazuhVersion(agent_version) < WazuhVersion('v3.12.0'): try: if wdb_conn is None: wdb_conn = WazuhDBConnection() syscheck_delete_agent(agent_id, wdb_conn) result.affected_items.append(agent_id) except WazuhError as e: result.add_failed_item(id_=agent_id, error=e) else: result.add_failed_item( id_=agent_id, error=WazuhError( 1760, extra_message="Agent version should be < v3.12.0.")) else: result.add_failed_item(id_=agent_id, error=WazuhError(1015)) if wdb_conn is not None: wdb_conn.close() result.affected_items.sort(key=int) result.total_affected_items = len(result.affected_items) return result