Пример #1
0
def test_unmerge_agent_info(stat_mock, agent_info, exception):
    stat_mock.return_value.st_size = len(agent_info)
    with patch('builtins.open', mock_open(read_data=agent_info)) as m:
        agent_infos = list(
            cluster.unmerge_agent_info('agent-info', '/random/path',
                                       'agent-info.merged'))
        assert len(agent_infos) == (1 if exception is None else 0)
Пример #2
0
        def overwrite_or_create_files(filename, data):
            full_filename_path = common.ossec_path + filename
            if os.path.basename(filename) == 'client.keys':
                self._check_removed_agents("{}{}".format(zip_path, filename),
                                           logger)

            if data['merged']:  # worker nodes can only receive agent-groups files
                if data['merge-type'] == 'agent-info':
                    logger.warning("Agent status received in a worker node")
                    raise WazuhException(3011)

                for name, content, _ in cluster.unmerge_agent_info(
                        'agent-groups', zip_path, filename):
                    full_unmerged_name = common.ossec_path + name
                    tmp_unmerged_path = full_unmerged_name + '.tmp'
                    with open(tmp_unmerged_path, 'wb') as f:
                        f.write(content)
                    os.chown(tmp_unmerged_path, common.ossec_uid,
                             common.ossec_gid)
                    os.rename(tmp_unmerged_path, full_unmerged_name)
            else:
                if not os.path.exists(os.path.dirname(full_filename_path)):
                    utils.mkdir_with_mode(os.path.dirname(full_filename_path))
                os.rename("{}{}".format(zip_path, filename),
                          full_filename_path)
                os.chown(full_filename_path, common.ossec_uid,
                         common.ossec_gid)
                os.chmod(
                    full_filename_path, self.cluster_items['files'][
                        data['cluster_item_key']]['permissions'])
Пример #3
0
        def overwrite_or_create_files(filename: str, data: Dict):
            """
            Updates a file coming from the master
            :param filename: Filename to update
            :param data: File metadata such as modification time, whether it's a merged file or not, etc.
            :return: None
            """
            full_filename_path = common.ossec_path + filename
            if os.path.basename(filename) == 'client.keys':
                self._check_removed_agents("{}{}".format(zip_path, filename), logger)

            if data['merged']:  # worker nodes can only receive agent-groups files
                if data['merge-type'] == 'agent-info':
                    logger.warning("Agent status received in a worker node")
                    raise WazuhException(3011)

                for name, content, _ in cluster.unmerge_agent_info('agent-groups', zip_path, filename):
                    full_unmerged_name = os.path.join(common.ossec_path, name)
                    tmp_unmerged_path = full_unmerged_name + '.tmp'
                    with open(tmp_unmerged_path, 'wb') as f:
                        f.write(content)
                    safe_move(tmp_unmerged_path, full_unmerged_name,
                              permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                              ownership=(common.ossec_uid(), common.ossec_gid())
                              )
            else:
                if not os.path.exists(os.path.dirname(full_filename_path)):
                    utils.mkdir_with_mode(os.path.dirname(full_filename_path))
                safe_move("{}{}".format(zip_path, filename), full_filename_path,
                          permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                          ownership=(common.ossec_uid(), common.ossec_gid())
                          )
