Пример #1
0
 def delete_tokens(self):
     """Delete all tokens for a Duo user account."""
     for token in self.token_ids:
         try:
             self.admin_api.delete_user_token(self.user_id, token)
         except RuntimeError as err:
             raise PluginError('Duo API error - %s' % err.message)
     # verify deletion
     self._get_user_result()
     if self.token_ids:
         raise PluginError('Deleting tokens - Verification failed')
Пример #2
0
 def delete_phones(self):
     """Delete all phones for a Duo user account."""
     for phone in self.phone_ids:
         try:
             self.admin_api.delete_user_phone(self.user_id, phone)
         except RuntimeError as err:
             raise PluginError('Duo API error - %s' % err.message)
     # verify deletion
     self._get_user_result()
     if self.phone_ids:
         raise PluginError('Deleting phones - Verification failed')
Пример #3
0
 def __init__(self, username, reason):
     self._setup_plugins_config()
     self.username = username
     self.reason = reason
     # Load GAM
     try:
         import sys
         sys.path.append(self.gam_location)
         import gam
         self.gam = gam.ProcessGAMCommand
     except IOError:
         raise PluginError('Failed locate GAM.')
     except ImportError:
         raise PluginError('Failed to import GAM.')
Пример #4
0
    def _get(self, username):
        """Get one or more Active Directory user objects."""
        try:
            result = self.ldapl.search_name(username)
        except ldap.LDAPError:
            raise PluginError('LDAP error - Invalid Base DN')

        if len(result) == 0:
            raise PluginError('User "%s" does not exist.' % username)
        elif len(result) > 1:
            raise PluginError(
                'More than one result found for "%s".' % username)
        elif len(result) == 1:
            return result[0][0][1]
Пример #5
0
 def disable(self):
     """Disables an Active Directory user account."""
     new_uac = str(int(self.aduser['userAccountControl'][0]) | 0x00000002)
     try:
         self.ldapl.conn.modify_s(
             self.aduser['distinguishedName'][0],
             [(ldap.MOD_REPLACE, 'userAccountControl', [new_uac])])
         self.aduser = self._get(self.aduser['sAMAccountName'][0])
         if not int(self.aduser['userAccountControl'][0]) & 0x00000002:
             raise PluginError(
                 'Disabling account - Verification failed.')
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while disabling AD account: %s' %
             self._get_ldap_errors(err))
Пример #6
0
 def _remove_group(self, group):
     """Remove Google user from group."""
     out = self._run_gam('gam update group %s remove user %s' % (
         group, self.username))[1]
     if out != ' removing %s@%s\n' % (self.username, self.domain):
         raise PluginError(
             'Removing user from group - Verification failed.')
Пример #7
0
 def _add_group(self, group_dn):
     """Add a user object to an Active Directory group."""
     try:
         self.ldapl.conn.modify_s(
             group_dn,  # distinguishedName
             [(ldap.MOD_ADD, 'member', self.aduser['distinguishedName'])]
         )
         self.aduser = self._get(self.aduser['sAMAccountName'][0])
         if ('memberOf' not in self.aduser or
                 group_dn not in self.aduser['memberOf']):
             raise PluginError(
                 'Adding to group "%s" - Verification failed.' % group_dn)
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while adding user to group: %s' %
             self._get_ldap_errors(err))
Пример #8
0
    def _update_file_state(self, fstate):
        """Updates file state by hash for all Bit9 policies."""
        # disable warnings when not verifying certificate
        if not self.strong_cert:
            requests.packages.urllib3.disable_warnings()

        auth_json = {
            'X-Auth-Token': self.token,
            'content-type': 'application/json',
        }
        data = {
            'hash': self.hashcode,
            'name': self.reason,
            'fileState': fstate,  # 1 means 'unapproved', 3 means 'banned'
        }

        # make request to Bit9
        try:
            bit9_request = requests.post(
                self.url,
                json.dumps(data),
                headers=auth_json,
                verify=self.strong_cert,
                timeout=60,
            )
            bit9_request.raise_for_status()
        except requests.exceptions.RequestException as err:
            raise PluginError('Bit9 server failed to respond - %s.' % err)
Пример #9
0
 def _move(self, newsuperior):
     """Move an Active Directory user to another organizational unit."""
     try:
         self.ldapl.conn.rename_s(
             self.aduser['distinguishedName'][0],
             'cn=%s' % self.aduser['cn'][0],
             newsuperior)
         self.aduser = self._get(self.aduser['sAMAccountName'][0])
         superior = self.aduser['distinguishedName'][0].split(
             ',', 1)[1]
         if newsuperior.lower() != superior.lower():
             raise PluginError(
                 'Moving to "%s" - Verification failed.' % newsuperior)
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while moving AD object: %s' %
             self._get_ldap_errors(err))
