class pfSenseGroup(object): def __init__(self, module): self.module = module self.pfsense = PFSenseModule(module) self.system = self.pfsense.get_element('system') self.groups = self.system.findall('group') def _find_group(self, name): found = None i = 0 for group in self.groups: i = list(self.system).index(group) if group.find('name').text == name: found = group break return (found, i) def add(self, group): group_elt, i = self._find_group(group['name']) changed = False if group_elt is None: changed = True if self.module.check_mode: self.module.exit_json(changed=True) group_elt = self.pfsense.new_element('group') self.pfsense.copy_dict_to_element(group, group_elt) self.system.insert(i + 1, group_elt) self.pfsense.write_config( descr='ansible pfsensible.core.group added %s' % (group['name'])) else: changed = self.pfsense.copy_dict_to_element(group, group_elt) if self.module.check_mode: self.module.exit_json(changed=changed) if changed: self.pfsense.write_config( descr='ansible pfsensible.core.group updated "%s"' % (group['name'])) self.module.exit_json(changed=changed) def remove(self, group): group_elt, dummy = self._find_group(group['name']) changed = False if group_elt is not None: if self.module.check_mode: self.module.exit_json(changed=True) self.system.remove(group_elt) changed = True self.pfsense.write_config( descr='ansible pfsensible.core.group removed "%s"' % (group['name'])) self.module.exit_json(changed=changed)
class PFSenseAuthserverLDAP(object): def __init__(self, module): self.module = module self.pfsense = PFSenseModule(module) self.system = self.pfsense.get_element('system') self.authservers = self.system.findall('authserver') self.diff = {'after': {}, 'before': {}} def _find_authserver_ldap(self, name): found = None i = 0 for authserver in self.authservers: i = list(self.system).index(authserver) if authserver.find('name').text == name and authserver.find( 'type').text == 'ldap': found = authserver break return (found, i) def add(self, authserver): authserver_elt, i = self._find_authserver_ldap(authserver['name']) changed = False # Replace the text CA name with the caref id authserver['ldap_caref'] = self.pfsense.get_caref(authserver['ca']) # CA is required for SSL/TLS if authserver['ldap_caref'] is None and authserver[ 'ldap_urltype'] != 'TCP - Standard': self.module.fail_json(msg="could not find CA '%s'" % (authserver['ca'])) del authserver['ca'] if authserver_elt is None: changed = True authserver_elt = self.pfsense.new_element('authserver') authserver['refid'] = self.pfsense.uniqid() self.pfsense.copy_dict_to_element(authserver, authserver_elt) self.system.insert(i + 1, authserver_elt) change_descr = 'ansible pfsensible.core.authserver_ldap added %s' % ( authserver['name']) else: self.diff['before'] = self.pfsense.element_to_dict(authserver_elt) changed = self.pfsense.copy_dict_to_element( authserver, authserver_elt) change_descr = 'ansible pfsensible.core.authserver_ldap updated "%s"' % ( authserver['name']) self.diff['after'] = self.pfsense.element_to_dict(authserver_elt) if changed and not self.module.check_mode: self.pfsense.write_config(descr=change_descr) self.module.exit_json(changed=changed, diff=self.diff) def remove(self, authserver): authserver_elt, dummy = self._find_authserver_ldap(authserver['name']) changed = False if authserver_elt is not None: self.diff['before'] = self.pfsense.element_to_dict(authserver_elt) self.authservers.remove(authserver_elt) changed = True if changed and not self.module.check_mode: self.pfsense.write_config( descr='ansible pfsensible.core.authserver_ldap removed "%s"' % (authserver['name'])) self.module.exit_json(changed=changed, diff=self.diff)
class pfSenseUser(object): def __init__(self, module): self.module = module self.pfsense = PFSenseModule(module) self.system = self.pfsense.get_element('system') self.users = self.system.findall('user') self.groups = self.system.findall('group') self.diff = {} self.change_descr = '' def _find_user(self, name): found = None i = 0 for user in self.users: if user.find('name').text == name: found = user break i += 1 return (found, i) def _find_group(self, name): found = None i = 0 for group_elt in self.groups: if group_elt.find('name').text == name: found = group_elt break i += 1 return (found, i) def _find_groups_for_uid(self, uid): groups = [] for group_elt in self.groups: for member_elt in group_elt.findall('member'): if member_elt.text == uid: groups.append(group_elt.find('name').text) return groups def _find_last_user_idx(self): found = False i = 0 for elt in self.system: if elt.tag == 'user': i += 1 found = True if not found: i += 1 return i def _nextuid(self): nextuid_elt = self.system.find('nextuid') nextuid = nextuid_elt.text nextuid_elt.text = str(int(nextuid) + 1) return nextuid def _format_diff_priv(self, priv): if isinstance(priv, str): return [priv] else: return priv def _validate_password(self, user): # if re.match(r'\$2b\$', user['password']): user['bcrypt-hash'] = user['password'] # else: # self.module.fail_json(msg='Password (%s) does not appear to be a bcrypt hash' % user['password']) # del user['password'] def add(self, user): changed = False stdout = None stderr = None mod_groups = [] # Allow authorizedkeys to be clear or base64 encoded if 'authorizedkeys' in user and 'ssh-' in user['authorizedkeys']: user['authorizedkeys'] = base64.b64encode(user['authorizedkeys']) user_elt, user_idx = self._find_user(user['name']) if user_elt is None: changed = True self.diff['before'] = {} if 'password' in user: self._validate_password(user) else: self.module.fail_json( msg='Password is required when adding a user') if 'uid' not in user: user['uid'] = self._nextuid() self.diff['after'] = user user_elt = self.pfsense.new_element('user') self.pfsense.copy_dict_to_element(user, user_elt) self.system.insert(self._find_last_user_idx(), user_elt) self.change_descr = 'ansible pfsensible.core.user added %s' % ( user['name']) else: if 'password' in user: self._validate_password(user) self.diff['before'] = self.pfsense.element_to_dict(user_elt) if 'priv' in self.diff['before']: self.diff['before']['priv'] = self._format_diff_priv( self.diff['before']['priv']) changed = self.pfsense.copy_dict_to_element(user, user_elt) self.diff['after'] = self.pfsense.element_to_dict(user_elt) if 'priv' in self.diff['after']: self.diff['after']['priv'] = self._format_diff_priv( self.diff['after']['priv']) self.change_descr = 'ansible pfsensible.core.user updated "%s"' % ( user['name']) # Handle group member element - need uid set or retrieved above if 'groups' in user: uid = user_elt.find('uid').text # Get current group membership self.diff['before']['groups'] = self._find_groups_for_uid(uid) # Add user to groups if needed for group in user['groups']: group_elt, group_idx = self._find_group(group) if group_elt is None: self.module.fail_json(msg='Group (%s) does not exist' % group) member_found = False for member_elt in group_elt.findall('member'): if member_elt.text == uid: member_found = True if not member_found: changed = True mod_groups.append(group) group_elt.append(self.pfsense.new_element('member', uid)) # Remove user from groups if needed for group in self.diff['before']['groups']: if group not in user['groups']: group_elt, group_idx = self._find_group(group) if group_elt is None: self.module.fail_json(msg='Group (%s) does not exist' % group) for member_elt in group_elt.findall('member'): if member_elt.text == uid: changed = True mod_groups.append(group) group_elt.remove(member_elt) break # Groups are not stored in the user element self.diff['after']['groups'] = user.pop('groups') # Decode keys for diff for k in self.diff: if 'authorizedkeys' in self.diff[k]: self.diff[k]['authorizedkeys'] = base64.b64decode( self.diff[k]['authorizedkeys']) if changed and not self.module.check_mode: self.pfsense.write_config(descr=self.change_descr) (dummy, stdout, stderr) = self.pfsense.phpshell( USER_PHP_COMMAND_SET.format(idx=user_idx, mod_groups=mod_groups)) self.module.exit_json(changed=changed, diff=self.diff, stdout=stdout, stderr=stderr) def remove(self, user): user_elt, user_idx = self._find_user(user['name']) changed = False stdout = None stderr = None uid = user_elt.find('uid').text mod_groups = [] self.diff['after'] = {} if user_elt is not None: changed = True self.diff['before'] = self.pfsense.element_to_dict(user_elt) # Get current group membership self.diff['before']['groups'] = self._find_groups_for_uid(uid) # Remove user from groups if needed for group in self.diff['before']['groups']: group_elt, group_idx = self._find_group(group) if group_elt is None: self.module.fail_json(msg='Group (%s) does not exist' % group) for member_elt in group_elt.findall('member'): if member_elt.text == uid: mod_groups.append(group) group_elt.remove(member_elt) break self.system.remove(user_elt) if changed and not self.module.check_mode: (dummy, stdout, stderr) = self.pfsense.phpshell( USER_PHP_COMMAND_DEL.format(cmd='del', idx=user_idx, mod_groups=mod_groups)) self.pfsense.write_config( descr='ansible pfsensible.core.user removed "%s"' % (user['name'])) self.module.exit_json(changed=changed, diff=self.diff, stdout=stdout, stderr=stderr)