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