summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2009-04-13 18:01:58 -0400
committerRob Crittenden <rcritten@redhat.com>2009-04-20 13:44:08 -0400
commita9387b48e66ca93cc8323869de25fe3f777567b6 (patch)
tree0b706b867766924bea0a5cda92060d5378eef58e
parente6171404bf0dce7cf08ef3044003190e18c851c9 (diff)
downloadfreeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.tar.gz
freeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.tar.xz
freeipa-a9387b48e66ca93cc8323869de25fe3f777567b6.zip
Handle GSSAPI exceptions more gracefully
-rw-r--r--ipalib/errors2.py79
-rw-r--r--ipalib/rpc.py34
-rw-r--r--ipapython/ipautil.py16
3 files changed, 116 insertions, 13 deletions
diff --git a/ipalib/errors2.py b/ipalib/errors2.py
index 33db5ccf..7e752d82 100644
--- a/ipalib/errors2.py
+++ b/ipalib/errors2.py
@@ -458,6 +458,85 @@ class ServiceError(KerberosError):
format = _('Service %(service)r not found in Kerberos database')
+class NoCCacheError(KerberosError):
+ """
+ **1103** Raised when a client attempts to use Kerberos without a ccache.
+
+ For example:
+
+ >>> raise NoCCacheError()
+ Traceback (most recent call last):
+ ...
+ NoCCacheError: No credentials cache found
+ """
+
+ errno = 1103
+ format = _('No credentials cache found')
+
+
+class TicketExpired(KerberosError):
+ """
+ **1104** Raised when a client attempts to use an expired ticket
+
+ For example:
+
+ >>> raise TicketExpired()
+ Traceback (most recent call last):
+ ...
+ TicketExpired: Ticket expired
+ """
+
+ errno = 1104
+ format = _('Ticket expired')
+
+
+class BadCCachePerms(KerberosError):
+ """
+ **1105** Raised when a client has bad permissions on their ccache
+
+ For example:
+
+ >>> raise BadCCachePerms()
+ Traceback (most recent call last):
+ ...
+ BadCCachePerms: Credentials cache permissions incorrect
+ """
+
+ errno = 1105
+ format = _('Credentials cache permissions incorrect')
+
+
+class BadCCacheFormat(KerberosError):
+ """
+ **1106** Raised when a client has a misformated ccache
+
+ For example:
+
+ >>> raise BadCCacheFormat()
+ Traceback (most recent call last):
+ ...
+ BadCCacheFormat: Bad format in credentials cache
+ """
+
+ errno = 1106
+ format = _('Bad format in credentials cache')
+
+
+class CannotResolveKDC(KerberosError):
+ """
+ **1107** Raised when the KDC can't be resolved
+
+ For example:
+
+ >>> raise CannotResolveKDC()
+ Traceback (most recent call last):
+ ...
+ CannotResolveKDC: Cannot resolve KDC for requested realm
+ """
+
+ errno = 1107
+ format = _('Cannot resolve KDC for requested realm')
+
##############################################################################
# 2000 - 2999: Authorization errors
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 5c336ca1..b0b55ce5 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -34,15 +34,24 @@ from types import NoneType
import threading
import socket
import os
+import errno
from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, Transport
import kerberos
from ipalib.backend import Connectible
from ipalib.errors2 import public_errors, PublicError, UnknownError, NetworkError
from ipalib import errors2
from ipalib.request import context
+from ipapython import ipautil
from OpenSSL import SSL
import httplib
+# Some Kerberos error definitions from krb5.h
+KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = (-1765328377L)
+KRB5KRB_AP_ERR_TKT_EXPIRED = (-1765328352L)
+KRB5_FCC_PERM = (-1765328190L)
+KRB5_FCC_NOFILE = (-1765328189L)
+KRB5_CC_FORMAT = (-1765328185L)
+KRB5_REALM_CANT_RESOLVE = (-1765328164L)
def xml_wrap(value):
"""
@@ -304,6 +313,23 @@ class KerbTransport(SSLTransport):
Handles Kerberos Negotiation authentication to an XML-RPC server.
"""
+ def _handle_exception(self, e, service=None):
+ (major, minor) = ipautil.get_gsserror(e)
+ if minor[1] == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
+ raise errors2.ServiceError(service=service)
+ elif minor[1] == KRB5_FCC_NOFILE:
+ raise errors2.NoCCacheError()
+ elif minor[1] == KRB5KRB_AP_ERR_TKT_EXPIRED:
+ raise errors2.TicketExpired()
+ elif minor[1] == KRB5_FCC_PERM:
+ raise errors2.BadCCachePerms()
+ elif minor[1] == KRB5_CC_FORMAT:
+ raise errors2.BadCCacheFormat()
+ elif minor[1] == KRB5_REALM_CANT_RESOLVE:
+ raise errors2.CannotResolveKDC()
+ else:
+ raise errors2.KerberosError(major=major, minor=minor)
+
def get_host_info(self, host):
(host, extra_headers, x509) = SSLTransport.get_host_info(self, host)
@@ -316,16 +342,12 @@ class KerbTransport(SSLTransport):
kerberos.GSS_C_MUTUAL_FLAG |
kerberos.GSS_C_SEQUENCE_FLAG)
except kerberos.GSSError, e:
- raise e # FIXME: raise a PublicError
+ self._handle_exception(e)
try:
kerberos.authGSSClientStep(vc, "")
except kerberos.GSSError, e:
- (major, minor) = e.args
- if minor[1] == -1765328377:
- raise errors2.ServiceError(service=service)
- else:
- raise e
+ self._handle_exception(e, service=service)
extra_headers = [
('Authorization', 'negotiate %s' % kerberos.authGSSClientResponse(vc))
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 57f5dcd9..df721a51 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -956,14 +956,16 @@ class ItemCompleter:
return items
def get_gsserror(e):
- """A GSSError exception looks differently in python 2.4 than it does
- in python 2.5, deal with it."""
+ """
+ A GSSError exception looks differently in python 2.4 than it does
+ in python 2.5. Deal with it.
+ """
try:
- primary = e[0]
- secondary = e[1]
+ major = e[0]
+ minor = e[1]
except:
- primary = e[0][0]
- secondary = e[0][1]
+ major = e[0][0]
+ minor = e[0][1]
- return (primary[0], secondary[0])
+ return (major, minor)