On 2015-08-21 15:52, Michael Šimáček wrote:


On 2015-08-20 20:42, Robbie Harwood wrote:
Michael Šimáček <msima...@redhat.com> writes:

On 2015-08-20 12:32, Michael Šimáček wrote:

Michael Šimáček <msima...@redhat.com> writes:

Attaching new revision of the patch. Changes from the previous:
- ldap2's connect now chooses the bind type same way as in ipaldap
- get_default_realm usages replaced by api.env.realm
- fixed missing third kinit attempt in trust-fetch-domains
- removed rewrapping gssapi errors to ccache errors in krb_utils
- updated some parts of exception handling

Rebased on top of current master.

One of the commits reintroduced krbV dependency that I didn't notice.
Attaching updated revision. Only changes against previous revision are
in files daemons/dnssec/ipa-dnskeysync-replica and
daemons/dnssec/ipa-ods-exporter.

This is much better, thanks!  I've got some comments inline.

+except gssapi.exceptions.GSSError:
      # If there was failure on using keytab, assume it is stale and
retrieve again
      retrieve_keytab(api, ccache_name, oneway_keytab_name,
oneway_principal)

This code still bothers me a bit, but I think fixing it is probably
beyond the scope of a python-gssapi port.

The code catches all GSSAPI exceptions and retries to do the same thing
with different keytab. So if there was a problem unrelated to keytab,
the same exception will be raised again. Nothing will be ignored silently.


+    try:
+        creds = get_credentials(name=name, ccache_name=ccache_name)
+        # property access would raise exception if expired
+        if creds.lifetime > 0:
+            return creds
+    except gssapi.exceptions.ExpiredCredentialsError:
+        return None

Per rfc2744, lifetime is unsigned.  It's not immediately clear what will
happen when `creds.lifetime == 0`; perhaps an explicit `return Nune` in
that case?

I think the check is probably redundant, gssapi raises exception upon
inquiring expired credentials. In trust-fetch-domains I just access the
lifetime in try-except without using the value, so I could do the same
here. It would be nice if gssapi provided some 'is_valid' or
'is_expired' method, so I wouldn't need to rely on side-effects of
property access, which is hard to read and confuses pylint.


          # Setup LDAP connection
          try:
-            ctx = krbV.default_context()
-            ccache = ctx.default_ccache()
-            api.Backend.ldap2.connect(ccache)
+            api.Backend.ldap2.connect()
              cls.ldap = api.Backend.ldap2