Пример #4
0
        async def update_file(name: str, data: Dict):
            """
            Updates a file from the worker. It checks the modification date to decide whether to update it or not.
            If it's a merged file, it unmerges it.
            :param name: Filename to update
            :param data: File metadata
            :return: None
            """
            # Full path
            full_path, error_updating_file, n_merged_files = common.ossec_path + name, False, 0

            # Cluster items information: write mode and permissions
            lock_full_path = "{}/queue/cluster/lockdir/{}.lock".format(common.ossec_path, os.path.basename(full_path))
            lock_file = open(lock_full_path, 'a+')
            try:
                fcntl.lockf(lock_file, fcntl.LOCK_EX)
                if os.path.basename(name) == 'client.keys':
                    self.logger.warning("Client.keys received in a master node")
                    raise WazuhException(3007)
                if data['merged']:
                    is_agent_info = data['merge_type'] == 'agent-info'
                    if is_agent_info:
                        self.sync_agent_info_status['total_agent_info'] = len(agent_ids)
                    else:
                        self.sync_extra_valid_status['total_extra_valid'] = len(agent_ids)
                    for file_path, file_data, file_time in cluster.unmerge_agent_info(data['merge_type'],
                                                                                      decompressed_files_path,
                                                                                      data['merge_name']):
                        full_unmerged_name = os.path.join(common.ossec_path, file_path)
                        tmp_unmerged_path = os.path.join(common.ossec_path, 'queue/cluster', self.name, os.path.basename(file_path))
                        try:
                            if is_agent_info:
                                agent_name_re = re.match(r'(^.+)-(.+)$', os.path.basename(file_path))
                                agent_name = agent_name_re.group(1) if agent_name_re else os.path.basename(file_path)
                                if agent_name not in agent_names:
                                    n_errors['warnings'][data['cluster_item_key']] = 1 \
                                        if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                        else n_errors['warnings'][data['cluster_item_key']] + 1

                                    self.logger.debug2("Received status of an non-existent agent '{}'".format(agent_name))
                                    continue
                            else:
                                agent_id = os.path.basename(file_path)
                                if agent_id not in agent_ids:
                                    n_errors['warnings'][data['cluster_item_key']] = 1 \
                                        if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                        else n_errors['warnings'][data['cluster_item_key']] + 1

                                    self.logger.debug2("Received group of an non-existent agent '{}'".format(agent_id))
                                    continue

                            try:
                                mtime = datetime.strptime(file_time, '%Y-%m-%d %H:%M:%S.%f')
                            except ValueError:
                                mtime = datetime.strptime(file_time, '%Y-%m-%d %H:%M:%S')

                            if os.path.isfile(full_unmerged_name):

                                local_mtime = datetime.utcfromtimestamp(int(os.stat(full_unmerged_name).st_mtime))
                                # check if the date is older than the manager's date
                                if local_mtime > mtime:
                                    logger.debug2("Receiving an old file ({})".format(file_path))
                                    continue

                            with open(tmp_unmerged_path, 'wb') as f:
                                f.write(file_data)

                            mtime_epoch = timegm(mtime.timetuple())
                            utils.safe_move(tmp_unmerged_path, full_unmerged_name,
                                            ownership=(common.ossec_uid(), common.ossec_gid()),
                                            permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                                            time=(mtime_epoch, mtime_epoch)
                                            )
                        except Exception as e:
                            self.logger.error("Error updating agent group/status ({}): {}".format(tmp_unmerged_path, e))
                            if is_agent_info:
                                self.sync_agent_info_status['total_agent_info'] -= 1
                            else:
                                self.sync_extra_valid_status['total_extra_valid'] -= 1

                            n_errors['errors'][data['cluster_item_key']] = 1 \
                                if n_errors['errors'].get(data['cluster_item_key']) is None \
                                else n_errors['errors'][data['cluster_item_key']] + 1
                        await asyncio.sleep(0.0001)

                else:
                    zip_path = "{}{}".format(decompressed_files_path, name)
                    utils.safe_move(zip_path, full_path,
                                    ownership=(common.ossec_uid(), common.ossec_gid()),
                                    permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions']
                                    )

            except WazuhException as e:
                logger.debug2("Warning updating file '{}': {}".format(name, e))
                error_tag = 'warnings'
                error_updating_file = True
            except Exception as e:
                logger.debug2("Error updating file '{}': {}".format(name, e))
                error_tag = 'errors'
                error_updating_file = True

            if error_updating_file:
                n_errors[error_tag][data['cluster_item_key']] = 1 if not n_errors[error_tag].get(
                    data['cluster_item_key']) \
                    else n_errors[error_tag][data['cluster_item_key']] + 1

            fcntl.lockf(lock_file, fcntl.LOCK_UN)
            lock_file.close()
