ac7d03
From 8c6cafb9d331d15cb224820c3bc254c84b49a0c7 Mon Sep 17 00:00:00 2001
ac7d03
From: Simo Sorce <simo@redhat.com>
ac7d03
Date: Thu, 22 Jun 2017 10:57:25 -0400
ac7d03
Subject: [PATCH] Make sure we check ccaches in all rpcserver paths
ac7d03
ac7d03
We need to verify the ccache is avcailable in all cases or finalize
ac7d03
will cause us to acquire creds with the keytab which is not what we
ac7d03
want.
ac7d03
ac7d03
Ticket #7037
ac7d03
ac7d03
Signed-off-by: Simo Sorce <simo@redhat.com>
ac7d03
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
ac7d03
---
ac7d03
 ipaserver/rpcserver.py | 72 +++++++++++++++++++++++++++-----------------------
ac7d03
 1 file changed, 39 insertions(+), 33 deletions(-)
ac7d03
ac7d03
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
ac7d03
index 2990df25985eab63d4bcfc8edf7f2b12da3e9832..9efe3c1f4b9e0114a02e8e04aafc76c3bc04c6f1 100644
ac7d03
--- a/ipaserver/rpcserver.py
ac7d03
+++ b/ipaserver/rpcserver.py
ac7d03
@@ -592,6 +592,41 @@ class KerberosSession(HTTP_Status):
ac7d03
     needing this do not share a common base class.
ac7d03
     '''
ac7d03
 
ac7d03
+    def need_login(self, start_response):
ac7d03
+        status = '401 Unauthorized'
ac7d03
+        headers = []
ac7d03
+        response = b''
ac7d03
+
ac7d03
+        self.debug('%s need login', status)
ac7d03
+
ac7d03
+        start_response(status, headers)
ac7d03
+        return [response]
ac7d03
+
ac7d03
+    def get_environ_creds(self, environ):
ac7d03
+        # If we have a ccache ...
ac7d03
+        ccache_name = environ.get('KRB5CCNAME')
ac7d03
+        if ccache_name is None:
ac7d03
+            self.debug('no ccache, need login')
ac7d03
+            return
ac7d03
+
ac7d03
+        # ... make sure we have a name ...
ac7d03
+        principal = environ.get('GSS_NAME')
ac7d03
+        if principal is None:
ac7d03
+            self.debug('no Principal Name, need login')
ac7d03
+            return
ac7d03
+
ac7d03
+        # ... and use it to resolve the ccache name (Issue: 6972 )
ac7d03
+        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
ac7d03
+
ac7d03
+        # Fail if Kerberos credentials are expired or missing
ac7d03
+        creds = get_credentials_if_valid(name=gss_name,
ac7d03
+                                         ccache_name=ccache_name)
ac7d03
+        if not creds:
ac7d03
+            self.debug('ccache expired or invalid, deleting session, need login')
ac7d03
+            return
ac7d03
+
ac7d03
+        return ccache_name
ac7d03
+
ac7d03
 
ac7d03
     def finalize_kerberos_acquisition(self, who, ccache_name, environ, start_response, headers=None):
ac7d03
         if headers is None:
ac7d03
@@ -754,43 +789,15 @@ class jsonserver_session(jsonserver, KerberosSession):
ac7d03
     def _on_finalize(self):
ac7d03
         super(jsonserver_session, self)._on_finalize()
ac7d03
 
ac7d03
-    def need_login(self, start_response):
ac7d03
-        status = '401 Unauthorized'
ac7d03
-        headers = []
ac7d03
-        response = b''
ac7d03
-
ac7d03
-        self.debug('jsonserver_session: %s need login', status)
ac7d03
-
ac7d03
-        start_response(status, headers)
ac7d03
-        return [response]
ac7d03
-
ac7d03
     def __call__(self, environ, start_response):
ac7d03
         '''
ac7d03
         '''
ac7d03
 
ac7d03
         self.debug('WSGI jsonserver_session.__call__:')
ac7d03
 
ac7d03
-        ccache_name = environ.get('KRB5CCNAME')
ac7d03
-
ac7d03
         # Redirect to login if no Kerberos credentials
ac7d03
+        ccache_name = self.get_environ_creds(environ)
ac7d03
         if ccache_name is None:
ac7d03
-            self.debug('no ccache, need login')
ac7d03
-            return self.need_login(start_response)
ac7d03
-
ac7d03
-        # If we have a ccache, make sure we have a GSS_NAME and use
ac7d03
-        # it to resolve the ccache name (Issue: 6972 )
ac7d03
-        principal = environ.get('GSS_NAME')
ac7d03
-        if principal is None:
ac7d03
-            self.debug('no GSS Name, need login')
ac7d03
-            return self.need_login(start_response)
ac7d03
-        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
ac7d03
-
ac7d03
-        # Redirect to login if Kerberos credentials are expired
ac7d03
-        creds = get_credentials_if_valid(name=gss_name,
ac7d03
-                                         ccache_name=ccache_name)
ac7d03
-        if not creds:
ac7d03
-            self.debug('ccache expired, deleting session, need login')
ac7d03
-            # The request is finished with the ccache, destroy it.
ac7d03
             return self.need_login(start_response)
ac7d03
 
ac7d03
         # Store the ccache name in the per-thread context
ac7d03
@@ -828,11 +835,10 @@ class KerberosLogin(Backend, KerberosSession):
ac7d03
     def __call__(self, environ, start_response):
ac7d03
         self.debug('WSGI KerberosLogin.__call__:')
ac7d03
 
ac7d03
-        # Get the ccache created by mod_auth_gssapi
ac7d03
-        user_ccache_name=environ.get('KRB5CCNAME')
ac7d03
+        # Redirect to login if no Kerberos credentials
ac7d03
+        user_ccache_name = self.get_environ_creds(environ)
ac7d03
         if user_ccache_name is None:
ac7d03
-            return self.internal_error(environ, start_response,
ac7d03
-                                       'login_kerberos: KRB5CCNAME not defined in HTTP request environment')
ac7d03
+            return self.need_login(start_response)
ac7d03
 
ac7d03
         return self.finalize_kerberos_acquisition('login_kerberos', user_ccache_name, environ, start_response)
ac7d03
 
ac7d03
-- 
ac7d03
2.9.4
ac7d03