Пример #10
0
def get_plugin_config_options(section):
    """Get configuration options from plugins.ini."""
    config = SafeConfigParser()
    config.read('plugins.ini')
    try:
        return dict(config.items(section))
    except NoSectionError:
        raise PluginError('No "%s" section in plugins.ini' % section)
Пример #11
0
    def deactivate_user(self):
        """Deactivate LastPass user.

        Blocks logins but retains data and enterprise membership.
        """
        num_users_disabled = 0
        users_unverified = []
        for domain in self.domains:
            email = '%s@%s' % (self.username, domain)
            # get user
            try:
                user = self._get_user_api(email)
            except PluginError as err:
                # user not found, go to next domain in list
                if err.message == '%s is not a valid user.' % email:
                    continue
                else:
                    raise
            # validate data
            if 'Users' not in user or len(user['Users']) < 1:
                continue
            try:
                uid = user['Users'].keys()[0]
                if not user['Users'][uid]['disabled']:
                    # disable user
                    self._delete_user_api(email, 0)
                    # verification
                    user = self._get_user_api(email)
                    if user['Users'][uid]['disabled']:
                        num_users_disabled += 1
                    else:
                        users_unverified.append(email)
                # user already disabled
                else:
                    num_users_disabled += 1
            except KeyError:
                raise PluginError('Received unexpected response from server.')
        if users_unverified:
            users = ' and '.join(users_unverified)
            raise PluginError(
                'Deactivating user - Verification failed for %s.' % users)
        if not num_users_disabled:
            domains = ' or '.join(self.domains)
            raise PluginError('Deactivating user - no users found for %s.' %
                              domains)
Пример #12
0
 def _setup_plugins_config(self):
     """Setup values from plugins.ini configuration."""
     option = get_plugin_config_options('lastpass')
     try:
         self.cid = option['cid']
         self.provhash = option['provhash']
         self.domains = convert_str_tolist(option['domains'])
     except KeyError as err:
         raise PluginError('No "%s" option in plugins.ini' % err.message)
Пример #13
0
 def _get_user_result(self):
     """"Lookup Duo user by name and store result."""
     self.user_result = None
     try:
         result = self.admin_api.get_users_by_name(self.username)
     except RuntimeError as err:
         raise PluginError('Duo API error - %s' % err.message)
     if not result:
         raise PluginError('User could not be found.')
     # check that response contains everything expected
     if (isinstance(result, list) and len(result) == 1
             and isinstance(result[0], dict)
             and set(['user_id', 'phones', 'tokens']) <= set(result[0])
             and isinstance(result[0]['phones'], list)
             and isinstance(result[0]['tokens'], list)):
         self.user_result = result[0]
     else:
         raise PluginError('Received unexpected response from server.')
Пример #14
0
 def randomize_password(self):
     """Changes a Google user's password to a random value."""
     out = self.info
     new_pwd = generate_random_string(
         self.reset_password_length)
     out = self._update('password \'%s\'' % new_pwd)
     if out != 'updating user %s@%s...\n' % (self.username, self.domain):
         raise PluginError(
             'Randomizing password - Verification failed.')
Пример #15
0
 def _run_gam(self, gam_cmd):
     """Take a GAM command string and run it."""
     with capture_stdout() as out:
         self.gam(gam_cmd.split())
     if out[1]:
         if '403' in out[1]:
             raise PluginError(
                 'GAM error - Not authorized to access this resource/API.')
     return out
Пример #16
0
 def _setup_plugins_config(self):
     """Setup values from plugins.ini configuration."""
     option = get_plugin_config_options('google')
     try:
         self.domain = option['domain']
         self.reset_password_length = int(option['reset_password_length'])
         self.gam_location = option['gam_location']
         self.backup_dir = option['backup_dir']
     except KeyError as err:
         raise PluginError('No "%s" option in plugins.ini' % err.message)
Пример #17
0
 def suspend(self):
     """Suspend a Google user account."""
     self._update('suspended on')
     out = self.info
     for line in out.split('\n'):
         if line.startswith('Account Suspended:'):
             result = line.split(':')[1].strip()
             if result == 'True':
                 return
     raise PluginError('Suspending account - Verification failed.')
Пример #18
0
 def remove_from_gal(self):
     """Remove a Google user from the Global Address List."""
     self._update('gal off')
     out = self.info
     for line in out.split('\n'):
         if line.startswith('Included in GAL:'):
             result = line.split(':')[1].strip()
             if result == 'False':
                 return
     raise PluginError('Removing from GAL - Verification failed.')
