예제 #1
0
    def _conversation(
        self, auth, query_list, data
    ):  # type: (Any, List[Tuple[Any, Any]], Any) -> Iterator[Tuple[str, int]]
        answers, prompts, missing = data
        prompts.extend(query_list)
        for query, qt in query_list:
            prompt = qt
            if qt == PAM_PROMPT_ECHO_OFF and query.strip(
                    ':\t ') in self.custom_prompts:
                prompt = query

            response = ''
            try:
                response = answers[prompt]
                if isinstance(response, list):
                    response = response.pop(0)
            except KeyError as exc:
                AUTH.error('Missing answer for prompt: %r' % (str(exc), ))
                missing.append(query)
            except IndexError:
                AUTH.error('Unexpected prompt: %r' % (query, ))

            if qt in (PAM_TEXT_INFO, PAM_ERROR_MSG):
                AUTH.info('PAM says: %r' % (query, ))
            # AUTH.error('# PAM(%d) %s: answer=%r' % (qt, repr(query).strip("':\" "), response))
            yield (response, 0)
    def __authenticate_thread(self, pam, username, password, new_password,
                              **custom_prompts):
        AUTH.info('Trying to authenticate user %r' % (username, ))
        username = self.__canonicalize_username(username)
        try:
            pam.authenticate(username, password, **custom_prompts)
        except AuthenticationFailed as auth_failed:
            AUTH.error(str(auth_failed))
            raise
        except PasswordExpired as pass_expired:
            AUTH.info(str(pass_expired))
            if new_password is None:
                raise

            try:
                pam.change_password(username, password, new_password)
            except PasswordChangeFailed as change_failed:
                AUTH.error(str(change_failed))
                raise
            else:
                AUTH.info('Password change for %r was successful' %
                          (username, ))
                return (username, new_password)
        else:
            AUTH.info('Authentication for %r was successful' % (username, ))
            return (username, password)
예제 #3
0
	def __canonicalize_username(self, username):
		try:
			lo, po = get_machine_connection(write=False)
			result = None
			if lo:
				attr = 'mailPrimaryAddress' if '@' in username else 'uid'
				result = lo.search(filter_format('(&(%s=%s)(objectClass=person))', (attr, username)), attr=['uid'], unique=True)
			if result and result[0][1].get('uid'):
				username = result[0][1]['uid'][0]
				AUTH.info('Canonicalized username: %r' % (username,))
		except (ldap.LDAPError, udm_errors.ldapError) as exc:
			# /etc/machine.secret missing or LDAP server not reachable
			AUTH.warn('Canonicalization of username was not possible: %s' % (exc,))
			reset_cache()
		except:
			AUTH.error('Canonicalization of username failed: %s' % (traceback.format_exc(),))
		finally:  # ignore all exceptions, even in except blocks
			return username