-        except krbV.Krb5Error as e:
+        except gssapi.exceptions.GSSError:
              sys.exit("Must have Kerberos credentials to migrate
Winsync users.")

Can you log the error here?  The other places GSSError is being caught
are doing a great job of either filtering-and-raising or
logging-and-exiting, so thanks for fixing those.

Yes, I'll update it in next revision of the patch.


+# Ugly hack for test purposes only. GSSAPI has no way to get default
ccache
+# name, but we don't need it outside test server
+def get_default_ccache_name():
+    try:
+        out = check_output(['klist'])
+    except CalledProcessError:
+        raise RuntimeError("Default ccache not found. Did you kinit?")
+    match = re.match(r'^Ticket cache:\s*(\S+)', out)
+    if not match:
+        raise RuntimeError("Cannot obtain ccache name")
+    return match.group(1)

Yup, this is still ugly.  Ah well, it's only test code.


I was trying to modify the code to not need the variable and just use
the default, but it is used for manipulating it as a file - in
production it is always defined by mod_auth_gssapi. So I'd keep this as is.



Next revision of the patch. Changes from previous rev: printing exception in ipa_winsync_migrate and more thorough dealing with credentials expiration in krb_utils and trust-fetch-domains.

Michael
From 4d24baa4ee13db5dbd0f6857d80771df23618b7d Mon Sep 17 00:00:00 2001
From: Michael Simacek <msima...@redhat.com>
Date: Mon, 20 Jul 2015 16:04:07 +0200
Subject: [PATCH] Port from python-krbV to python-gssapi

python-krbV library is deprecated and doesn't work with python 3. Replacing all
it's usages with python-gssapi.

- Removed Backend.krb and KRB5_CCache classes
  They were wrappers around krbV classes that cannot really work without them
- Added few utility functions for querying GSSAPI credentials
  in krb_utils module. They provide replacements for KRB5_CCache.
- Merged two kinit_keytab functions
- Changed ldap plugin connection defaults to match ipaldap
- Unified getting default realm
  Using api.env.realm instead of krbV call
---
 BUILD.txt                                         |   2 +-
 daemons/dnssec/ipa-dnskeysync-replica             |   4 +-
 daemons/dnssec/ipa-ods-exporter                   |   4 +-
 doc/examples/python-api.py                        |   4 +-
 freeipa.spec.in                                   |  10 +-
 install/oddjob/com.redhat.idm.trust-fetch-domains |  88 ++----
 install/tools/ipa-adtrust-install                 |  16 +-
 install/tools/ipa-csreplica-manage                |   5 +-
 install/tools/ipa-replica-manage                  |   7 +-
 ipa-client/ipa-client.spec.in                     |   2 +-
 ipa-client/ipa-install/ipa-client-automount       |   4 +-
 ipa-client/ipa-install/ipa-client-install         |   8 +-
 ipalib/krb_utils.py                               | 337 +++++-----------------
 ipalib/plugins/kerberos.py                        | 125 --------
 ipalib/plugins/passwd.py                          |   6 +-
 ipalib/plugins/vault.py                           |   7 +-
 ipalib/rpc.py                                     |   9 +-
 ipalib/util.py                                    |  12 -
 ipapython/config.py                               |  11 -
 ipapython/ipautil.py                              |  28 +-
 ipaserver/install/ipa_cacert_manage.py            |   7 +-
 ipaserver/install/ipa_ldap_updater.py             |   4 +-
 ipaserver/install/ipa_otptoken_import.py          |   7 +-
 ipaserver/install/ipa_winsync_migrate.py          |  10 +-
 ipaserver/install/ldapupdate.py                   |  10 +-
 ipaserver/install/schemaupdate.py                 |   4 +-
 ipaserver/install/server/upgrade.py               |   3 +-
 ipaserver/plugins/join.py                         |  13 +-
 ipaserver/plugins/ldap2.py                        |  60 ++--
 ipaserver/rpcserver.py                            |  25 +-
 ipatests/test_cmdline/cmdline.py                  |   5 +-
 ipatests/test_cmdline/test_ipagetkeytab.py        |  23 +-
 ipatests/test_xmlrpc/test_dns_plugin.py           |   3 +-
 ipatests/test_xmlrpc/test_netgroup_plugin.py      |   6 +-
 ipatests/test_xmlrpc/test_permission_plugin.py    |   3 +-
 lite-server.py                                    |  16 +-
 make-lint                                         |   4 +-
 37 files changed, 246 insertions(+), 646 deletions(-)
 delete mode 100644 ipalib/plugins/kerberos.py

diff --git a/BUILD.txt b/BUILD.txt
index 53012b14d05673d4fbc4d0567e877348d5e78444..4507fa357375edc09377368ab3d1eb1c48994a61 100644
--- a/BUILD.txt
+++ b/BUILD.txt
@@ -20,7 +20,7 @@ systemd-units samba-devel samba-python libwbclient-devel libtalloc-devel \
 libtevent-devel nspr-devel nss-devel openssl-devel openldap-devel krb5-devel \
 krb5-workstation libuuid-devel libcurl-devel xmlrpc-c-devel popt-devel \
 autoconf automake m4 libtool gettext python-devel python-ldap \
-python-setuptools python-krbV python-nss python-netaddr python-gssapi \
+python-setuptools python-nss python-netaddr python-gssapi \
 python-rhsm pyOpenSSL pylint python-polib libipa_hbac-python python-memcached \
 sssd python-lxml python-pyasn1 python-qrcode-core python-dns m2crypto \
 check libsss_idmap-devel libsss_nss_idmap-devel java-headless rhino \
diff --git a/daemons/dnssec/ipa-dnskeysync-replica b/daemons/dnssec/ipa-dnskeysync-replica
index b80b38962957f922cc871ead471f8da0831bec4d..29864b56114ece631931d32ba2e50d7261dab5db 100755
--- a/daemons/dnssec/ipa-dnskeysync-replica
+++ b/daemons/dnssec/ipa-dnskeysync-replica
@@ -12,7 +12,7 @@ from binascii import hexlify
 from datetime import datetime
 import dns.dnssec
 import fcntl
-from krbV import Krb5Error
+from gssapi import GSSError
 import logging
 import os
 from pprint import pprint
@@ -146,7 +146,7 @@ ccache_filename = os.path.join(WORKDIR, 'ipa-dnskeysync-replica.ccache')
 try:
     ipautil.kinit_keytab(PRINCIPAL, paths.IPA_DNSKEYSYNCD_KEYTAB,
                          ccache_filename, attempts=5)
-except Krb5Error as e:
+except GSSError as e:
     log.critical('Kerberos authentication failed: %s', e)
     sys.exit(1)
 
diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
index 4d5423797fc9d4bdd0a432bac96b8209bb98c6d8..f68fe8373c003909350e2f0d524445422cca41bd 100755
--- a/daemons/dnssec/ipa-ods-exporter
+++ b/daemons/dnssec/ipa-ods-exporter
@@ -20,7 +20,7 @@ from datetime import datetime
 import dateutil.tz
 import dns.dnssec
 import fcntl
-from krbV import Krb5Error
+from gssapi import GSSError
 import logging
 import os
 import subprocess
@@ -487,7 +487,7 @@ ccache_name = os.path.join(WORKDIR, 'ipa-ods-exporter.ccache')
 try:
     ipautil.kinit_keytab(PRINCIPAL, paths.IPA_ODS_EXPORTER_KEYTAB, ccache_name,
                          attempts=5)
-except Krb5Error as e:
+except GSSError as e:
     log.critical('Kerberos authentication failed: %s', e)
     sys.exit(1)
 
diff --git a/doc/examples/python-api.py b/doc/examples/python-api.py
index 805925f262774edca20fd0f31eda214b83a24fc9..215bb915370ffaac9fb64747a42bb2422b69a6e0 100755
--- a/doc/examples/python-api.py
+++ b/doc/examples/python-api.py
@@ -37,9 +37,7 @@ api.finalize()
 # Backend.ldap.connect(), otherwise Backend.rpcclient.connect().
 
 if api.env.in_server:
-    api.Backend.ldap2.connect(
-        ccache=api.Backend.krb.default_ccname()
-     )
+    api.Backend.ldap2.connect()
 else:
     api.Backend.rpcclient.connect()
 
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 50e084c782ece59152ea3cca1ee0b4591ab0a4b7..66a3d37b9875609e22b73f9f856a034d10ab5a41 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -68,11 +68,10 @@ BuildRequires:  gettext
 BuildRequires:  python-devel
 BuildRequires:  python-ldap
 BuildRequires:  python-setuptools
-BuildRequires:  python-krbV
 BuildRequires:  python-nss
 BuildRequires:  python-cryptography
 BuildRequires:  python-netaddr
-BuildRequires:  python-gssapi >= 1.1.1
+BuildRequires:  python-gssapi >= 1.1.2
 BuildRequires:  python-rhsm
 BuildRequires:  pyOpenSSL
 BuildRequires:  pylint >= 1.0
@@ -128,7 +127,7 @@ Requires: mod_wsgi
 Requires: mod_auth_gssapi >= 1.1.0-2
 Requires: mod_nss >= 1.0.8-26
 Requires: python-ldap >= 2.4.15
-Requires: python-krbV
+Requires: python-gssapi >= 1.1.2
 Requires: python-sssdconfig
 Requires: acl
 Requires: python-pyasn1
@@ -263,7 +262,7 @@ Requires: certmonger >= 0.78
 Requires: nss-tools
 Requires: bind-utils
 Requires: oddjob-mkhomedir
-Requires: python-krbV
+Requires: python-gssapi >= 1.1.2
 Requires: python-dns >= 1.11.1
 Requires: libsss_autofs
 Requires: autofs
@@ -287,7 +286,6 @@ Summary: IPA administrative tools
 Group: System Environment/Base
 Requires: %{name}-python = %{version}-%{release}
 Requires: %{name}-client = %{version}-%{release}
-Requires: python-krbV
 Requires: python-ldap
 
 Conflicts: %{alt_name}-admintools
@@ -303,7 +301,7 @@ IPA administrators.
 %package python
 Summary: Python libraries used by IPA
 Group: System Environment/Libraries
-Requires: python-gssapi >= 1.1.1
+Requires: python-gssapi >= 1.1.2
 Requires: gnupg
 Requires: iproute
 Requires: keyutils
diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
index 6a2171d5f1936fabd00081bbbcea562a0e7041b8..d19e06f124e036d10ba33b73d45db6022f6244a6 100755
--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
@@ -7,33 +7,10 @@ from ipalib import api, errors
 from ipapython.dn import DN
 from ipalib.config import Env
 from ipalib.constants import DEFAULT_CONFIG
-from ipalib.krb_utils import KRB5_CCache
+from ipapython.ipautil import kinit_keytab
 import sys
 import os, pwd
-import krbV
-import time
-
-# This version is different from the original in ipapyton.ipautil
-# in the fact that it returns a krbV.CCache object.
-def kinit_keytab(principal, keytab, ccache_name, attempts=1):
-    errors_to_retry = {krbV.KRB5KDC_ERR_SVC_UNAVAILABLE,
-                       krbV.KRB5_KDC_UNREACH}
-    for attempt in range(1, attempts + 1):
-        try:
-            krbcontext = krbV.default_context()
-            ktab = krbV.Keytab(name=keytab, context=krbcontext)
-            princ = krbV.Principal(name=principal, context=krbcontext)
-            ccache = krbV.CCache(name=ccache_name, context=krbcontext,
-                                 primary_principal=princ)
-            ccache.init(princ)
-            ccache.init_creds_keytab(keytab=ktab, principal=princ)
-            return ccache
-        except krbV.Krb5Error as e:
-            if e.args[0] not in errors_to_retry:
-                raise
-            if attempt == attempts:
-                raise
-            time.sleep(5)
+import gssapi
 
 def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
     getkeytab_args = ["/usr/sbin/ipa-getkeytab",
@@ -127,17 +104,21 @@ ccache_name = '/var/run/ipa/krb5cc_oddjob_trusts'
 #   - if not, initialize it from Samba's keytab
 # - refer the correct ccache object for further use
 #
-if not os.path.isfile(ccache_name):
-    ccache = kinit_keytab(principal, keytab_name, ccache_name)
-
-ccache_check = KRB5_CCache(ccache_name)
-if not ccache_check.credential_is_valid(principal):
-    ccache = kinit_keytab(principal, keytab_name, ccache_name)
-else:
-    ccache = ccache_check.ccache
+have_ccache = False
+try:
+    cred = kinit_keytab(principal, keytab_name, ccache_name)
+    if cred.lifetime > 0:
+        have_ccache = True
+except gssapi.exceptions.ExpiredCredentialsError:
+    pass
+if not have_ccache:
+    # delete stale ccache and try again
+    if os.path.exists(oneway_ccache_name):
+        os.unlink(ccache_name)
+    cred = kinit_keytab(principal, keytab_name, ccache_name)
 
 old_ccache = os.environ.get('KRB5CCNAME')
-api.Backend.ldap2.connect(ccache)
+api.Backend.ldap2.connect(ccache_name)
 
 # Retrieve own NetBIOS name and trusted forest's name.
 # We use script's input to retrieve the trusted forest's name to sanitize input
@@ -159,32 +140,25 @@ oneway_principal = str('%s$@%s' % (own_trust_flatname, trusted_domain.upper()))
 if not os.path.isfile(oneway_keytab_name):
     retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
 
-oneway_ccache = None
 try:
-    # The keytab may have stale key material (from older trust-add run)
-    if not os.path.isfile(oneway_ccache_name):
-        oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-    else:
-        oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
-        if not oneway_ccache_check.credential_is_valid(oneway_principal):
-            # If credentials were invalid, obtain them again
-            oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-        else:
-            oneway_ccache = oneway_ccache_check.ccache
-except krbV.Krb5Error as e:
+    have_ccache = False
+    try:
+        # The keytab may have stale key material (from older trust-add run)
+        cred = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
+        if cred.lifetime > 0:
+            have_ccache = True
+    except gssapi.exceptions.ExpiredCredentialsError:
+        pass
+    if not have_ccache:
+        if os.path.exists(oneway_ccache_name):
+            os.unlink(oneway_ccache_name)
+        kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
+except gssapi.exceptions.GSSError:
     # If there was failure on using keytab, assume it is stale and retrieve again
     retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
-
-try:
-    # There wasn existing ccache, validate its content
-    oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
-    if not oneway_ccache_check.credential_is_valid(oneway_principal):
-        # If credentials were invalid, obtain them again
-        oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-    else:
-        oneway_ccache = oneway_ccache_check.ccache
-except krbV.Krb5Error as e:
-    oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
+    if os.path.exists(oneway_ccache_name):
+        os.unlink(oneway_ccache_name)
+    kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
 
 # We are done: we have ccache with TDO credentials and can fetch domains
 ipa_domain = api.env.domain
diff --git a/install/tools/ipa-adtrust-install b/install/tools/ipa-adtrust-install
index a3037440cc9be832d64edec6f1f152407ed75c8b..a60a84e9bcd38f0700b7d9c6b4e3c6586cb47867 100755
--- a/install/tools/ipa-adtrust-install
+++ b/install/tools/ipa-adtrust-install
@@ -21,14 +21,14 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+import gssapi
 from ipaserver.install import adtrustinstance
 from ipaserver.install.installutils import *
 from ipaserver.install import service
 from ipapython import version
 from ipapython import ipautil, sysrestore, ipaldap
-from ipalib import api, errors, util
+from ipalib import api, errors, krb_utils
 from ipapython.config import IPAOptionParser
-import krbV
 from ipaplatform.paths import paths
 from ipapython.ipa_log_manager import *
 from ipapython.dn import DN
@@ -302,21 +302,19 @@ def main():
             print "Proceeding with credentials that existed before"
 
     try:
-        ctx = krbV.default_context()
-        ccache = ctx.default_ccache()
-        principal = ccache.principal()
-    except krbV.Krb5Error as e:
-        sys.exit("Must have Kerberos credentials to setup AD trusts on server")
+        principal = krb_utils.get_principal()
+    except gssapi.exceptions.GSSError as e:
+        sys.exit("Must have Kerberos credentials to setup AD trusts on server: %s" % e.message)
 
     try:
-        api.Backend.ldap2.connect(ccache)
+        api.Backend.ldap2.connect()
     except errors.ACIError as e:
         sys.exit("Outdated Kerberos credentials. Use kdestroy and kinit to update your ticket")
     except errors.DatabaseError as e:
         sys.exit("Cannot connect to the LDAP database. Please check if IPA is running")
 
     try:
-        user = api.Command.user_show(unicode(principal[0]))['result']
+        user = api.Command.user_show(principal)['result']
         group = api.Command.group_show(u'admins')['result']
         if not (user['uid'][0] in group['member_user'] and
                 group['cn'][0] in user['memberof_group']):
diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index 3a5c78aa41da11287054489c0f1157fdf42994da..eec8bb2c88790bc6d9cbf195da5c08a5e0d52e51 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -22,12 +22,11 @@
 import sys
 import os
 
-import krbV
 from ipapython.ipa_log_manager import *
 
 from ipaserver.install import (replication, installutils, bindinstance,
     cainstance, certs)
-from ipalib import api, errors, util
+from ipalib import api, errors
 from ipalib.constants import CACERT
 from ipapython import ipautil, ipaldap, version, dogtag
 from ipapython.dn import DN
@@ -407,7 +406,7 @@ def main():
     api.finalize()
 
     dirman_passwd = None
-    realm = krbV.default_context().default_realm
+    realm = api.env.realm
 
     if options.host:
         host = options.host
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 1c9c7d32c43a2169b13a019f2bc8730f531f7573..f26c6ab6054378cddaa7c6ebc9013ab5369f0776 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -20,7 +20,7 @@
 import sys
 import os
 
-import re, krbV
+import re
 import traceback
 from urllib2 import urlparse
 import ldap
@@ -1379,7 +1379,7 @@ def main():
     api.finalize()
 
     dirman_passwd = None
-    realm = krbV.default_context().default_realm
+    realm = api.env.realm
 
     if options.host:
         host = options.host
@@ -1404,8 +1404,7 @@ def main():
         api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
                                   bind_pw=options.dirman_passwd)
     else:
-        ccache = krbV.default_context().default_ccache()
-        api.Backend.ldap2.connect(ccache=ccache)
+        api.Backend.ldap2.connect()
 
     if args[0] == "list":
         replica = None
diff --git a/ipa-client/ipa-client.spec.in b/ipa-client/ipa-client.spec.in
index 686259ad24b241c232dce83b695a05f6fd6c3849..4413937bb6c98ef4ad8e87f1b94246b98d82755c 100644
--- a/ipa-client/ipa-client.spec.in
+++ b/ipa-client/ipa-client.spec.in
@@ -9,7 +9,7 @@ URL:            http://www.freeipa.org
 Source0:        %{name}-%{version}.tgz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
-Requires: python python-ldap python-krbV ipa-python cyrus-sasl-gssapi
+Requires: python python-ldap python-gssapi ipa-python cyrus-sasl-gssapi
 
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
 
diff --git a/ipa-client/ipa-install/ipa-client-automount b/ipa-client/ipa-install/ipa-client-automount
index 0739a2e6b67f44b795bd4990db22fa33bd9f108d..6aa85adf272cc7db1eeee13a60f594ded974403d 100755
--- a/ipa-client/ipa-install/ipa-client-automount
+++ b/ipa-client/ipa-install/ipa-client-automount
@@ -26,7 +26,7 @@ import os
 import urlparse
 import time
 import tempfile
-from krbV import Krb5Error
+import gssapi
 
 import SSSDConfig
 
@@ -435,7 +435,7 @@ def main():
             host_princ = str('host/%s@%s' % (api.env.host, api.env.realm))
             ipautil.kinit_keytab(host_princ, paths.KRB5_KEYTAB, ccache_name)
             os.environ['KRB5CCNAME'] = ccache_name
-        except Krb5Error as e:
+        except gssapi.exceptions.GSSError as e:
             sys.exit("Failed to obtain host TGT: %s" % e)
         # Now we have a TGT, connect to IPA
         try:
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index c2131ffb6dd71afa31910f98b0a18a4ff80351d5..9352b0049490163eed72952e3d627f13c6c90ff5 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -31,8 +31,8 @@ try:
     from ConfigParser import RawConfigParser
     from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
     import shutil
-    from krbV import Krb5Error
     import dns
+    import gssapi
 
     import nss.nss as nss
     import SSSDConfig
@@ -2618,7 +2618,7 @@ def install(options, env, fstore, statestore):
                                              ccache_name,
                                              config=krb_name,
                                              attempts=options.kinit_attempts)