Пример #19
0
 def _setup_plugins_config(self):
     """Setup values from plugins.ini configuration."""
     option = plugins.utils.get_plugin_config_options('bit9')
     try:
         self.token = option['token']
         self.url = option['url']
         self.strong_cert = True
         if option['strong_cert'].lower() == 'false':
             self.strong_cert = False
     except KeyError as err:
         raise PluginError('No "%s" option in plugins.ini' % err.message)
Пример #20
0
 def _setup_plugins_config(self):
     """Setup values from plugins.ini configuration."""
     option = get_plugin_config_options('duo')
     try:
         self.admin_api = duo_client.Admin(
             ikey=option['integration_key'],
             skey=option['secret_key'],
             host=option['api_hostname'],
         )
     except KeyError as err:
         raise PluginError('No "%s" option in plugins.ini' % err.message)
Пример #21
0
 def _call_api(self, cmd, data):
     """Make a call to the LastPass Provisioning API."""
     api_url = 'https://lastpass.com/enterpriseapi.php'
     post_data = {
         'cid': self.cid,
         'provhash': self.provhash,
         'cmd': cmd,
         'data': data,
     }
     response = requests.post(api_url, data=json.dumps(post_data))
     if response.status_code == requests.codes.ok:
         try:
             json_response = response.json()
         except ValueError:
             raise PluginError('API is not configured correctly.')
         if 'error' in json_response:
             raise PluginError(json_response['error'][0])
         return json_response
     else:
         raise PluginError('HTTP %s' % response.status_code)
Пример #22
0
 def randomize_password(self):
     """Change an Active Directory user's password to a random value."""
     new_pwd = generate_random_string(self.reset_password_length)
     new_pwd = unicode('\"' + new_pwd + '\"').encode('utf-16-le')
     try:
         self.ldapl.conn.modify_s(
             self.aduser['distinguishedName'][0],
             [(ldap.MOD_REPLACE, 'unicodePwd', [new_pwd])])
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while randomizing AD password: %s' %
             self._get_ldap_errors(err))
Пример #23
0
 def remove_group_memberships(self):
     """Remove an Active Directory user from all groups."""
     if 'memberOf' not in self.aduser:
         return
     self._backup_group_memberships()
     try:
         for group in self.aduser['memberOf']:
             self.ldapl.conn.modify_s(
                 group,
                 [(
                     ldap.MOD_DELETE,
                     'member',
                     self.aduser['distinguishedName'])])
         self.aduser = self._get(self.aduser['sAMAccountName'][0])
         if 'memberOf' in self.aduser:
             raise PluginError(
                 'Removing group memberships - Verification failed.')
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while removing from groups: %s' %
             self._get_ldap_errors(err))
Пример #24
0
 def __init__(self, username, reason):
     # create LDAP connection
     self._setup_plugins_config()
     self.ldapl = PyLDAPLite(
         server='ldaps://%s' % self.server, base_dn=self.base_dn)
     try:
         self.ldapl.connect(self.admin, self.password)
     except ldap.LDAPError as err:
         raise PluginError(
             'LDAP error while creating connection: %s' %
             self._get_ldap_errors(err))
     self.aduser = self._get(username)
     self.reason = reason
Пример #25
0
 def _setup_plugins_config(self):
     """Setup values from plugins.ini configuration."""
     option = get_plugin_config_options('activedirectory')
     try:
         self.server = option['server']
         self.base_dn = option['base_dn']
         self.admin = option['admin']
         self.password = option['password']
         self.reset_password_length = int(option['reset_password_length'])
         self.backup_dir = option['backup_dir']
         self.disabled_group = option['disabled_group']
         self.disabled_ou = option['disabled_ou']
     except KeyError as err:
         raise PluginError('No "%s" option in plugins.ini' % err.message)
Пример #26
0
 def _backup_group_memberships(self):
     """Backup a user's group memberships."""
     groups = self.groups
     if not groups:
         return
     backup_file = '%s_googlegroups_%s.txt' % (
         self.username, datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
     try:
         with open('%s/%s' % (self.backup_dir, backup_file), 'w') as fil:
             for grp in groups:
                 fil.write("%s\n" % grp)
     except IOError:
         raise PluginError(
             'Error writing group memberships to backup file.')
Пример #27
0
 def info(self):
     """Get Google user account information."""
     out = self._run_gam('gam info user %s' % self.username)[0]
     if not out:
         raise PluginError('GAM error - User could not be found.')
     return out