Пример #5
0
    def _update_worker_files_in_master(self, json_file, zip_dir_path,
                                       worker_name, cluster_control_key,
                                       cluster_control_subkey, tag):
        def update_file(n_errors,
                        name,
                        data,
                        file_time=None,
                        content=None,
                        agents=None):
            # Full path
            full_path = common.ossec_path + name
            error_updating_file = False

            # Cluster items information: write mode and umask
            w_mode = cluster_items[data['cluster_item_key']]['write_mode']
            umask = cluster_items[data['cluster_item_key']]['umask']

            if content is None:
                zip_path = "{}/{}".format(zip_dir_path, name)
                with open(zip_path, 'rb') as f:
                    content = f.read()

            lock_full_path = "{}/queue/cluster/lockdir/{}.lock".format(
                common.ossec_path, os.path.basename(full_path))
            lock_file = open(lock_full_path, 'a+')
            try:
                fcntl.lockf(lock_file, fcntl.LOCK_EX)
                _update_file(file_path=name,
                             new_content=content,
                             umask_int=umask,
                             mtime=file_time,
                             w_mode=w_mode,
                             tmp_dir=tmp_path,
                             whoami='master',
                             agents=agents)

            except WazuhException as e:
                logger.debug2("{}: Warning updating file '{}': {}".format(
                    tag, name, e))
                error_tag = 'warnings'
                error_updating_file = True
            except Exception as e:
                logger.debug2("{}: Error updating file '{}': {}".format(
                    tag, name, e))
                error_tag = 'errors'
                error_updating_file = True

            if error_updating_file:
                n_errors[error_tag][data['cluster_item_key']] = 1 if not n_errors[error_tag].get(data['cluster_item_key']) \
                                                                  else n_errors[error_tag][data['cluster_item_key']] + 1

            fcntl.lockf(lock_file, fcntl.LOCK_UN)
            lock_file.close()

            return n_errors, error_updating_file

        # tmp path
        tmp_path = "/queue/cluster/{}/tmp_files".format(worker_name)
        cluster_items = get_cluster_items()['files']
        n_merged_files = 0
        n_errors = {'errors': {}, 'warnings': {}}

        # create temporary directory for lock files
        lock_directory = "{}/queue/cluster/lockdir".format(common.ossec_path)
        if not os.path.exists(lock_directory):
            mkdir_with_mode(lock_directory)

        try:
            agents = Agent.get_agents_overview(select={'fields': ['name']},
                                               limit=None)['items']
            agent_names = set(map(itemgetter('name'), agents))
            agent_ids = set(map(itemgetter('id'), agents))
        except Exception as e:
            logger.debug2("{}: Error getting agent ids and names: {}".format(
                tag, e))
            agent_names, agent_ids = {}, {}

        before = time.time()
        try:
            for filename, data in json_file.items():
                if data['merged']:
                    for file_path, file_data, file_time in unmerge_agent_info(
                            data['merge_type'], zip_dir_path,
                            data['merge_name']):
                        n_errors, error_updating_file = update_file(
                            n_errors, file_path, data, file_time, file_data,
                            (agent_names, agent_ids))
                        if not error_updating_file:
                            n_merged_files += 1

                        if self.stopper.is_set():
                            break
                else:
                    n_errors, _ = update_file(n_errors, filename, data)

        except Exception as e:
            logger.error("{}: Error updating worker files: '{}'.".format(
                tag, e))
            raise e

        after = time.time()
        logger.debug(
            "{0}: Time updating worker files: {1:.2f}s. Total of updated worker files: {2}."
            .format(tag, after - before, n_merged_files))

        if sum(n_errors['errors'].values()) > 0:
            logging.error("{}: Errors updating worker files: {}".format(
                tag, ' | '.join([
                    '{}: {}'.format(key, value)
                    for key, value in n_errors['errors'].items()
                ])))
        if sum(n_errors['warnings'].values()) > 0:
            for key, value in n_errors['warnings'].items():
                if key == '/queue/agent-info/':
                    logger.debug2(
                        "Received {} agent statuses for non-existent agents. Skipping."
                        .format(value))
                elif key == '/queue/agent-groups/':
                    logger.debug2(
                        "Received {} group assignments for non-existent agents. Skipping."
                        .format(value))

        # Save info for healthcheck
        self.manager.set_worker_status(worker_id=self.name,
                                       key=cluster_control_key,
                                       subkey=cluster_control_subkey,
                                       status=n_merged_files)