-                    except Krb5Error as e:
+                    except gssapi.exceptions.GSSError as e:
                         print_port_conf_info()
                         root_logger.error("Kerberos authentication failed: %s"
                                           % e)
@@ -2698,7 +2698,7 @@ def install(options, env, fstore, statestore):
                                      config=krb_name,
                                      attempts=options.kinit_attempts)
                 env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
-            except Krb5Error as e:
+            except gssapi.exceptions.GSSError as e:
                 print_port_conf_info()
                 root_logger.error("Failed to obtain host TGT: %s" % e)
                 # failure to get ticket makes it impossible to login and bind
@@ -2745,7 +2745,7 @@ def install(options, env, fstore, statestore):
                                  CCACHE_FILE,
                                  attempts=options.kinit_attempts)
             os.environ['KRB5CCNAME'] = CCACHE_FILE
-        except Krb5Error as e:
+        except gssapi.exceptions.GSSError as e:
             root_logger.error("Failed to obtain host TGT: %s" % e)
             return CLIENT_INSTALL_ERROR
     else:
diff --git a/ipalib/krb_utils.py b/ipalib/krb_utils.py
index 19cd0ad79f61b673d6f869f4e62c0ebcfb81885b..db1cffc1e32a2e50fba64897ff1eba005f90fdc3 100644
--- a/ipalib/krb_utils.py
+++ b/ipalib/krb_utils.py
@@ -16,25 +16,22 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import krbV
 import time
 import re
-from ipapython.ipa_log_manager import *
+import gssapi
+
+from ipalib import errors
 
 #-------------------------------------------------------------------------------
 
-# Kerberos constants, should be defined in krbV, but aren't
-KRB5_GC_CACHED = 0x2
-
-# Kerberos error codes, should be defined in krbV, but aren't
-KRB5_CC_NOTFOUND                = -1765328243 # Matching credential not found
-KRB5_FCC_NOFILE                 = -1765328189 # No credentials cache found
-KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = -1765328377 # Server not found in Kerberos database
-KRB5KRB_AP_ERR_TKT_EXPIRED      = -1765328352 # Ticket expired
-KRB5_FCC_PERM                   = -1765328190 # Credentials cache permissions incorrect
-KRB5_CC_FORMAT                  = -1765328185 # Bad format in credentials cache
-KRB5_REALM_CANT_RESOLVE         = -1765328164 # Cannot resolve network address for KDC in requested realm
-
+# Kerberos error codes
+KRB5_CC_NOTFOUND                = 2529639053 # Matching credential not found
+KRB5_FCC_NOFILE                 = 2529639107 # No credentials cache found
+KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = 2529638919 # Server not found in Kerberos database
+KRB5KRB_AP_ERR_TKT_EXPIRED      = 2529638944 # Ticket expired
+KRB5_FCC_PERM                   = 2529639106 # Credentials cache permissions incorrect
+KRB5_CC_FORMAT                  = 2529639111 # Bad format in credentials cache
+KRB5_REALM_CANT_RESOLVE         = 2529639132 # Cannot resolve network address for KDC in requested realm
 
 krb_ticket_expiration_threshold = 60*5 # number of seconds to accmodate clock skew
 krb5_time_fmt = '%m/%d/%y %H:%M:%S'
@@ -136,260 +133,66 @@ def krb5_format_time(timestamp):
     '''
     return time.strftime(krb5_time_fmt, time.localtime(timestamp))
 
-class KRB5_CCache(object):
+def get_credentials(name=None, ccache_name=None):
     '''
