talk to PAM in a thread

since PAM can be slow, we don't want to block the rest of the application
This commit is contained in:
Min RK
2018-03-01 11:22:01 +01:00
parent f0494cc7d6
commit 4de6b39788

View File

@@ -3,19 +3,22 @@
# Copyright (c) IPython Development Team. # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
from concurrent.futures import ThreadPoolExecutor
import pipes import pipes
import re import re
from shutil import which from shutil import which
import sys import sys
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
from tornado import gen
try: try:
import pamela import pamela
except Exception as e: except Exception as e:
pamela = None pamela = None
_pamela_error = e _pamela_error = e
from tornado.concurrent import run_on_executor
from tornado import gen
from traitlets.config import LoggingConfigurable from traitlets.config import LoggingConfigurable
from traitlets import Bool, Set, Unicode, Dict, Any, default, observe from traitlets import Bool, Set, Unicode, Dict, Any, default, observe
@@ -520,6 +523,12 @@ class LocalAuthenticator(Authenticator):
class PAMAuthenticator(LocalAuthenticator): class PAMAuthenticator(LocalAuthenticator):
"""Authenticate local UNIX users with PAM""" """Authenticate local UNIX users with PAM"""
# run PAM in a thread, since it can be slow
executor = Any()
@default('executor')
def _default_executor(self):
return ThreadPoolExecutor(1)
encoding = Unicode('utf8', encoding = Unicode('utf8',
help=""" help="""
The text encoding to use when communicating with PAM The text encoding to use when communicating with PAM
@@ -550,7 +559,7 @@ class PAMAuthenticator(LocalAuthenticator):
raise _pamela_error from None raise _pamela_error from None
super().__init__(**kwargs) super().__init__(**kwargs)
@gen.coroutine @run_on_executor
def authenticate(self, handler, data): def authenticate(self, handler, data):
"""Authenticate with PAM, and return the username if login is successful. """Authenticate with PAM, and return the username if login is successful.
@@ -567,6 +576,7 @@ class PAMAuthenticator(LocalAuthenticator):
else: else:
return username return username
@run_on_executor
def pre_spawn_start(self, user, spawner): def pre_spawn_start(self, user, spawner):
"""Open PAM session for user if so configured""" """Open PAM session for user if so configured"""
if not self.open_sessions: if not self.open_sessions:
@@ -578,6 +588,7 @@ class PAMAuthenticator(LocalAuthenticator):
self.log.warning("Disabling PAM sessions from now on.") self.log.warning("Disabling PAM sessions from now on.")
self.open_sessions = False self.open_sessions = False
@run_on_executor
def post_spawn_stop(self, user, spawner): def post_spawn_stop(self, user, spawner):
"""Close PAM session for user if we were configured to opened one""" """Close PAM session for user if we were configured to opened one"""
if not self.open_sessions: if not self.open_sessions: