summaryrefslogtreecommitdiffstats
path: root/swiftkerbauth
diff options
context:
space:
mode:
authorPrashanth Pai <ppai@redhat.com>2014-01-15 15:31:07 +0530
committerChetan Risbud <crisbud@redhat.com>2014-01-17 01:28:11 -0800
commitd5fe1795d40db8c61c0c84d29a8131600e0986bb (patch)
treeb993985129c9f13b87aaa2fc65dd31d1e5dab454 /swiftkerbauth
parentf952c756ad024e100953a43b1f297f82b5c8f3e2 (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.py4
-rw-r--r--swiftkerbauth/kerbauth_utils.py25
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