Пример #6
0
    def _update_master_files_in_worker(self, wrong_files, zip_path_dir, tag=None):
        def overwrite_or_create_files(filename, data, content=None):
            # Cluster items information: write mode and umask
            cluster_item_key = data['cluster_item_key']
            w_mode = cluster_items[cluster_item_key]['write_mode']
            umask = cluster_items[cluster_item_key]['umask']

            if content is None:
                # Full path
                file_path = common.ossec_path + filename
                zip_path = "{}/{}".format(zip_path_dir, filename)
                # File content and time
                with open(zip_path, 'r') as f:
                    file_data = f.read()
            else:
                file_data = content

            tmp_path='/queue/cluster/tmp_files'

            _update_file(file_path=filename, new_content=file_data,
                         umask_int=umask, w_mode=w_mode, tmp_dir=tmp_path, whoami='worker')

        if not tag:
            tag = "[Worker] [Sync process]"

        cluster_items = get_cluster_items()['files']

        before = time.time()
        error_shared_files = 0
        if wrong_files['shared']:
            logger.debug("{0}: Received {1} wrong files to fix from master. Action: Overwrite files.".format(tag, len(wrong_files['shared'])))
            for file_to_overwrite, data in wrong_files['shared'].items():
                try:
                    logger.debug2("{0}: Overwrite file: '{1}'".format(tag, file_to_overwrite))
                    if data['merged']:
                        for name, content, _ in unmerge_agent_info('agent-groups', zip_path_dir, file_to_overwrite):
                            overwrite_or_create_files(name, data, content)
                            if self.stopper.is_set():
                                break
                    else:
                        overwrite_or_create_files(file_to_overwrite, data)
                        if self.stopper.is_set():
                            break
                except Exception as e:
                    error_shared_files += 1
                    logger.debug2("{}: Error overwriting file '{}': {}".format(tag, file_to_overwrite, str(e)))
                    continue

        error_missing_files = 0
        if wrong_files['missing']:
            logger.debug("{0}: Received {1} missing files from master. Action: Create files.".format(tag, len(wrong_files['missing'])))
            for file_to_create, data in wrong_files['missing'].items():
                try:
                    logger.debug2("{0}: Create file: '{1}'".format(tag, file_to_create))
                    if data['merged']:
                        for name, content, _ in unmerge_agent_info('agent-groups', zip_path_dir, file_to_create):
                            overwrite_or_create_files(name, data, content)
                            if self.stopper.is_set():
                                break
                    else:
                        overwrite_or_create_files(file_to_create, data)
                        if self.stopper.is_set():
                            break
                except Exception as e:
                    error_missing_files += 1
                    logger.debug2("{}: Error creating file '{}': {}".format(tag, file_to_create, str(e)))
                    continue

        error_extra_files = 0
        if wrong_files['extra']:
            logger.debug("{0}: Received {1} extra files from master. Action: Remove files.".format(tag, len(wrong_files['extra'])))
            for file_to_remove in wrong_files['extra']:
                try:
                    logger.debug2("{0}: Remove file: '{1}'".format(tag, file_to_remove))
                    file_path = common.ossec_path + file_to_remove
                    try:
                        os.remove(file_path)
                    except OSError as e:
                        if e.errno == errno.ENOENT and '/queue/agent-groups/' in file_path:
                            logger.debug2("{}: File {} doesn't exist.".format(tag, file_to_remove))
                            continue
                        else:
                            raise e
                except Exception as e:
                    error_extra_files += 1
                    logger.debug2("{}: Error removing file '{}': {}".format(tag, file_to_remove, str(e)))
                    continue

                if self.stopper.is_set():
                    break

            directories_to_check = {os.path.dirname(f): cluster_items[data\
                                    ['cluster_item_key']]['remove_subdirs_if_empty']
                                    for f, data in wrong_files['extra'].items()}
            for directory in map(itemgetter(0), filter(lambda x: x[1], directories_to_check.items())):
                try:
                    full_path = common.ossec_path + directory
                    dir_files = set(os.listdir(full_path))
                    if not dir_files or dir_files.issubset(set(cluster_items['excluded_files'])):
                        shutil.rmtree(full_path)
                except Exception as e:
                    error_extra_files += 1
                    logger.debug2("{}: Error removing directory '{}': {}".format(tag, directory, str(e)))
                    continue

                if self.stopper.is_set():
                    break

        if error_extra_files or error_shared_files or error_missing_files:
            logger.error("{}: Found errors: {} overwriting, {} creating and {} removing".format(tag,
                        error_shared_files, error_missing_files, error_extra_files))

        after = time.time()
        logger.debug2("{}: Time updating integrity from master: {}s".format(tag, after - before))

        return True
Пример #7
0
    def _update_client_files_in_master(self, json_file, files_to_update_json,
                                       zip_dir_path, client_name,
                                       cluster_control_key,
                                       cluster_control_subkey, tag):
        def update_file(n_errors,
                        name,
                        data,
                        file_time=None,
                        content=None,
                        agents=None):
            # Full path
            full_path = common.ossec_path + name

            # Cluster items information: write mode and umask
            w_mode = cluster_items[data['cluster_item_key']]['write_mode']
            umask = int(cluster_items[data['cluster_item_key']]['umask'],
                        base=0)

            if content is None:
                zip_path = "{}/{}".format(zip_dir_path, name)
                with open(zip_path, 'rb') as f:
                    content = f.read()

            lock_full_path = "{}/queue/cluster/lockdir/{}.lock".format(
                common.ossec_path, os.path.basename(full_path))
            lock_file = open(lock_full_path, 'a+')
            try:
                fcntl.lockf(lock_file, fcntl.LOCK_EX)
                _update_file(file_path=name,
                             new_content=content,
                             umask_int=umask,
                             mtime=file_time,
                             w_mode=w_mode,
                             tmp_dir=tmp_path,
                             whoami='master',
                             agents=agents)

            except Exception as e:
                logger.debug2("{}: Error updating file '{}': {}".format(
                    tag, name, e))
                n_errors[data['cluster_item_key']] = 1 if not n_errors.get(data['cluster_item_key']) \
                                                          else n_errors[data['cluster_item_key']] + 1

            fcntl.lockf(lock_file, fcntl.LOCK_UN)
            lock_file.close()

            return n_errors

        # tmp path
        tmp_path = "/queue/cluster/{}/tmp_files".format(client_name)
        cluster_items = get_cluster_items()['files']
        n_agentsinfo = 0
        n_agentgroups = 0
        n_errors = {}

        # create temporary directory for lock files
        lock_directory = "{}/queue/cluster/lockdir".format(common.ossec_path)
        if not os.path.exists(lock_directory):
            mkdir_with_mode(lock_directory)

        try:
            agents = Agent.get_agents_overview(select={'fields': ['name']},
                                               limit=None)['items']
            agent_names = set(map(itemgetter('name'), agents))
            agent_ids = set(map(itemgetter('id'), agents))
            agents = None
        except Exception as e:
            logger.debug2("{}: Error getting agent ids and names: {}".format(
                tag, e))
            agent_names, agent_ids = {}, {}

        before = time.time()
        try:
            for filename, data in json_file.items():
                if data['merged']:
                    for file_path, file_data, file_time in unmerge_agent_info(
                            data['merge_type'], zip_dir_path,
                            data['merge_name']):
                        n_errors = update_file(n_errors, file_path, data,
                                               file_time, file_data,
                                               (agent_names, agent_ids))
                        if data['merge_type'] == 'agent-info':
                            n_agentsinfo += 1
                        else:
                            n_agentgroups += 1

                        if self.stopper.is_set():
                            break
                else:
                    n_errors = update_file(n_errors, filename, data)

        except Exception as e:
            logger.error("{}: Error updating client files: '{}'.".format(
                tag, e))
            raise e

        after = time.time()
        logger.debug(
            "{0}: Time updating client files: {1:.2f}s. Agents-info updated total: {2}. Agent-groups updated total: {3}."
            .format(tag, after - before, n_agentsinfo, n_agentgroups))

        if sum(n_errors.values()) > 0:
            logging.error("{}: Errors updating client files: {}".format(
                tag, ' | '.join([
                    '{}: {}'.format(key, value)
                    for key, value in n_errors.items()
                ])))

        # Save info for healthcheck
        status_number = n_agentsinfo if cluster_control_key == 'last_sync_agentinfo' else n_agentgroups
        self.manager.set_client_status(client_id=self.name,
                                       key=cluster_control_key,
                                       subkey=cluster_control_subkey,
                                       status=status_number)
Пример #8
0
        def update_file(name, data):
            # Full path
            full_path, error_updating_file, n_merged_files = common.ossec_path + name, False, 0

            # Cluster items information: write mode and permissions
            lock_full_path = "{}/queue/cluster/lockdir/{}.lock".format(
                common.ossec_path, os.path.basename(full_path))
            lock_file = open(lock_full_path, 'a+')
            try:
                fcntl.lockf(lock_file, fcntl.LOCK_EX)
                if os.path.basename(name) == 'client.keys':
                    self.logger.warning(
                        "Client.keys received in a master node")
                    raise WazuhException(3007)
                if data['merged']:
                    is_agent_info = data['merge_type'] == 'agent-info'
                    if is_agent_info:
                        self.sync_agent_info_status['total_agent_info'] = len(
                            agent_ids)
                    else:
                        self.sync_extra_valid_status[
                            'total_extra_valid'] = len(agent_ids)
                    for file_path, file_data, file_time in cluster.unmerge_agent_info(
                            data['merge_type'], decompressed_files_path,
                            data['merge_name']):
                        try:
                            full_unmerged_name = common.ossec_path + file_path
                            tmp_unmerged_path = full_unmerged_name + '.tmp'
                            if is_agent_info:
                                agent_name_re = re.match(
                                    r'(^.+)-(.+)$',
                                    os.path.basename(file_path))
                                agent_name = agent_name_re.group(
                                    1) if agent_name_re else os.path.basename(
                                        file_path)
                                if agent_name not in agent_names:
                                    n_errors['warnings'][data['cluster_item_key']] = 1 \
                                        if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                        else n_errors['warnings'][data['cluster_item_key']] + 1

                                    self.logger.debug2(
                                        "Received status of an non-existent agent '{}'"
                                        .format(agent_name))
                                    continue
                            else:
                                agent_id = os.path.basename(file_path)
                                if agent_id not in agent_ids:
                                    n_errors['warnings'][data['cluster_item_key']] = 1 \
                                        if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                        else n_errors['warnings'][data['cluster_item_key']] + 1

                                    self.logger.debug2(
                                        "Received group of an non-existent agent '{}'"
                                        .format(agent_id))
                                    continue

                            try:
                                mtime = datetime.strptime(
                                    file_time, '%Y-%m-%d %H:%M:%S.%f')
                            except ValueError:
                                mtime = datetime.strptime(
                                    file_time, '%Y-%m-%d %H:%M:%S')

                            if os.path.isfile(full_unmerged_name):

                                local_mtime = datetime.utcfromtimestamp(
                                    int(os.stat(full_unmerged_name).st_mtime))
                                # check if the date is older than the manager's date
                                if local_mtime > mtime:
                                    logger.debug2(
                                        "Receiving an old file ({})".format(
                                            file_path))
                                    return

                            with open(tmp_unmerged_path, 'wb') as f:
                                f.write(file_data)

                            mtime_epoch = timegm(mtime.timetuple())
                            os.utime(
                                tmp_unmerged_path,
                                (mtime_epoch, mtime_epoch))  # (atime, mtime)
                            os.chown(tmp_unmerged_path, common.ossec_uid,
                                     common.ossec_gid)
                            os.chmod(
                                tmp_unmerged_path, self.cluster_items['files'][
                                    data['cluster_item_key']]['permissions'])
                            os.rename(tmp_unmerged_path, full_unmerged_name)
                        except Exception as e:
                            self.logger.debug2(
                                "Error updating agent group/status: {}".format(
                                    e))
                            if is_agent_info:
                                self.sync_agent_info_status[
                                    'total_agent_info'] -= 1
                            else:
                                self.sync_extra_valid_status[
                                    'total_extra_valid'] -= 1

                            n_errors['errors'][data['cluster_item_key']] = 1 \
                                if n_errors['errors'].get(data['cluster_item_key']) is None \
                                else n_errors['errors'][data['cluster_item_key']] + 1

                else:
                    zip_path = "{}{}".format(decompressed_files_path, name)
                    os.chown(zip_path, common.ossec_uid, common.ossec_gid)
                    os.chmod(
                        zip_path, self.cluster_items['files'][
                            data['cluster_item_key']]['permissions'])
                    os.rename(zip_path, full_path)

            except WazuhException as e:
                logger.debug2("Warning updating file '{}': {}".format(name, e))
                error_tag = 'warnings'
                error_updating_file = True
            except Exception as e:
                logger.debug2("Error updating file '{}': {}".format(name, e))
                error_tag = 'errors'
                error_updating_file = True

            if error_updating_file:
                n_errors[error_tag][data['cluster_item_key']] = 1 if not n_errors[error_tag].get(
                    data['cluster_item_key']) \
                    else n_errors[error_tag][data['cluster_item_key']] + 1

            fcntl.lockf(lock_file, fcntl.LOCK_UN)
            lock_file.close()