-    Kerberos stores a TGT (Ticket Granting Ticket) and the service
-    tickets bound to it in a ccache (credentials cache). ccaches are
-    bound to a Kerberos user principal. This class opens a Kerberos
-    ccache and allows one to manipulate it. Most useful is the
-    extraction of ticket entries (cred's) in the ccache and the
-    ability to examine their attributes.
+    Obtains GSSAPI credentials with given principal name from ccache. When no
+    principal name specified, it retrieves the default one for given
+    credentials cache.
+
+    :parameters:
+      name
+        gssapi.Name object specifying principal or None for the default
+      ccache_name
+        string specifying Kerberos credentials cache name or None for the
+        default
+    :returns:
+      gssapi.Credentials object
     '''
+    store = None
+    if ccache_name:
+        store = {'ccache': ccache_name}
+    try:
+        return gssapi.Credentials(usage='initiate', name=name, store=store)
+    except gssapi.exceptions.GSSError as e:
+        if e.min_code == KRB5_FCC_NOFILE:
+            raise ValueError('"%s", ccache="%s"' % (e.message, ccache_name))
+        raise
+
+def get_principal(ccache_name=None):
+    '''
+    Gets default principal name from given credentials cache.
+
+    :parameters:
+      ccache_name
+        string specifying Kerberos credentials cache name or None for the
+        default
+    :returns:
+      Default principal name as string
+    '''
+    creds = get_credentials(ccache_name=ccache_name)
+    return unicode(creds.name)
 
-    def __init__(self, ccache):
-        '''
-        :parameters:
-          ccache
-            The name of a Kerberos ccache used to hold Kerberos tickets.
-        :returns:
-          `KRB5_CCache` object encapsulting the ccache.
-        '''
-        log_mgr.get_logger(self, True)
-        self.context = None
-        self.scheme = None
-        self.name = None
-        self.ccache = None
-        self.principal = None
-
-        try:
-            self.context = krbV.default_context()
-            self.scheme, self.name = krb5_parse_ccache(ccache)
-            self.ccache = krbV.CCache(name=str(ccache), context=self.context)
-            self.principal = self.ccache.principal()
-        except krbV.Krb5Error as e:
-            error_code = e.args[0]
-            message = e.args[1]
-            if error_code == KRB5_FCC_NOFILE:
-                raise ValueError('"%s", ccache="%s"' % (message, ccache))
-            else:
-                raise e
-
-    def ccache_str(self):
-        '''
-        A Kerberos ccache is identified by a name comprised of a
-        scheme and location component. This function returns that
-        canonical name. See `krb5_parse_ccache()`
-
-        :returns:
-          The name of ccache with it's scheme and location components.
-        '''
-
-        return '%s:%s' % (self.scheme, self.name)
-
-    def __str__(self):
-        return 'cache="%s" principal="%s"' % (self.ccache_str(), self.principal.name)
-
-    def get_credentials(self, principal):
-        '''
-        Given a Kerberos principal return the krbV credentials
-        tuple describing the credential. If the principal does
-        not exist in the ccache a KeyError is raised.
-
-        :parameters:
-          principal
-            The Kerberos principal whose ticket is being retrieved.
-            The principal may be either a string formatted as a
-            Kerberos V5 principal or it may be a `krbV.Principal`
-            object.
-        :returns:
-          A krbV credentials tuple. If the principal is not in the
-          ccache a KeyError is raised.
-
-        '''
-
-        if isinstance(principal, krbV.Principal):
-            krbV_principal = principal
-        else:
-            try:
-                krbV_principal = krbV.Principal(str(principal), self.context)
-            except Exception as e:
-                self.error('could not create krbV principal from "%s", %s', principal, e)
-                raise e
-
-        creds_tuple = (self.principal,
-                       krbV_principal,
-                       (0, None),    # keyblock: (enctype, contents)
-                       (0, 0, 0, 0), # times: (authtime, starttime, endtime, renew_till)
-                       0,0,          # is_skey, ticket_flags
-                       None,         # addrlist
-                       None,         # ticket_data
-                       None,         # second_ticket_data
-                       None)         # adlist
-        try:
-            cred = self.ccache.get_credentials(creds_tuple, KRB5_GC_CACHED)
-        except krbV.Krb5Error as e:
-            error_code = e.args[0]
-            if error_code == KRB5_CC_NOTFOUND:
-                raise KeyError('"%s" credential not found in "%s" ccache' % \
-                               (krbV_principal.name, self.ccache_str()))
-            raise e
-        except Exception as e:
-            raise e
-
-        return cred
-
-    def get_credential_times(self, principal):
-        '''
-        Given a Kerberos principal return the ticket timestamps if the
-        principal's ticket in the ccache is valid.  If the principal
-        does not exist in the ccache a KeyError is raised.
-
-        The return credential time values are Unix timestamps in
-        localtime.
-
-        The returned timestamps are:
-
-        authtime
-          The time when the ticket was issued.
-        starttime
-          The time when the ticket becomes valid.
-        endtime
-          The time when the ticket expires.
-        renew_till
-          The time when the ticket becomes no longer renewable (if renewable).
-
-        :parameters:
-          principal
-            The Kerberos principal whose ticket is being validated.
-            The principal may be either a string formatted as a
-            Kerberos V5 principal or it may be a `krbV.Principal`
-            object.
-        :returns:
-            return authtime, starttime, endtime, renew_till
-        '''
-
-        if isinstance(principal, krbV.Principal):
-            krbV_principal = principal
-        else:
-            try:
-                krbV_principal = krbV.Principal(str(principal), self.context)
-            except Exception as e:
-                self.error('could not create krbV principal from "%s", %s', principal, e)
-                raise e
-
-        try:
-            cred = self.get_credentials(krbV_principal)
-            authtime, starttime, endtime, renew_till = cred[3]
-
-            self.debug('get_credential_times: principal=%s, authtime=%s, starttime=%s, endtime=%s, renew_till=%s',
-                       krbV_principal.name,
-                       krb5_format_time(authtime), krb5_format_time(starttime),
-                       krb5_format_time(endtime), krb5_format_time(renew_till))
-
-            return authtime, starttime, endtime, renew_till
-
-        except KeyError as e:
-            raise e
-        except Exception as e:
-            self.error('get_credential_times failed, principal="%s" error="%s"', krbV_principal.name, e)
-            raise e
-
-    def credential_is_valid(self, principal):
-        '''
-        Given a Kerberos principal return a boolean indicating if the
-        principal's ticket in the ccache is valid. If the ticket is
-        not in the ccache False is returned. If the ticket
-        exists in the ccache it's validity is checked and returned.
-
-        :parameters:
-          principal
-            The Kerberos principal whose ticket is being validated.
-            The principal may be either a string formatted as a
-            Kerberos V5 principal or it may be a `krbV.Principal`
-            object.
-        :returns:
-          True if the principal's ticket exists and is valid. False if
-          the ticket does not exist or if the ticket is not valid.
-        '''
-
-        try:
-            authtime, starttime, endtime, renew_till = self.get_credential_times(principal)
-        except KeyError as e:
-            return False
-        except Exception as e:
-            self.error('credential_is_valid failed, principal="%s" error="%s"', principal, e)
-            raise e
-
-
-        now = time.time()
-        if starttime > now:
-            return False
-        if endtime < now:
-            return False
-        return True
-
-    def valid(self, host, realm):
-        '''
-        Test to see if ldap service ticket or the TGT is valid.
-
-        :parameters:
-          host
-            ldap server
-          realm
-            kerberos realm
-        :returns:
-          True if either the ldap service ticket or the TGT is valid,
-          False otherwise.
-        '''
-
-        try:
-            principal = krb5_format_service_principal_name('HTTP', host, realm)
-            valid = self.credential_is_valid(principal)
-            if valid:
-                return True
-        except KeyError:
-            pass
-
-        try:
-            principal = krb5_format_tgt_principal_name(realm)
-            valid = self.credential_is_valid(principal)
-            return valid
-        except KeyError:
-            return False
-
-    def endtime(self, host, realm):
-        '''
-        Returns the minimum endtime for tickets of interest (ldap service or TGT).
-
-        :parameters:
-          host
-            ldap server
-          realm
-            kerberos realm
-        :returns:
-          UNIX timestamp value.
-        '''
-
-        result = 0
-        try:
-            principal = krb5_format_service_principal_name('HTTP', host, realm)
-            authtime, starttime, endtime, renew_till = self.get_credential_times(principal)
-            if result:
-                result = min(result, endtime)
-            else:
-                result = endtime
-        except KeyError:
-            pass
-
-        try:
-            principal = krb5_format_tgt_principal_name(realm)
-            authtime, starttime, endtime, renew_till = self.get_credential_times(principal)
-            if result:
-                result = min(result, endtime)
-            else:
-                result = endtime
-        except KeyError:
-            pass
+def get_credentials_if_valid(name=None, ccache_name=None):
+    '''
+    Obtains GSSAPI credentials with principal name from ccache. When no
+    principal name specified, it retrieves the default one for given
+    credentials cache. When the credentials cannot be retrieved or aren't valid
+    it returns None.
+
+    :parameters:
+      name
+        gssapi.Name object specifying principal or None for the default
+      ccache_name
+        string specifying Kerberos credentials cache name or None for the
+        default
+    :returns:
+      gssapi.Credentials object or None if valid credentials weren't found
+    '''
 
-        self.debug('KRB5_CCache %s endtime=%s (%s)', self.ccache_str(), result, krb5_format_time(result))
-        return result
+    try:
+        creds = get_credentials(name=name, ccache_name=ccache_name)
+        if creds.lifetime > 0:
+            return creds
+        return None
+    except gssapi.exceptions.ExpiredCredentialsError:
+        return None
diff --git a/ipalib/plugins/kerberos.py b/ipalib/plugins/kerberos.py
deleted file mode 100644
index 3ed6d76719af46689cc3a0f6890ec243f9c685d3..0000000000000000000000000000000000000000
--- a/ipalib/plugins/kerberos.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Authors:
-#   Jason Gerard DeRose <jder...@redhat.com>
-#
-# Copyright (C) 2008  Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Backend plugin for Kerberos.
-
-This wraps the python-kerberos and python-krbV bindings.
-"""
-
-import sys
-from ipalib import api
-from ipalib.backend import Backend
-from ipalib.plugable import Registry
-import krbV
-
-register = Registry()
-
-ENCODING = 'UTF-8'
-
-
-@register()
-class krb(Backend):
-    """
-    Kerberos backend plugin.
-
-    This wraps the `krbV` bindings (and will eventually wrap the `kerberos`
-    bindings also).  Importantly, this plugin does correct Unicode
-    encoding/decoding of values going-to/coming-from the bindings.
-    """
-
-    def __default_ccache(self):
-        """
-        Return the ``krbV.CCache`` for the default credential cache.
-        """
-        return krbV.default_context().default_ccache()
-
-    def __default_principal(self):
-        """
-        Return the ``krb5.Principal`` for the default credential cache.
-        """
-        return self.__default_ccache().principal()
-
-    def __get_ccache(self, ccname):
-        """
-        Return the ``krbV.CCache`` for the ``ccname`` credential ccache.
-        """
-        return krbV.CCache(ccname)
-
-    def __get_principal(self, ccname):
-        """
-        Return the ``krb5.Principal`` for the ``ccname`` credential ccache.
-        """
-        return self.__get_ccache(ccname).principal()
-
-    def default_ccname(self):
-        """
-        Return the default ccache file name (schema+name).
-
-        This will return something like 'FILE:/tmp/krb5cc_500'.
-
-        This cannot return anything meaningful if used in the server as a
-        request is processed.
-        """
-        default_ccache = self.__default_ccache()
-        ccname = "%(type)s:%(name)s" % dict(type=default_ccache.type,
-                                            name=default_ccache.name)
-        return ccname
-
-    def default_principal(self):
-        """
-        Return the principal name in default credential cache.
-
-        This will return something like 'ad...@example.com'.  If no credential
-        cache exists for the invoking user, None is returned.
-
-        This cannot return anything meaningful if used in the server as a
-        request is processed.
-        """
-        return self.__default_principal().name.decode(ENCODING)
-
-    def default_realm(self):
-        """
-        Return the realm from the default credential cache.
-
-        This will return something like 'EXAMPLE.COM'.  If no credential cache
-        exists for the invoking user, None is returned.
-
-        This cannot return anything meaningful if used in the server as a
-        request is processed.
-        """
-        return krbV.default_context().default_realm.decode(ENCODING)
-
-    def get_principal(self, ccname):
-        """
-        Return the principal from credential cache file at ``ccname``.
-
-        This will return something like 'ad...@example.com'.
-        """
-        return self.__get_principal(ccname).name.decode(ENCODING)
-
-    def get_realm(self, ccname):
-        """
-        Return the realm from credential cache file at ``ccname``.
-
-        This will return something like 'EXAMPLE.COM'.
-        """
-        return self.__get_principal(ccname).realm.decode(ENCODING)
-
-
diff --git a/ipalib/plugins/passwd.py b/ipalib/plugins/passwd.py
index f5fc14d510ea7eea1e16435fe11d982d4ca49d79..a4f791c1bdf4b6f695b3a79f00a54c084f423229 100644
--- a/ipalib/plugins/passwd.py
+++ b/ipalib/plugins/passwd.py
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipalib import api, errors, util
+from ipalib import api, errors, krb_utils
 from ipalib import Command
 from ipalib import Str, Password
 from ipalib import _
@@ -58,7 +58,7 @@ def get_current_password(principal):
     current password is prompted for, otherwise return a fixed value to
     be ignored later.
     """
-    current_principal = util.get_current_principal()
+    current_principal = krb_utils.get_principal()
     if current_principal == normalize_principal(principal):
         return None
     else:
@@ -74,7 +74,7 @@ class passwd(Command):
             label=_('User name'),
             primary_key=True,
             autofill=True,
-            default_from=lambda: util.get_current_principal(),
+            default_from=lambda: krb_utils.get_principal(),
             normalizer=lambda value: normalize_principal(value),
         ),
         Password('password',
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index 83dc085b5aadb4e2878e29d17449f0808cc7a9c2..6c9a4b9cb4823bca94ecc9bbd98c40454c6b8cb1 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -34,7 +34,6 @@ from cryptography.hazmat.primitives.serialization import load_pem_public_key,\
     load_pem_private_key
 
 import nss.nss as nss
-import krbV
 
 from ipalib.frontend import Command, Object, Local
 from ipalib import api, errors
@@ -614,7 +613,7 @@ class vault_add(PKQuery, Local):
         else:
             backend = self.api.Backend.rpcclient
         if not backend.isconnected():
-            backend.connect(ccache=krbV.default_context().default_ccache())
+            backend.connect()
 
         if vault_type == u'standard':
 
@@ -1034,7 +1033,7 @@ class vault_archive(PKQuery, Local):
         else:
             backend = self.api.Backend.rpcclient
         if not backend.isconnected():
-            backend.connect(ccache=krbV.default_context().default_ccache())
+            backend.connect()
 
         # retrieve vault info
         vault = self.api.Command.vault_show(*args, **options)['result']
@@ -1299,7 +1298,7 @@ class vault_retrieve(PKQuery, Local):
         else:
             backend = self.api.Backend.rpcclient
         if not backend.isconnected():
-            backend.connect(ccache=krbV.default_context().default_ccache())
+            backend.connect()
 
         # retrieve vault info
         vault = self.api.Command.vault_show(*args, **options)['result']
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 04b8d01d9827d0c1c20befe34da36da63855edcd..9d0fc8f7bc5e2deeff809526b8cb12efe792d4c4 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -55,7 +55,6 @@ from ipalib.errors import (public_errors, UnknownError, NetworkError,
     KerberosError, XMLRPCMarshallError, JSONError, ConversionError)
 from ipalib import errors, capabilities
 from ipalib.request import context, Connection
-from ipalib.util import get_current_principal
 from ipapython.ipa_log_manager import root_logger
 from ipapython import ipautil
 from ipapython import kernel_keyring
@@ -66,7 +65,8 @@ from ipalib.text import _
 import ipapython.nsslib
 from ipapython.nsslib import NSSHTTPS, NSSConnection
 from ipalib.krb_utils import KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, KRB5KRB_AP_ERR_TKT_EXPIRED, \
-                             KRB5_FCC_PERM, KRB5_FCC_NOFILE, KRB5_CC_FORMAT, KRB5_REALM_CANT_RESOLVE
+                             KRB5_FCC_PERM, KRB5_FCC_NOFILE, KRB5_CC_FORMAT, \
+                             KRB5_REALM_CANT_RESOLVE, get_principal
 from ipapython.dn import DN
 from ipalib.capabilities import VERSION_WITHOUT_CAPABILITIES
 from ipalib import api
@@ -518,10 +518,7 @@ class KerbTransport(SSLTransport):
         self._sec_context = None
 
     def _handle_exception(self, e, service=None):
-        # kerberos library coerced error codes to signed, gssapi uses unsigned
         minor = e.min_code
-        if minor & (1 << 31):
-            minor -= 1 << 32
         if minor == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
             raise errors.ServiceError(service=service)
         elif minor == KRB5_FCC_NOFILE:
@@ -835,7 +832,7 @@ class RPCClient(Connectible):
                           delegate=False, nss_dir=None):
         try:
             rpc_uri = self.env[self.env_rpc_uri_key]
-            principal = get_current_principal()
+            principal = get_principal()
             setattr(context, 'principal', principal)
             # We have a session cookie, try using the session URI to see if it
             # is still valid
diff --git a/ipalib/util.py b/ipalib/util.py
index 7baec85d6a660db5c217b212890a99897bb26401..f016ab7c0fdc0257f9451c746f5bf7f3d7f42bbf 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -61,18 +61,6 @@ def json_serialize(obj):
         return ''
     return json_serialize(obj.__json__())
 
-def get_current_principal():
-    try:
-        import gssapi
-        cred = gssapi.Credentials(usage='initiate')
-        return unicode(cred.name)
-    except ImportError:
-        raise RuntimeError('python-gssapi is not available.')
-    except gssapi.exceptions.GSSError:
-        #TODO: do a kinit?
-        raise errors.CCacheError()
-
-
 def validate_host_dns(log, fqdn):
     """
     See if the hostname has a DNS A/AAAA record.
diff --git a/ipapython/config.py b/ipapython/config.py
index 8b6b5ac93e16578e6b512e085e104041906dd74a..d586d66d67958462b61152b61272b9a0aa8cf0d7 100644
--- a/ipapython/config.py
+++ b/ipapython/config.py
@@ -176,17 +176,6 @@ def __parse_config(discover_server = True):
 def __discover_config(discover_server = True):
     servers = []
     try:
-        if not config.default_realm:
-            try:
-                # only import krbV when we need it
-                import krbV
-                krbctx = krbV.default_context()
-                config.default_realm = krbctx.default_realm
-            except ImportError:
-                pass
-            if not config.default_realm:
-                return False
-
         if not config.default_domain:
             # try once with REALM -> domain
             domain = str(config.default_realm).lower()
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index c3ffb1d5c6f8b58e0cbf7a12a59b956322c407c9..d959bb369d946217acd080e78483cc9013dda4c7 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -34,7 +34,7 @@ import xmlrpclib
 import datetime
 import netaddr
 import time
-import krbV
+import gssapi
 import pwd
 import grp
 from dns import resolver, rdatatype
@@ -54,6 +54,11 @@ GEN_PWD_LEN = 12
 
 IPA_BASEDN_INFO = 'ipa v2.0'
 
+# Having this in krb_utils would cause circular import
+KRB5_KDC_UNREACH = 2529639068 # Cannot contact any KDC for requested realm
+KRB5KDC_ERR_SVC_UNAVAILABLE = 2529638941 # A service is not available that is
+                                         # required to process the request
+
 try:
     from subprocess import CalledProcessError
 except ImportError:
@@ -1206,8 +1211,8 @@ def kinit_keytab(principal, keytab, ccache_name, config=None, attempts=1):
     The optional parameter 'attempts' specifies how many times the credential
     initialization should be attempted in case of non-responsive KDC.
     """
-    errors_to_retry = {krbV.KRB5KDC_ERR_SVC_UNAVAILABLE,
-                       krbV.KRB5_KDC_UNREACH}
+    errors_to_retry = {KRB5KDC_ERR_SVC_UNAVAILABLE,
+                       KRB5_KDC_UNREACH}
     root_logger.debug("Initializing principal %s using keytab %s"
                       % (principal, keytab))
     root_logger.debug("using ccache %s" % ccache_name)
@@ -1218,18 +1223,15 @@ def kinit_keytab(principal, keytab, ccache_name, config=None, attempts=1):
         else:
             os.environ.pop('KRB5_CONFIG', None)
         try:
-            krbcontext = krbV.default_context()
-            ktab = krbV.Keytab(name=keytab, context=krbcontext)
-            princ = krbV.Principal(name=principal, context=krbcontext)
-            ccache = krbV.CCache(name=ccache_name, context=krbcontext,
-                                 primary_principal=princ)
-            ccache.init(princ)
-            ccache.init_creds_keytab(keytab=ktab, principal=princ)
+            name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
+            store = {'ccache': ccache_name,
+                     'client_keytab': keytab}
+            cred = gssapi.Credentials(name=name, store=store, usage='initiate')
             root_logger.debug("Attempt %d/%d: success"
                               % (attempt, attempts))
-            return
-        except krbV.Krb5Error as e:
-            if e.args[0] not in errors_to_retry:
+            return cred
+        except gssapi.exceptions.GSSError as e:
+            if e.min_code not in errors_to_retry:
                 raise
             root_logger.debug("Attempt %d/%d: failed: %s"
                               % (attempt, attempts, e))
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index 34a931d1a591e11e30c83638e16d6b4e18650547..c991cafa12c2dc9f1726532b78d58306602cb92c 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -23,7 +23,7 @@ from optparse import OptionGroup
 import base64
 from nss import nss
 from nss.error import NSPRError
-import krbV
+import gssapi
 
 from ipapython import admintool, certmonger, ipautil
 from ipapython.dn import DN
@@ -126,9 +126,8 @@ class CACertManage(admintool.AdminTool):
         password = self.options.password
         if not password:
             try:
-                ccache = krbV.default_context().default_ccache()
-                conn.connect(ccache=ccache)
-            except (krbV.Krb5Error, errors.ACIError):
+                conn.connect()
+            except (gssapi.exceptions.GSSError, errors.ACIError):
                 pass
             else:
                 return conn
diff --git a/ipaserver/install/ipa_ldap_updater.py b/ipaserver/install/ipa_ldap_updater.py
index 2c4f28af4899c4394d097428165c4e5d0ee7d184..8321c20a31d8acdf2e1e050dc0ff0ef69f76dd94 100644
--- a/ipaserver/install/ipa_ldap_updater.py
+++ b/ipaserver/install/ipa_ldap_updater.py
@@ -26,8 +26,6 @@
 import os
 import sys
 
-import krbV
-
 from ipalib import api
 from ipapython import ipautil, admintool
 from ipaplatform.paths import paths
@@ -100,7 +98,7 @@ class LDAPUpdater_Upgrade(LDAPUpdater):
         super(LDAPUpdater_Upgrade, self).run()
         options = self.options
 
-        realm = krbV.default_context().default_realm
+        realm = api.env.realm
         upgrade = IPAUpgrade(realm, self.files,
                              schema_files=options.schema_files)
 
diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
index 386ca4273c413d9f6a121956d0db3f0c44fe5c24..ae89f7e07fc823005b4970ae20314a8259939b8e 100644
--- a/ipaserver/install/ipa_otptoken_import.py
+++ b/ipaserver/install/ipa_otptoken_import.py
@@ -30,7 +30,7 @@ from lxml import etree
 import dateutil.parser
 import dateutil.tz
 import nss.nss as nss
-import krbV
+import gssapi
 
 from ipapython import admintool
 from ipalib import api, errors
@@ -509,9 +509,8 @@ class OTPTokenImport(admintool.AdminTool):
 
         conn = ldap2(api)
         try:
-            ccache = krbV.default_context().default_ccache()
-            conn.connect(ccache=ccache)
-        except (krbV.Krb5Error, errors.ACIError):
+            conn.connect()
+        except (gssapi.exceptions.GSSError, errors.ACIError):
             raise admintool.ScriptError("Unable to connect to LDAP! Did you kinit?")
 
         try:
diff --git a/ipaserver/install/ipa_winsync_migrate.py b/ipaserver/install/ipa_winsync_migrate.py
index 097b8c806cfb4df2ea98db86da7b34d99176a9c4..75d1dbe315a8a8aa4f19497912f28108730b9caa 100644
--- a/ipaserver/install/ipa_winsync_migrate.py
+++ b/ipaserver/install/ipa_winsync_migrate.py
@@ -17,7 +17,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import krbV
+import gssapi
 import sys
 
 from ipalib import api
@@ -321,12 +321,10 @@ class WinsyncMigrate(admintool.AdminTool):
 
         # Setup LDAP connection
         try:
-            ctx = krbV.default_context()
-            ccache = ctx.default_ccache()
-            api.Backend.ldap2.connect(ccache)
+            api.Backend.ldap2.connect()
             cls.ldap = api.Backend.ldap2
-        except krbV.Krb5Error as e:
-            sys.exit("Must have Kerberos credentials to migrate Winsync users.")
+        except gssapi.exceptions.GSSError as e:
+            sys.exit("Must have Kerberos credentials to migrate Winsync users. Error: %s" % e)
         except errors.ACIError as e:
             sys.exit("Outdated Kerberos credentials. Use kdestroy and kinit to update your ticket.")
         except errors.DatabaseError as e:
diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index 1f3aca542b668545b58a988c59be01c410862e1c..0444327aae619ae35e1eaeb67f7835a9f4282c6c 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -32,7 +32,6 @@ import pwd
 import fnmatch
 import re
 
-import krbV
 import ldap
 
 from ipaserver.install import installutils
@@ -272,13 +271,8 @@ class LDAPUpdate:
         if sub_dict.get("REALM"):
             self.realm = sub_dict["REALM"]
         else:
-            krbctx = krbV.default_context()
-            try:
-                self.realm = krbctx.default_realm
-                suffix = ipautil.realm_to_suffix(self.realm)
-            except krbV.Krb5Error:
-                self.realm = None
-                suffix = None
+            self.realm = api.env.realm
+            suffix = ipautil.realm_to_suffix(self.realm) if self.realm else None
 
         if suffix is not None:
             assert isinstance(suffix, DN)
diff --git a/ipaserver/install/schemaupdate.py b/ipaserver/install/schemaupdate.py
index 03edb63075e893ca9887559de6470b9f94c40cf9..f98d0e949f59f19e0b51deeac0717e5c87ff92cf 100644
--- a/ipaserver/install/schemaupdate.py
+++ b/ipaserver/install/schemaupdate.py
@@ -20,9 +20,9 @@
 import pprint
 
 import ldap.schema
-import krbV
 
 import ipapython.version
+from ipalib import api
 from ipapython.ipa_log_manager import log_mgr
 from ipapython.dn import DN
 from ipaserver.install.ldapupdate import connect
@@ -106,7 +106,7 @@ def update_schema(schema_files, ldapi=False, dm_password=None,):
     SCHEMA_ELEMENT_CLASSES_KEYS = [x[0] for x in SCHEMA_ELEMENT_CLASSES]
 
     conn = connect(ldapi=ldapi, dm_password=dm_password,
-                   realm=krbV.default_context().default_realm,
+                   realm=api.env.realm,
                    fqdn=installutils.get_fqdn())
 
     old_schema = conn.schema
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index f8a4ff28242dc51c5a9496859d464bbe789a3ce3..cb92250e40bc3da4b0b588fee431e2f37bf5d05d 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -9,7 +9,6 @@ import pwd
 import fileinput
 import ConfigParser
 import sys
-import krbV
 
 from ipalib import api
 import SSSDConfig
@@ -1567,7 +1566,7 @@ def upgrade_check(options):
 
 
 def upgrade():
-    realm = krbV.default_context().default_realm
+    realm = api.env.realm
     schema_files = [os.path.join(ipautil.SHARE_DIR, f) for f
                     in dsinstance.ALL_SCHEMA_FILES]
     data_upgrade = IPAUpgrade(realm, schema_files=schema_files)
diff --git a/ipaserver/plugins/join.py b/ipaserver/plugins/join.py
index 3b668053c5d275c53da0c897fb4f82442a725564..7342117e78e3f82c78e0ef0aac8eea6a0b20fde9 100644
--- a/ipaserver/plugins/join.py
+++ b/ipaserver/plugins/join.py
@@ -21,8 +21,6 @@
 Joining an IPA domain
 """
 
-import krbV
-
 from ipalib import api
 from ipalib import Command, Str
 from ipalib import errors
@@ -30,15 +28,6 @@ from ipalib import _
 from ipaserver.install import installutils
 
 
-def get_realm():
-    """
-    Returns the default kerberos realm configured for this server.
-    """
-    krbctx = krbV.default_context()
-
-    return unicode(krbctx.default_realm)
-
-
 def validate_host(ugettext, cn):
     """
     Require at least one dot in the hostname (to support localhost.localdomain)
@@ -66,7 +55,7 @@ class join(Command):
     takes_options = (
         Str('realm',
             doc=_("The IPA realm"),
-            default_from=lambda: get_realm(),
+            default_from=lambda: api.env.realm,
             autofill=True,
         ),
         Str('nshardwareplatform?',
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index 68feee4f09eb12e50867dfbe3c482a359838aa82..acaf45fddb7ba54a42af15270534e1cde81fc2bd 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -30,11 +30,12 @@ Backend plugin for LDAP.
 import os
 import pwd
 
-import krbV
 import ldap as _ldap
 
+from ipalib import krb_utils
 from ipapython.dn import DN
-from ipapython.ipaldap import SASL_GSSAPI, LDAPClient
+from ipapython.ipaldap import (LDAPClient, AUTOBIND_AUTO, AUTOBIND_ENABLED,
+                               AUTOBIND_DISABLED)
 
 
 try:
@@ -88,13 +89,14 @@ class ldap2(CrudBackend, LDAPClient):
 
     def create_connection(self, ccache=None, bind_dn=None, bind_pw='',
             tls_cacertfile=None, tls_certfile=None, tls_keyfile=None,
-            debug_level=0, autobind=False, serverctrls=None, clientctrls=None):
+            debug_level=0, autobind=AUTOBIND_AUTO, serverctrls=None,
+            clientctrls=None):
         """
         Connect to LDAP server.
 
         Keyword arguments:
         ldapuri -- the LDAP server to connect to
-        ccache -- Kerberos V5 ccache object or name
+        ccache -- Kerberos ccache name
         bind_dn -- dn used to bind to the server
         bind_pw -- password used to bind to the server
         debug_level -- LDAP debug level option
@@ -122,8 +124,6 @@ class ldap2(CrudBackend, LDAPClient):
         conn = self._conn
 
         with self.error_handler():
-            if self.ldap_uri.startswith('ldapi://') and ccache:
-                conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host)
             minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN)
             maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX)
             # Always connect with at least an SSF of 56, confidentiality
@@ -134,33 +134,37 @@ class ldap2(CrudBackend, LDAPClient):
                 if maxssf < minssf:
                     conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf)
 
-        if ccache is not None:
-            if isinstance(ccache, krbV.CCache):
-                principal = ccache.principal().name
-                # Get a fully qualified CCACHE name (schema+name)
-                # As we do not use the krbV.CCache object later,
-                # we can safely overwrite it
-                ccache = "%(type)s:%(name)s" % dict(type=ccache.type,
-                                                    name=ccache.name)
-            else:
-                principal = krbV.CCache(name=ccache,
-                    context=krbV.default_context()).principal().name
+        ldapi = self.ldap_uri.startswith('ldapi://')
 
-            os.environ['KRB5CCNAME'] = ccache
-            self.gssapi_bind(server_controls=serverctrls,
+        if bind_pw:
+            self.simple_bind(bind_dn, bind_pw,
+                             server_controls=serverctrls,
                              client_controls=clientctrls)
-            setattr(context, 'principal', principal)
-        else:
-            # no kerberos ccache, use simple bind or external sasl
-            if autobind:
-                pent = pwd.getpwuid(os.geteuid())
-                self.external_bind(pent.pw_name,
+        elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi:
+            try:
+                pw_name = pwd.getpwuid(os.geteuid()).pw_name
+                self.external_bind(pw_name,
                                    server_controls=serverctrls,
                                    client_controls=clientctrls)
+            except errors.NotFound:
+                if autobind == AUTOBIND_ENABLED:
+                    # autobind was required and failed, raise
+                    # exception that it failed
+                    raise
+        else:
+            if ldapi:
+                with self.error_handler():
+                    conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host)
+            if ccache is None:
+                os.environ.pop('KRB5CCNAME', None)
             else:
-                self.simple_bind(bind_dn, bind_pw,
-                                 server_controls=serverctrls,
-                                 client_controls=clientctrls)
+                os.environ['KRB5CCNAME'] = ccache
+
+            principal = krb_utils.get_principal(ccache_name=ccache)
+
+            self.gssapi_bind(server_controls=serverctrls,
+                             client_controls=clientctrls)
+            setattr(context, 'principal', principal)
 
         return conn
 
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index 8fa09734489d3724f4e345abbf8ece1de469f98c..df75d98bbe871ef8b9f3b3ddf6c0417889b66f32 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -30,7 +30,8 @@ import datetime
 import urlparse
 import json
 import traceback
-from krbV import Krb5Error
+import gssapi
+import time
 
 import ldap.controls
 from pyasn1.type import univ, namedtype
@@ -54,8 +55,8 @@ from ipalib.session import (
     default_max_session_duration, krbccache_dir, krbccache_prefix)
 from ipalib.backend import Backend
 from ipalib.krb_utils import (
-    KRB5_CCache, krb_ticket_expiration_threshold, krb5_format_principal_name,
-    krb5_format_service_principal_name)
+    krb_ticket_expiration_threshold, krb5_format_principal_name,
+    krb5_format_service_principal_name, get_credentials, get_credentials_if_valid)
 from ipapython import ipautil
 from ipaplatform.paths import paths
 from ipapython.version import VERSION
@@ -593,8 +594,8 @@ class KerberosSession(object):
         session_data['ccache_data'] = load_ccache_data(ccache_name)
 
         # Set when the session will expire
-        cc = KRB5_CCache(ccache_name)
-        endtime = cc.endtime(self.api.env.host, self.api.env.realm)
+        creds = get_credentials(ccache_name=ccache_name)
+        endtime = creds.lifetime + time.time()
         self.update_session_expiration(session_data, endtime)
 
         # Store the session data now that it's been updated with the ccache
@@ -789,15 +790,15 @@ class jsonserver_session(jsonserver, KerberosSession):
         ipa_ccache_name = bind_ipa_ccache(ccache_data)
 
         # Redirect to login if Kerberos credentials are expired
-        cc = KRB5_CCache(ipa_ccache_name)
-        if not cc.valid(self.api.env.host, self.api.env.realm):
+        creds = get_credentials_if_valid(ccache_name=ipa_ccache_name)
+        if not creds:
             self.debug('ccache expired, deleting session, need login')
             # The request is finished with the ccache, destroy it.
             release_ipa_ccache(ipa_ccache_name)
             return self.need_login(start_response)
 
         # Update the session expiration based on the Kerberos expiration
-        endtime = cc.endtime(self.api.env.host, self.api.env.realm)
+        endtime = creds.lifetime + time.time()
         self.update_session_expiration(session_data, endtime)
 
         # Store the session data in the per-thread context
@@ -962,7 +963,7 @@ class login_password(Backend, KerberosSession, HTTP_Status):
 
         try:
             ipautil.kinit_keytab(armor_principal, paths.IPA_KEYTAB, armor_path)
-        except Krb5Error as e:
+        except gssapi.exceptions.GSSError as e:
             raise CCacheError(str(e))
 
         # Format the user as a kerberos principal
@@ -1229,15 +1230,15 @@ class xmlserver_session(xmlserver, KerberosSession):
         ipa_ccache_name = bind_ipa_ccache(ccache_data)
 
         # Redirect to /ipa/xml if Kerberos credentials are expired
-        cc = KRB5_CCache(ipa_ccache_name)
-        if not cc.valid(self.api.env.host, self.api.env.realm):
+        creds = get_credentials_if_valid(ccache_name=ipa_ccache_name)
+        if not creds:
             self.debug('xmlserver_session.__call_: ccache expired, deleting session, need login')
             # The request is finished with the ccache, destroy it.
             release_ipa_ccache(ipa_ccache_name)
             return self.need_login(start_response)
 
         # Update the session expiration based on the Kerberos expiration
-        endtime = cc.endtime(self.api.env.host, self.api.env.realm)
+        endtime = creds.lifetime + time.time()
         self.update_session_expiration(session_data, endtime)
 
         # Store the session data in the per-thread context
diff --git a/ipatests/test_cmdline/cmdline.py b/ipatests/test_cmdline/cmdline.py
index 0ae8cc079bb6ee89bd791fabdbaeb12252c3ca11..e41b027a3a54d2b51fe60c3a5cfa74ab18cf5730 100644
--- a/ipatests/test_cmdline/cmdline.py
+++ b/ipatests/test_cmdline/cmdline.py
@@ -22,7 +22,6 @@ Base class for all cmdline tests
 """
 
 import nose
-import krbV
 import distutils.spawn
 import os
 
@@ -33,11 +32,9 @@ from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
 from ipaserver.plugins.ldap2 import ldap2
 
 # See if our LDAP server is up and we can talk to it over GSSAPI
-ccache = krbV.default_context().default_ccache()
-
 try:
     conn = ldap2(api)
-    conn.connect(ccache=ccache)
+    conn.connect()
     conn.disconnect()
     server_available = True
 except errors.DatabaseError:
diff --git a/ipatests/test_cmdline/test_ipagetkeytab.py b/ipatests/test_cmdline/test_ipagetkeytab.py
index 2b99c268e782cefc259b0f78c9a2c83af361d38b..d9ab0daaa8e46c70bda8a758a1bb8d00760747d9 100644
--- a/ipatests/test_cmdline/test_ipagetkeytab.py
+++ b/ipatests/test_cmdline/test_ipagetkeytab.py
@@ -26,10 +26,10 @@ from cmdline import cmdline_test
 from ipalib import api
 from ipalib import errors
 import tempfile
-from ipapython import ipautil
+from ipapython import ipautil, ipaldap
 import nose
 import tempfile
-import krbV
+import gssapi
 from ipaserver.plugins.ldap2 import ldap2
 from ipapython.dn import DN
 
@@ -37,21 +37,18 @@ def use_keytab(principal, keytab):
     try:
         tmpdir = tempfile.mkdtemp(prefix = "tmp-")
         ccache_file = 'FILE:%s/ccache' % tmpdir
-        krbcontext = krbV.default_context()
-        principal = str(principal)
-        keytab = krbV.Keytab(name=keytab, context=krbcontext)
-        principal = krbV.Principal(name=principal, context=krbcontext)
+        name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
+        store = {'ccache': ccache_file,
+                 'client_keytab': keytab}
         os.environ['KRB5CCNAME'] = ccache_file
-        ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=principal)
-        ccache.init(principal)
-        ccache.init_creds_keytab(keytab=keytab, principal=principal)
+        gssapi.Credentials(name=name, usage='initiate', store=store)
         conn = ldap2(api)
-        conn.connect(ccache=ccache)
+        conn.connect(autobind=ipaldap.AUTOBIND_DISABLED)
         conn.disconnect()
-    except krbV.Krb5Error as e:
-        raise StandardError('Unable to bind to LDAP. Error initializing principal %s in %s: %s' % (principal.name, keytab, str(e)))
+    except gssapi.exceptions.GSSError as e:
+        raise StandardError('Unable to bind to LDAP. Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
     finally:
-        del os.environ['KRB5CCNAME']
+        os.environ.pop('KRB5CCNAME', None)
         if tmpdir:
             shutil.rmtree(tmpdir)
 
diff --git a/ipatests/test_xmlrpc/test_dns_plugin.py b/ipatests/test_xmlrpc/test_dns_plugin.py
index caad00de327f701224bc1ba957d28ff3e64017c3..f0b8edaa14bdc05e103d2fd332033b97b64169b1 100644
--- a/ipatests/test_xmlrpc/test_dns_plugin.py
+++ b/ipatests/test_xmlrpc/test_dns_plugin.py
@@ -34,7 +34,6 @@ try:
 except ImportError:
     have_ldap2 = False
 else:
-    import krbV
     have_ldap2 = True
 
 _dns_zone_record = DNSName(u'@')
@@ -402,7 +401,7 @@ def _get_nameservers_ldap(conn):
 
 def get_nameservers():
         ldap = ldap2(api)
-        ldap.connect(ccache=krbV.default_context().default_ccache())
+        ldap.connect()
         nameservers = [normalize_zone(x) for x in _get_nameservers_ldap(ldap)]
         return nameservers
 
diff --git a/ipatests/test_xmlrpc/test_netgroup_plugin.py b/ipatests/test_xmlrpc/test_netgroup_plugin.py
index afe0c617d2245c727e944ae8bd2cebd30b92d042..10553c21f060db15f9a04bd98b47d7c0cad14c00 100644
--- a/ipatests/test_xmlrpc/test_netgroup_plugin.py
+++ b/ipatests/test_xmlrpc/test_netgroup_plugin.py
@@ -22,7 +22,6 @@ Test the `ipalib/plugins/netgroup.py` module.
 """
 
 import nose
-import krbV
 
 from ipalib import api
 from ipalib import errors
@@ -36,9 +35,6 @@ from ipatests.test_xmlrpc.test_user_plugin import get_user_result
 # Global so we can save the value between tests
 netgroup_dn = None
 
-# See if our LDAP server is up and we can talk to it over GSSAPI
-ccache = krbV.default_context().default_ccache().name
-
 netgroup1 = u'netgroup1'
 netgroup2 = u'netgroup2'
 netgroup_single = u'a'
@@ -1298,7 +1294,7 @@ class test_netgroup(Declarative):
 #        # Do an LDAP query to the compat area and verify that the entry
 #        # is correct
 #        conn = ldap2(api)
-#        conn.connect(ccache=ccache)
+#        conn.connect()
 #        try:
 #            entries = conn.find_entries('cn=%s' % self.ng_cn,
 #                      base_dn='cn=ng,cn=compat,%s' % api.env.basedn)
diff --git a/ipatests/test_xmlrpc/test_permission_plugin.py b/ipatests/test_xmlrpc/test_permission_plugin.py
index 2d1a7d5e7dfb51575b0ce2b391026cf5fcd8ae07..971d0e6cbdeb0063f9df0c2587c4c67875638562 100644
--- a/ipatests/test_xmlrpc/test_permission_plugin.py
+++ b/ipatests/test_xmlrpc/test_permission_plugin.py
@@ -37,7 +37,6 @@ try:
 except ImportError:
     have_ldap2 = False
 else:
-    import krbV
     have_ldap2 = True
 
 permission1 = u'testperm'
@@ -3175,7 +3174,7 @@ class test_managed_permissions(Declarative):
     def add_managed_permission(self):
         """Add a managed permission and the corresponding ACI"""
         ldap = ldap2(api)
-        ldap.connect(ccache=krbV.default_context().default_ccache())
+        ldap.connect()
 
         result = api.Command.permission_add(permission1, type=u'user',
                                             ipapermright=u'write',
diff --git a/lite-server.py b/lite-server.py
index 99089b00f9a9cc4c54a227c3aff55c7357ba2428..0e867915f19e16801556b4362e53f330da365f4e 100755
--- a/lite-server.py
+++ b/lite-server.py
@@ -37,13 +37,27 @@ from paste import httpserver
 import paste.gzipper
 from paste.urlmap import URLMap
 from ipalib import api
+from subprocess import check_output, CalledProcessError
+import re
+
+# Ugly hack for test purposes only. GSSAPI has no way to get default ccache
+# name, but we don't need it outside test server
+def get_default_ccache_name():
+    try:
+        out = check_output(['klist'])
+    except CalledProcessError:
+        raise RuntimeError("Default ccache not found. Did you kinit?")
+    match = re.match(r'^Ticket cache:\s*(\S+)', out)
+    if not match:
+        raise RuntimeError("Cannot obtain ccache name")
+    return match.group(1)
 
 
 class KRBCheater(object):
     def __init__(self, app):
         self.app = app
         self.url = app.url
-        self.ccname = api.Backend.krb.default_ccname()
+        self.ccname = get_default_ccache_name()
 
     def __call__(self, environ, start_response):
         environ['KRB5CCNAME'] = self.ccname
diff --git a/make-lint b/make-lint
index 0447985303f485a014fecf7d17d0b1c7eb6137bd..380e8c86d039be0351e2fefa3758194aa2397e12 100755
--- a/make-lint
+++ b/make-lint
@@ -50,7 +50,6 @@ class IPATypeChecker(TypeChecker):
     # 'class or module': ['generated', 'properties']
     ignore = {
         # Python standard library & 3rd party classes
-        'krbV.Principal': ['name'],
         'socket._socketobject': ['sendall'],
         # should be 'subprocess.Popen'
         '.Popen': ['stdin', 'stdout', 'stderr', 'pid', 'returncode', 'poll',
@@ -68,7 +67,6 @@ class IPATypeChecker(TypeChecker):
         'ipalib.base.NameSpace': ['add', 'mod', 'del', 'show', 'find'],
         'ipalib.cli.Collector': ['__options'],
         'ipalib.config.Env': ['*'],
-        'ipalib.krb_utils.KRB5_CCache': LOGGING_ATTRS,
         'ipalib.parameters.Param': ['cli_name', 'cli_short_name', 'label',
             'default', 'doc', 'required', 'multivalue', 'primary_key',
             'normalizer', 'default_from', 'autofill', 'query', 'attribute',
@@ -261,7 +259,7 @@ Errors were found during the static code check.
             for mod in sorted(linter.missing):
                 print >> sys.stderr, "    " + mod
             print >> sys.stderr, """
-Please make sure all of the required and optional (python-krbV, python-rhsm)
+Please make sure all of the required and optional (python-gssapi, python-rhsm)
 python packages are installed.
 """
 
-- 
2.1.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to