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



On 2015-08-19 11:26, Alexander Bokovoy wrote:
On Tue, 18 Aug 2015, Michael Šimáček wrote:
On 2015-08-17 21:10, Robbie Harwood 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

This patch doesn't seem to apply to master.  Can you update it or
indicate what you're patching against?  Thanks!


Attaching patch rebased on top of current master.
My refactoring of com.redhat.idm.trust-fetch-domains went in yesterday
so this patch will not apply anymore. Could you please rebase it?



Rebased on top of current master.

Michael



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.

Michael
From f87e9945923ae283ad806f2e79e6104ca35025ed 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                                   |   7 +-
 install/oddjob/com.redhat.idm.trust-fetch-domains |  82 ++----
 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          |   8 +-
 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, 238 insertions(+), 643 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..ddb108cc1b0cee781b71fcc758eaa0d2d4c6c028 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -68,7 +68,6 @@ BuildRequires:  gettext
 BuildRequires:  python-devel
 BuildRequires:  python-ldap
 BuildRequires:  python-setuptools
-BuildRequires:  python-krbV
 BuildRequires:  python-nss
 BuildRequires:  python-cryptography
 BuildRequires:  python-netaddr
@@ -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.1
 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.1
 Requires: python-dns >= 1.11.1
 Requires: libsss_autofs
 Requires: autofs
@@ -287,7 +286,7 @@ Summary: IPA administrative tools
 Group: System Environment/Base
 Requires: %{name}-python = %{version}-%{release}
 Requires: %{name}-client = %{version}-%{release}
-Requires: python-krbV
+Requires: python-gssapi >= 1.1.1
 Requires: python-ldap
 
 Conflicts: %{alt_name}-admintools
diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
index 6a2171d5f1936fabd00081bbbcea562a0e7041b8..6d04174ddfb03ec43f813622c63d0a87553b6acf 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,18 @@ 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
+try:
+    cred = kinit_keytab(principal, keytab_name, ccache_name)
+    # would raise exception if expired
+    cred.lifetime
+except gssapi.exceptions.ExpiredCredentialsError:
+    # 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 +137,22 @@ 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:
+    try:
+        # The keytab may have stale key material (from older trust-add run)
+        cred = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
+        # would raise exception if expired
+        cred.lifetime
+    except gssapi.exceptions.ExpiredCredentialsError:
+        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..7b2263f324f9527e298f04a2b67d3be95ff44bee 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)
+        # property access would raise exception if expired
+        if creds.lifetime > 0:
+            return creds
+    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..4b5c6c592c1183bcbe4f48729714fed4517322a7 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,11 +321,9 @@ 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:
+        except gssapi.exceptions.GSSError:
             sys.exit("Must have Kerberos credentials to migrate Winsync users.")
         except errors.ACIError as e:
             sys.exit("Outdated Kerberos credentials. Use kdestroy and kinit to update your ticket.")
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