ipa-kdb: Change install to use the new ipa-kdb kdc backend

Use ipakdb instead of kldap and change install procedures accordingly
Note that we do not need to store the master key in a keytab as we can
read it off of ldap in our driver.
This commit is contained in:
Simo Sorce 2011-06-08 17:21:23 -04:00
parent 35e15f6c91
commit 195a65d5c2
8 changed files with 60 additions and 166 deletions

View File

@ -13,8 +13,6 @@ app_DATA = \
caJarSigningCert.cfg.template \
default-aci.ldif \
default-hbac.ldif \
default-keytypes.ldif \
default-pwpolicy.ldif \
delegation.ldif \
replica-acis.ldif \
ds-nfiles.ldif \

View File

@ -1,33 +0,0 @@
#kerberos keytypes
dn: cn=$REALM,cn=kerberos,$SUFFIX
changetype: modify
add: krbSupportedEncSaltTypes
krbSupportedEncSaltTypes: aes256-cts:normal
krbSupportedEncSaltTypes: aes256-cts:special
krbSupportedEncSaltTypes: aes128-cts:normal
krbSupportedEncSaltTypes: aes128-cts:special
krbSupportedEncSaltTypes: des3-hmac-sha1:normal
krbSupportedEncSaltTypes: des3-hmac-sha1:special
krbSupportedEncSaltTypes: arcfour-hmac:normal
krbSupportedEncSaltTypes: arcfour-hmac:special
krbSupportedEncSaltTypes: des-hmac-sha1:normal
krbSupportedEncSaltTypes: des-cbc-md5:normal
krbSupportedEncSaltTypes: des-cbc-crc:normal
krbSupportedEncSaltTypes: des-cbc-crc:v4
krbSupportedEncSaltTypes: des-cbc-crc:afs3
-
add: krbMaxTicketLife
krbMaxTicketLife: 86400
-
add: krbMaxRenewableAge
krbMaxRenewableAge: 604800
#kerberos keytypes
dn: cn=$REALM,cn=kerberos,$SUFFIX
changetype: modify
add: krbDefaultEncSaltTypes
krbDefaultEncSaltTypes: aes256-cts:special
krbDefaultEncSaltTypes: aes128-cts:special
krbDefaultEncSaltTypes: des3-hmac-sha1:special
krbDefaultEncSaltTypes: arcfour-hmac:special

View File

@ -1,14 +0,0 @@
dn: cn=global_policy,cn=$REALM,cn=kerberos,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
objectClass: krbPwdPolicy
krbMinPwdLife: 3600
krbPwdMinDiffChars: 0
krbPwdMinLength: 8
krbPwdHistoryLength: 0
krbMaxPwdLife: 7776000
krbPwdMaxFailure: 6
krbPwdFailureCountInterval: 60
krbPwdLockoutDuration: 600

View File

