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

Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
Reviewed-By: Simo Sorce <ssorce@redhat.com>
This commit is contained in:
Michael Simacek
2015-07-20 16:04:07 +02:00
committed by Jan Cholasta
parent aebb72e1fb
commit aad73fad60
37 changed files with 249 additions and 649 deletions

View File

@@ -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

View File

@@ -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.partition('@')[0].partition('/')[0])['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']):

View File

@@ -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

View File

@@ -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