Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)