diff options
author | Prashanth Pai <ppai@redhat.com> | 2014-01-15 15:31:07 +0530 |
---|---|---|
committer | Chetan Risbud <crisbud@redhat.com> | 2014-01-17 01:28:11 -0800 |
commit | d5fe1795d40db8c61c0c84d29a8131600e0986bb (patch) | |
tree | b993985129c9f13b87aaa2fc65dd31d1e5dab454 /swiftkerbauth | |
parent | f952c756ad024e100953a43b1f297f82b5c8f3e2 (diff) |
Handle case in passive mode where Kerberos password has expired
In RHEL IdM or Windows AD server, the administrator can expire user passwords
after certain period of time. On password expiry, running kinit will present
a prompt to enter the new passwod. This used to result in kinit subprocess
waiting indefinitely for user input and request never reaching completion.
This fix will kill kinit child process if it is taking too long to finish.
Change-Id: I129a420663c67debe3345448a172b54abc8179bc
Signed-off-by: Prashanth Pai <ppai@redhat.com>
Reviewed-on: http://review.gluster.org/6713
Tested-by: Chetan Risbud <crisbud@redhat.com>
Reviewed-by: Chetan Risbud <crisbud@redhat.com>
Diffstat (limited to 'swiftkerbauth')
-rw-r--r-- | swiftkerbauth/kerbauth.py | 4 | ||||
-rw-r--r-- | swiftkerbauth/kerbauth_utils.py | 25 |
2 files changed, 27 insertions, 2 deletions
diff --git a/swiftkerbauth/kerbauth.py b/swiftkerbauth/kerbauth.py index c8b51fb..fa06bcd 100644 --- a/swiftkerbauth/kerbauth.py +++ b/swiftkerbauth/kerbauth.py @@ -407,6 +407,10 @@ class KerbAuth(object): return HTTPServerError("kinit command not found\n") if ret != 0: self.logger.warning("Failed: kinit %s", user) + if ret == -1: + self.logger.warning("Failed: kinit: Password has probably " + "expired.") + return HTTPServerError("Kinit is taking too long.\n") return HTTPUnauthorized(request=req) self.logger.debug("kinit succeeded") diff --git a/swiftkerbauth/kerbauth_utils.py b/swiftkerbauth/kerbauth_utils.py index 683cdea..effa472 100644 --- a/swiftkerbauth/kerbauth_utils.py +++ b/swiftkerbauth/kerbauth_utils.py @@ -16,6 +16,7 @@ import re import random import grp +import signal from subprocess import Popen, PIPE from time import time from swiftkerbauth import TOKEN_LIFE, RESELLER_PREFIX @@ -111,5 +112,25 @@ def run_kinit(username, password): kinit = Popen(['kinit', username], stdin=PIPE, stdout=PIPE, stderr=PIPE) kinit.stdin.write('%s\n' % password) - kinit.wait() - return kinit.returncode + + # The following code handles a corner case where the Kerberos password + # has expired and a prompt is displayed to enter new password. Ideally, + # we would want to read from stdout but these are blocked reads. This is + # a hack to kill the process if it's taking too long! + + class Alarm(Exception): + pass + + def signal_handler(signum, frame): + raise Alarm + # Set the signal handler and a 1-second alarm + signal.signal(signal.SIGALRM, signal_handler) + signal.alarm(1) + try: + kinit.wait() # Wait for the child to exit + signal.alarm(0) # Reset the alarm + return kinit.returncode # Exit status of child on graceful exit + except Alarm: + # Taking too long, kill and return error + kinit.kill() + return -1 |