def remove_user_role(user_id, role_ids): """Create a relationship between a user and a role :param user_id: User id :param role_ids: List of role ids :return User-Roles information """ username = get_username(user_id=user_id) result = AffectedItemsWazuhResult(none_msg=f'No role was unlinked from user {username}', some_msg=f'Some roles were not unlinked from user {username}', all_msg=f'All roles were unlinked from user {username}') success = False with UserRolesManager() as urm: for role_id in role_ids: user_role = urm.remove_role_in_user(user_id=int(user_id[0]), role_id=role_id) if user_role == SecurityError.INVALID: result.add_failed_item(id_=int(role_id), error=WazuhError(4016)) elif user_role == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=int(role_id), error=WazuhError(4002)) elif user_role == SecurityError.USER_NOT_EXIST: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(5001)) break elif user_role == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if success: with AuthenticationManager() as auth: result.affected_items.append(auth.get_user_id(int(user_id[0]))) result.affected_items.sort(key=str) invalid_users_tokens(users=user_id) return result
def get_user_me(): """Get the information of the current user Returns ------- AffectedItemsWazuhResult with the desired information """ result = AffectedItemsWazuhResult(all_msg='Current user information was returned') affected_items = list() with AuthenticationManager() as auth: user = auth.get_user(common.current_user.get()) for index, role_id in enumerate(user['roles']): with RolesManager() as rm: role = rm.get_role_id(role_id=int(role_id)) role.pop('users') for index_r, rule_id in enumerate(role['rules']): with RulesManager() as rum: role['rules'][index_r] = rum.get_rule(rule_id=int(rule_id)) role['rules'][index_r].pop('roles') for index_p, policy_id in enumerate(role['policies']): with PoliciesManager() as pm: role['policies'][index_p] = pm.get_policy_id(policy_id=int(policy_id)) role['policies'][index_p].pop('roles') user['roles'][index] = role affected_items.append(user) if user else result.add_failed_item(id_=common.current_user.get(), error=WazuhError(5001)) data = process_array(affected_items) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def edit_run_as(user_id: str = None, allow_run_as: bool = False): """Enable/Disable the user's allow_run_as flag Parameters ---------- user_id : str User ID allow_run_as : bool Enable or disable authorization context login method for the specified user Returns ------- result : AffectedItemsWazuhResult Status message """ result = AffectedItemsWazuhResult( none_msg=f"The parameter allow_run_as could not be " f"{'enabled' if allow_run_as else 'disabled'} for the user", all_msg=f"Parameter allow_run_as has been " f"{'enabled' if allow_run_as else 'disabled'} for the user") with AuthenticationManager() as auth: user_id = int(user_id) query = auth.edit_run_as(user_id, allow_run_as) if query is False: result.add_failed_item(id_=user_id, error=WazuhError(5001)) elif query == SecurityError.INVALID: result.add_failed_item(id_=user_id, error=WazuhError(5010)) else: result.affected_items.append(auth.get_user_id(user_id)) result.total_affected_items += 1 invalid_users_tokens(users=[user_id]) return result
def revoke_current_user_tokens(): """Revoke all current user's tokens""" with TokenManager() as tm: with AuthenticationManager() as am: tm.add_user_roles_rules(users={am.get_user(common.current_user.get())['id']}) return WazuhResult({'message': f'User {common.current_user.get()} was successfully logged out'})
def update_user(user_id=None, password=None): """Update a specified user Parameters ---------- user_id : str User ID password : str Password for the new user Returns ------- Status message """ if not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(all_msg='User modified correctly', none_msg='User could not be updated') with AuthenticationManager() as auth: query = auth.update_user(user_id[0], password) if not query: result.add_failed_item(id_=user_id[0], error=WazuhError(5001)) else: result.affected_items.append(auth.get_user_id(user_id[0])) result.total_affected_items += 1 invalid_users_tokens(users=[user_id[0]]) return result
def create_user(username: str = None, password: str = None): """Create a new user Parameters ---------- username : str Name for the new user password : str Password for the new user Returns ------- result : AffectedItemsWazuhResult Status message """ if len(password) > 64 or len(password) < 8: raise WazuhError(5009) elif not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(none_msg='User could not be created', all_msg='User was successfully created') with AuthenticationManager() as auth: if auth.add_user(username, password): operation = auth.get_user(username) if operation: result.affected_items.append(operation) result.total_affected_items = 1 else: result.add_failed_item(id_=username, error=WazuhError(5000)) else: result.add_failed_item(id_=username, error=WazuhError(5000)) return result
def update_user(user_id: str = None, password: str = None): """Update a specified user Parameters ---------- user_id : list User ID password : str Password for the new user Returns ------- Status message """ if password is None: raise WazuhError(4001) if password: if len(password) > 64 or len(password) < 8: raise WazuhError(5009) elif not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(all_msg='User was successfully updated', none_msg='User could not be updated') with AuthenticationManager() as auth: query = auth.update_user(int(user_id[0]), password) if query is False: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(5001)) else: result.affected_items.append(auth.get_user_id(int(user_id[0]))) result.total_affected_items += 1 invalid_users_tokens(users=user_id) return result
def update_user(user_id: str = None, password: str = None, allow_run_as: bool = None): """Update a specified user Parameters ---------- user_id : str User ID password : str Password for the new user allow_run_as : bool Enable authorization context login method for the new user Returns ------- Status message """ if password is None and allow_run_as is None: raise WazuhError(4001) if password and not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(all_msg='User was successfully updated', none_msg='User could not be updated') with AuthenticationManager() as auth: query = auth.update_user(user_id[0], password, allow_run_as) if query is False: result.add_failed_item(id_=user_id[0], error=WazuhError(5001)) else: result.affected_items.append(auth.get_user_id(user_id[0])) result.total_affected_items += 1 invalid_users_tokens(users=user_id) return result
def remove_users(user_ids): """Remove a specified list of users Parameters ---------- user_ids : list List of IDs Returns ------- Status message """ result = AffectedItemsWazuhResult( none_msg='No user was deleted', some_msg='Some users were not deleted', all_msg='Users were successfully deleted') with AuthenticationManager() as auth: for user_id in user_ids: current_user = auth.get_user(common.current_user.get()) if not isinstance(current_user, bool) and int(user_id) == int( current_user['id']): result.add_failed_item(id_=user_id, error=WazuhError(5008)) continue user = auth.get_user_id(user_id) query = auth.delete_user(user_id) if not query: result.add_failed_item(id_=user_id, error=WazuhError(5001)) elif query == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=user_id, error=WazuhError(5004)) elif user: result.affected_items.append(user) result.total_affected_items += 1 result.affected_items.sort(key=str) return result
def _expand_resource(resource): """This function expand a specified resource depending of its type. Parameters ---------- resource : str Resource to be expanded Returns ------- str Result of the resource expansion. """ name, attribute, value = resource.split(':') resource_type = ':'.join([name, attribute]) # This is the special case, expand_group can receive * or the name of the group. That's why it' s always called if resource_type == 'agent:group': return expand_group(value) # We need to transform the wildcard * to the resource of the system if value == '*': if resource_type == 'agent:id': return get_agents_info() elif resource_type == 'group:id': return get_groups() elif resource_type == 'role:id': with RolesManager() as rm: roles = rm.get_roles() return {str(role_id.id) for role_id in roles} elif resource_type == 'policy:id': with PoliciesManager() as pm: policies = pm.get_policies() return {str(policy_id.id) for policy_id in policies} elif resource_type == 'user:id': users_system = set() with AuthenticationManager() as auth: users = auth.get_users() for user in users: users_system.add(str(user['user_id'])) return users_system elif resource_type == 'rule:id': with RulesManager() as rum: rules = rum.get_rules() return {str(rule_id.id) for rule_id in rules} elif resource_type == 'rule:file': return expand_rules() elif resource_type == 'decoder:file': return expand_decoders() elif resource_type == 'list:file': return expand_lists() elif resource_type == 'node:id': return set(cluster_nodes.get()) elif resource_type == '*:*': # Resourceless return {'*'} return set() # We return the value casted to set else: return {value}
def get_permissions(user_id=None, auth_context=None): with AuthenticationManager() as auth: if auth.user_auth_context(user_id): # Add dummy rbac_policies for developing here if auth_context: return WazuhResult( optimize_resources(auth_context=auth_context)) return WazuhResult(optimize_resources(user_id=user_id))
def get_users(user_ids: list = None, offset: int = 0, limit: int = common.database_limit, sort_by: dict = None, sort_ascending: bool = True, search_text: str = None, complementary_search: bool = False, search_in_fields: list = None): """Get the information of a specified user Parameters ---------- user_ids : list List of user ids offset : int First item to return limit : int Maximum number of items to return sort_by : dict Fields to sort the items by. Format: {"fields":["field1","field2"],"order":"asc|desc"} sort_ascending : bool Sort in ascending (true) or descending (false) order search_text : str Text to search complementary_search : bool Find items without the text to search search_in_fields : list Fields to search in Returns ------- AffectedItemsWazuhResult with the desired information """ result = AffectedItemsWazuhResult( none_msg='No user was returned', some_msg='Some users were not returned', all_msg='All specified users were returned') affected_items = list() with AuthenticationManager() as auth: for user_id in user_ids: user_id = int(user_id) user = auth.get_user_id(user_id) affected_items.append(user) if user else result.add_failed_item( id_=user_id, error=WazuhError(5001)) data = process_array(affected_items, search_text=search_text, search_in_fields=search_in_fields, complementary_search=complementary_search, sort_by=sort_by, sort_ascending=sort_ascending, offset=offset, limit=limit) result.affected_items = data['items'] result.total_affected_items = data['totalItems'] return result
def set_user_role(user_id, role_ids, position=None): """Create a relationship between a user and a role. Parameters ---------- user_id : list User ID role_ids : list of int List of role ids position : int Position where the new role will be inserted Returns ------- Dict User-Roles information """ if position is not None and position < 0: raise WazuhError(4018) username = get_username(user_id=user_id) result = AffectedItemsWazuhResult( none_msg=f'No link was created to user {username}', some_msg=f'Some roles were not linked to user {username}', all_msg=f'All roles were linked to user {username}') success = False with UserRolesManager() as urm: for role_id in role_ids: user_role = urm.add_role_to_user(user_id=int(user_id[0]), role_id=int(role_id), position=position) if user_role == SecurityError.ALREADY_EXIST: result.add_failed_item(id_=int(role_id), error=WazuhError(4017)) elif user_role == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=int(role_id), error=WazuhError(4002)) elif user_role == SecurityError.USER_NOT_EXIST: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(5001)) break elif user_role == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=int(user_id[0]), error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if position is not None: position += 1 if success: with AuthenticationManager() as auth: result.affected_items.append(auth.get_user_id(int(user_id[0]))) result.affected_items.sort(key=str) invalid_users_tokens(users=user_id) return result
def revoke_current_user_tokens(): """Revoke all current user's tokens""" with AuthenticationManager() as am: invalid_users_tokens( users=[am.get_user(common.current_user.get())['id']]) return WazuhResult({ 'message': f'User {common.current_user.get()} was successfully logged out' })
def get_permissions(user_id=None, auth_context=None): with AuthenticationManager() as auth: if not auth.user_allow_run_as(user_id) and auth_context: raise WazuhPermissionError(code=6004) elif auth.user_allow_run_as(user_id): permissions, roles = optimize_resources(auth_context=auth_context, user_id=user_id) else: permissions, roles = optimize_resources(user_id=user_id) result = { 'policies': permissions, 'roles': roles } return WazuhResult(result)
def get_username(user_id): """Return the username of the specified user_id Parameters ---------- user_id : list User ID Returns ------- username if the user_id exists, unknown in other case """ with AuthenticationManager() as am: user = am.get_user_id(user_id=int(user_id[0])) username = user['username'] if user else 'unknown' return username
def check_token(username, roles, token_nbf_time, run_as): """Check the validity of a token with the current time and the generation time of the token. Parameters ---------- username : str Unique username roles : list List of roles related with the current token token_nbf_time : int Issued at time of the current token run_as : bool Indicate if the token has been granted through run_as endpoint Returns ------- Dict with the result """ # Check that the user exists with AuthenticationManager() as am: user = am.get_user(username=username) if not user: return {'valid': False} user_id = user['id'] with UserRolesManager() as urm: user_roles = [ role['id'] for role in map(Roles.to_dict, urm.get_all_roles_from_user(user_id=user_id)) ] if not am.user_allow_run_as( user['username']) and set(user_roles) != set(roles): return {'valid': False} with TokenManager() as tm: for role in user_roles: if not tm.is_token_valid( role_id=role, user_id=user_id, token_nbf_time=int(token_nbf_time), run_as=run_as): return {'valid': False} policies = optimize_resources(roles) return {'valid': True, 'policies': policies}
def get_roles(auth_context=None, user_id=None): """Obtain the roles of a user using auth_context or user_id :param auth_context: Authorization context of the current user :param user_id: Username of the current user """ with AuthenticationManager() as am: user_id = am.get_user(username=user_id)['id'] rbac = RBAChecker(auth_context=auth_context, user_id=user_id) # Authorization Context method if auth_context: roles = rbac.run_auth_context_roles() # User-role link method else: roles = rbac.run_user_role_link_roles(user_id) return roles
def get_permissions(user_id=None, auth_context=None): """Obtain the permissions of a user using auth_context or user_id :param auth_context: Authorization context of the current user :param user_id: Username of the current user """ with AuthenticationManager() as auth: if not auth.user_allow_run_as(user_id) and auth_context: raise WazuhPermissionError(6004) elif auth.user_allow_run_as(user_id): roles = get_roles(auth_context=auth_context, user_id=user_id) else: roles = get_roles(user_id=user_id) result = {'roles': roles} return WazuhResult(result)
def check_user_master(user, password): """This function must be executed in master node. Parameters ---------- user : str Unique username password : str User password Returns ------- Dict with the result of the query """ with AuthenticationManager() as auth_: if auth_.check_user(user, password): return {'result': True} return {'result': False}
def remove_role_rule(role_id, rule_ids): """Remove a relationship between a role and one or more rules. :param role_id: The new role_id :param rule_ids: List of rule ids :return Result of operation """ result = AffectedItemsWazuhResult( none_msg=f'No security rule was unlinked from role {role_id[0]}', some_msg= f'Some security rules were not unlinked from role {role_id[0]}', all_msg=f'All security rules were unlinked from role {role_id[0]}') success = False with RolesRulesManager() as rrm: for rule_id in rule_ids: role_rule = rrm.remove_rule_in_role(role_id=int(role_id[0]), rule_id=int(rule_id)) if role_rule == SecurityError.INVALID: result.add_failed_item(id_=rule_id, error=WazuhError(4024)) elif role_rule == SecurityError.ROLE_NOT_EXIST: result.add_failed_item(id_=role_id[0], error=WazuhError(4002)) elif role_rule == SecurityError.RULE_NOT_EXIST: result.add_failed_item(id_=rule_id, error=WazuhError(4022)) elif role_rule == SecurityError.ADMIN_RESOURCES: result.add_failed_item(id_=role_id[0], error=WazuhError(4008)) else: success = True result.total_affected_items += 1 if success: with RolesManager() as rm: result.affected_items.append( rm.get_role_id(role_id=role_id[0])) # Invalidate users with auth_context with AuthenticationManager() as am: user_list = list() for user in am.get_users(): if am.user_allow_run_as(username=user['username']): user_list.append(user['user_id']) invalid_users_tokens(users=user_list) result.affected_items.sort(key=str) return result
def optimize_resources(auth_context=None, user_id=None): """This function preprocess the policies of the user for a more easy treatment in the decorator of the RBAC :param auth_context: Authorization context of the current user :param user_id: Username of the current user """ with AuthenticationManager() as am: user_id = am.get_user(username=user_id)['id'] rbac = RBAChecker(auth_context=auth_context, user_id=user_id) # Authorization Context method if auth_context: data = rbac.run_auth_context() # User-role link method else: data = rbac.run_user_role_link(user_id) policies = data['policies'] roles = data['roles'] preprocessor = PreProcessor() for policy in policies: preprocessor.process_policy(policy) return preprocessor.get_optimize_dict(), roles
def create_user(username: str = None, password: str = None): """Create a new user :param username: Name for the new user :param password: Password for the new user :return: Status message """ if not _user_password.match(password): raise WazuhError(5007) result = AffectedItemsWazuhResult(none_msg='User could not be created', all_msg='User created correctly') with AuthenticationManager() as auth: if auth.add_user(username, password): operation = auth.get_user(username) if operation: result.affected_items.append(operation) result.total_affected_items = 1 else: result.add_failed_item(id_=username, error=WazuhError(5000)) else: result.add_failed_item(id_=username, error=WazuhError(5000)) return result
def _expand_resource(resource): """This function expand a specified resource depending of it type. :param resource: Resource to be expanded :return expanded_resource: Returns the result of the resource expansion """ name, attribute, value = resource.split(':') resource_type = ':'.join([name, attribute]) # This is the special case, expand_group can receive * or the name of the group. That's why it' s always called if resource_type == 'agent:group': return expand_group(value) # We need to transform the wildcard * to the resource of the system if value == '*': if resource_type == 'agent:id': return get_agents_info() elif resource_type == 'group:id': return get_groups() elif resource_type == 'role:id': with RolesManager() as rm: roles = rm.get_roles() return {str(role_id.id) for role_id in roles} elif resource_type == 'policy:id': with PoliciesManager() as pm: policies = pm.get_policies() return {str(policy_id.id) for policy_id in policies} elif resource_type == 'user:id': users_system = set() with AuthenticationManager() as auth: users = auth.get_users() for user in users: users_system.add(user['user_id']) return users_system elif resource_type == 'rule:id': with RulesManager() as rum: rules = rum.get_rules() return {str(rule_id.id) for rule_id in rules} elif resource_type == 'rule:file': tags = ['rule_include', 'rule_exclude', 'rule_dir'] format_rules = format_rule_decoder_file( get_ossec_conf(section='ruleset')['ruleset'], { 'status': Status.S_ALL.value, 'relative_dirname': None, 'filename': None }, tags) return {rule['filename'] for rule in format_rules} elif resource_type == 'decoder:file': tags = ['decoder_include', 'decoder_exclude', 'decoder_dir'] format_decoders = format_rule_decoder_file( get_ossec_conf(section='ruleset')['ruleset'], { 'status': Status.S_ALL.value, 'relative_dirname': None, 'filename': None }, tags) return {decoder['filename'] for decoder in format_decoders} elif resource_type == 'list:path': return { os.path.join(cdb_list['relative_dirname'], cdb_list['filename']) for cdb_list in iterate_lists(only_names=True) } elif resource_type == 'node:id': return set(cluster_nodes.get()) elif resource_type == 'file:path': return get_files() elif resource_type == '*:*': # Resourceless return {'*'} return set() # We return the value casted to set else: return {value}