@ -6,7 +6,6 @@
[realms]
$REALM = {
master_key_type = aes256-cts
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal des-cbc-crc:v4 des-cbc-crc:afs3
max_life = 7d
max_renewable_life = 14d
acl_file = /var/kerberos/krb5kdc/kadm5.acl

View File

@ -16,3 +16,42 @@ objectClass: top
cn: kerberos
aci: (targetattr="*")(version 3.0; acl "KDC System Account"; allow (all) userdn= "ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
#Realm base object
dn: cn=$REALM,cn=kerberos,$SUFFIX
changetype: add
cn: $REALM
objectClass: top
objectClass: krbrealmcontainer
objectClass: krbticketpolicyaux
krbSubTrees: $SUFFIX
krbSearchScope: 2
krbSupportedEncSaltTypes: aes256-cts:normal
krbSupportedEncSaltTypes: aes256-cts:special
krbSupportedEncSaltTypes: aes128-cts:normal
krbSupportedEncSaltTypes: aes128-cts:special
krbSupportedEncSaltTypes: des3-hmac-sha1:normal
krbSupportedEncSaltTypes: des3-hmac-sha1:special
krbSupportedEncSaltTypes: arcfour-hmac:normal
krbSupportedEncSaltTypes: arcfour-hmac:special
krbMaxTicketLife: 86400
krbMaxRenewableAge: 604800
krbDefaultEncSaltTypes: aes256-cts:special
krbDefaultEncSaltTypes: aes128-cts:special
krbDefaultEncSaltTypes: des3-hmac-sha1:special
krbDefaultEncSaltTypes: arcfour-hmac:special
# Default password Policy
dn: cn=global_policy,cn=$REALM,cn=kerberos,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
objectClass: krbPwdPolicy
krbMinPwdLife: 3600
krbPwdMinDiffChars: 0
krbPwdMinLength: 8
krbPwdHistoryLength: 0
krbMaxPwdLife: 7776000
krbPwdMaxFailure: 6
krbPwdFailureCountInterval: 60
krbPwdLockoutDuration: 600

View File

@ -31,11 +31,6 @@
[dbmodules]
$REALM = {
db_library = kldap
ldap_servers = ldapi://%2fvar%2frun%2fslapd-$SERVER_ID.socket
ldap_kerberos_container_dn = cn=kerberos,$SUFFIX
ldap_kdc_dn = uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX
ldap_kadmind_dn = uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX
ldap_service_password_file = /var/kerberos/krb5kdc/ldappwd
db_library = ipadb.so
}

View File

@ -388,7 +388,8 @@ def get_directive(filename, directive, separator=' '):
return None
def kadmin(command):
ipautil.run(["kadmin.local", "-q", command])
ipautil.run(["kadmin.local", "-q", command,
"-x", "ipa-setup-override-restrictions"])
def kadmin_addprinc(principal):
kadmin("addprinc -randkey " + principal)

View File

@ -114,7 +114,8 @@ class KrbInstance(service.Service):
host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'ipaservice', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux'])
host_entry.setValues('krbextradata', service_entry.getValues('krbextradata'))
host_entry.setValue('krblastpwdchange', service_entry.getValue('krblastpwdchange'))
host_entry.setValue('krbpasswordexpiration', service_entry.getValue('krbpasswordexpiration'))
if 'krbpasswordexpiration' in service_entry.toDict():
host_entry.setValue('krbpasswordexpiration', service_entry.getValue('krbpasswordexpiration'))
host_entry.setValue('krbprincipalname', service_entry.getValue('krbprincipalname'))
if 'krbticketflags' in service_entry.toDict():
host_entry.setValue('krbticketflags', service_entry.getValue('krbticketflags'))
@ -163,16 +164,14 @@ class KrbInstance(service.Service):
self.step("setting KDC account password", self.__configure_kdc_account_password)
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
self.step("adding kerberos entries to the DS", self.__add_krb_entries)
self.step("adding kerberos container to the directory", self.__add_krb_container)
self.step("configuring KDC", self.__configure_instance)
self.step("initialize kerberos container", self.__init_ipa_kdb)
self.step("adding default ACIs", self.__add_default_acis)
self.step("configuring KDC", self.__create_instance)
self.step("adding default keytypes", self.__add_default_keytypes)
self.step("adding default password policy", self.__add_default_pwpolicy)
self.step("creating a keytab for the directory", self.__create_ds_keytab)
self.step("creating a keytab for the machine", self.__create_host_keytab)
self.step("exporting the kadmin keytab", self.__export_kadmin_changepw_keytab)
self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
self.step("adding the kerberos master key to the directory", self.__add_master_key)
if setup_pkinit:
self.step("creating X509 Certificate for PKINIT", self.__setup_pkinit)
self.step("creating principal for anonymous PKINIT", self.__add_anonymous_pkinit_principal)
@ -201,7 +200,7 @@ class KrbInstance(service.Service):
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
self.step("writing stash file from DS", self.__write_stash_from_ds)
self.step("configuring KDC", self.__create_replica_instance)
self.step("configuring KDC", self.__configure_instance)
self.step("creating a keytab for the directory", self.__create_ds_keytab)
self.step("creating a keytab for the machine", self.__create_host_keytab)
self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
@ -304,21 +303,12 @@ class KrbInstance(service.Service):
logging.critical("failed to add Name Only Sasl mapping")
raise e
def __add_krb_entries(self):
def __add_krb_container(self):
self._ldap_mod("kerberos.ldif", self.sub_dict)
def __add_default_acis(self):
self._ldap_mod("default-aci.ldif", self.sub_dict)
def __add_default_keytypes(self):
self._ldap_mod("default-keytypes.ldif", self.sub_dict)
def __add_default_pwpolicy(self):
self._ldap_mod("default-pwpolicy.ldif", self.sub_dict)
def __create_replica_instance(self):
self.__create_instance(replica=True)
def __template_file(self, path):
template = os.path.join(ipautil.SHARE_DIR, os.path.basename(path) + ".template")
conf = ipautil.template_file(template, self.sub_dict)
@ -327,21 +317,23 @@ class KrbInstance(service.Service):
fd.write(conf)
fd.close()
def __create_instance(self, replica=False):
def __init_ipa_kdb(self):
#populate the directory with the realm structure
args = ["kdb5_util", "create", "-s", "-P", self.master_password,
"-r", self.realm,
"-x", "ipa-setup-override-restrictions"]
try:
ipautil.run(args, nolog=(self.master_password))
except ipautil.CalledProcessError, e:
print "Failed to initialize the realm container"
def __configure_instance(self):
self.__template_file("/var/kerberos/krb5kdc/kdc.conf")
self.__template_file("/etc/krb5.conf")
self.__template_file("/usr/share/ipa/html/krb5.ini")
self.__template_file("/usr/share/ipa/html/krb.con")
self.__template_file("/usr/share/ipa/html/krbrealm.con")
if not replica:
#populate the directory with the realm structure
args = ["kdb5_ldap_util", "-D", "uid=kdc,cn=sysaccounts,cn=etc,"+self.suffix, "-w", self.kdc_password, "create", "-s", "-P", self.master_password, "-r", self.realm, "-subtrees", self.suffix, "-sscope", "sub"]
try:
ipautil.run(args, nolog=(self.kdc_password, self.master_password))
except ipautil.CalledProcessError, e:
print "Failed to populate the realm structure in kerberos", e
MIN_KRB5KDC_WITH_WORKERS = "1.9"
cpus = os.sysconf('SC_NPROCESSORS_ONLN')
workers = False
@ -401,89 +393,6 @@ class KrbInstance(service.Service):
def __add_pwd_extop_module(self):
self._ldap_mod("pwd-extop-conf.ldif", self.sub_dict)
def __add_master_key(self):
#check for a keytab file by checking if the header magic is for a keytab
def __is_keytab(header):
if header == 0x0502 or header == 0x0501 or header == 0x0205 or header == 0x0105:
return 1
else:
return 0
#check whether a keytab file is v1 or v2
def __keytab_version(header):
if header == 0x0502 or header == 0x0205:
return 2
elif header == 0x0501 or header == 0x0105:
return 1
else:
return 0
#get the Master Key from the stash file
try:
stash = open("/var/kerberos/krb5kdc/.k5."+self.realm, "r")
keytype = struct.unpack('h', stash.read(2))[0]
if __is_keytab(keytype):
#in v2, all numbers are stored in network order
if __keytab_version(keytype) > 1:
__endian = '!'
else:
__endian = ''
#walk the first entry (there should only be one)
keyentrylen = struct.unpack(__endian + 'i', stash.read(4))[0]
#number of components in the principal name
keyprinccomps = struct.unpack(__endian + 'h', stash.read(2))[0]
#version 1 counted the realm as a component, version 2 doesn't
if __keytab_version(keytype) == 1:
keyprinccomps = keyprinccomps - 1
keyprinc = []
#read the components. the realm goes first, so we should
#end up with (realm, "K", "M")
for i in range(keyprinccomps + 1):
keyprinccompsize = struct.unpack(__endian + 'h', stash.read(2))[0]
keyprinc = keyprinc + [stash.read(keyprinccompsize)]
#version 2 added the principal name type, otherwise we just
#assume it's a regular old principal name
if __keytab_version(keytype) > 1:
keyprinctype = struct.unpack(__endian + 'i', stash.read(4))[0]
else:
keyprinctype = 1
#date the key was added to this keytab
keydate = struct.unpack(__endian + 'i', stash.read(4))[0]
#kvno
keyversion = struct.unpack('B', stash.read(1))[0]
#read the real enctype
keytype = struct.unpack(__endian + 'h', stash.read(2))[0]
keylen = struct.unpack(__endian + 'h', stash.read(2))[0]
keydata = stash.read(keylen)
#check that we parsed the whole file, so no surprises
keyoffset = stash.tell()
stash.seek(0,2)
if stash.tell() != keyoffset:
logging.critical("Unexpected unprocessed data in Stash file (processed %ld bytes, %ld left)." % (keyoffset, stash.tell() - keyoffset))
else:
keyversion = 1
keyprinctype = 1
keyprinc = [self.realm,"K","M"]
keylen = struct.unpack('i', stash.read(4))[0]
keydata = stash.read(keylen)
except os.error:
logging.critical("Failed to retrieve Master Key from Stash file: %s")
#encode it in the asn.1 attribute
MasterKey = univ.Sequence()
MasterKey.setComponentByPosition(0, univ.Integer(keytype))
MasterKey.setComponentByPosition(1, univ.OctetString(keydata))
krbMKey = univ.Sequence()
krbMKey.setComponentByPosition(0, univ.Integer(keyversion))
krbMKey.setComponentByPosition(1, MasterKey)
asn1key = pyasn1.codec.ber.encoder.encode(krbMKey)
#protect the master key by adding an appropriate deny rule along with the key
mod = [(ldap.MOD_ADD, 'aci', ipautil.template_str(KRBMKEY_DENY_ACI, self.sub_dict)),
(ldap.MOD_ADD, 'krbMKey', str(asn1key))]
try:
self.admin_conn.modify_s(self.get_realm_suffix(), mod)
except ldap.TYPE_OR_VALUE_EXISTS, e:
logging.critical("failed to add master key to kerberos database\n")
raise e
def __create_ds_keytab(self):
ldap_principal = "ldap/" + self.fqdn + "@" + self.realm
installutils.kadmin_addprinc(ldap_principal)