mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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:
parent
35e15f6c91
commit
195a65d5c2
@ -13,8 +13,6 @@ app_DATA = \
|
|||||||
caJarSigningCert.cfg.template \
|
caJarSigningCert.cfg.template \
|
||||||
default-aci.ldif \
|
default-aci.ldif \
|
||||||
default-hbac.ldif \
|
default-hbac.ldif \
|
||||||
default-keytypes.ldif \
|
|
||||||
default-pwpolicy.ldif \
|
|
||||||
delegation.ldif \
|
delegation.ldif \
|
||||||
replica-acis.ldif \
|
replica-acis.ldif \
|
||||||
ds-nfiles.ldif \
|
ds-nfiles.ldif \
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
|||||||
[realms]
|
[realms]
|
||||||
$REALM = {
|
$REALM = {
|
||||||
master_key_type = aes256-cts
|
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_life = 7d
|
||||||
max_renewable_life = 14d
|
max_renewable_life = 14d
|
||||||
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
||||||
|
@ -16,3 +16,42 @@ objectClass: top
|
|||||||
cn: kerberos
|
cn: kerberos
|
||||||
aci: (targetattr="*")(version 3.0; acl "KDC System Account"; allow (all) userdn= "ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
|
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
|
||||||
|
|
||||||
|
@ -31,11 +31,6 @@
|
|||||||
|
|
||||||
[dbmodules]
|
[dbmodules]
|
||||||
$REALM = {
|
$REALM = {
|
||||||
db_library = kldap
|
db_library = ipadb.so
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,8 @@ def get_directive(filename, directive, separator=' '):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def kadmin(command):
|
def kadmin(command):
|
||||||
ipautil.run(["kadmin.local", "-q", command])
|
ipautil.run(["kadmin.local", "-q", command,
|
||||||
|
"-x", "ipa-setup-override-restrictions"])
|
||||||
|
|
||||||
def kadmin_addprinc(principal):
|
def kadmin_addprinc(principal):
|
||||||
kadmin("addprinc -randkey " + principal)
|
kadmin("addprinc -randkey " + principal)
|
||||||
|
@ -114,7 +114,8 @@ class KrbInstance(service.Service):
|
|||||||
host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'ipaservice', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux'])
|
host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'ipaservice', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux'])
|
||||||
host_entry.setValues('krbextradata', service_entry.getValues('krbextradata'))
|
host_entry.setValues('krbextradata', service_entry.getValues('krbextradata'))
|
||||||
host_entry.setValue('krblastpwdchange', service_entry.getValue('krblastpwdchange'))
|
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'))
|
host_entry.setValue('krbprincipalname', service_entry.getValue('krbprincipalname'))
|
||||||
if 'krbticketflags' in service_entry.toDict():
|
if 'krbticketflags' in service_entry.toDict():
|
||||||
host_entry.setValue('krbticketflags', service_entry.getValue('krbticketflags'))
|
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("setting KDC account password", self.__configure_kdc_account_password)
|
||||||
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
|
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("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 directory", self.__create_ds_keytab)
|
||||||
self.step("creating a keytab for the machine", self.__create_host_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("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 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:
|
if setup_pkinit:
|
||||||
self.step("creating X509 Certificate for PKINIT", self.__setup_pkinit)
|
self.step("creating X509 Certificate for PKINIT", self.__setup_pkinit)
|
||||||
self.step("creating principal for anonymous PKINIT", self.__add_anonymous_pkinit_principal)
|
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("adding sasl mappings to the directory", self.__configure_sasl_mappings)
|
||||||
self.step("writing stash file from DS", self.__write_stash_from_ds)
|
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 directory", self.__create_ds_keytab)
|
||||||
self.step("creating a keytab for the machine", self.__create_host_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)
|
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")
|
logging.critical("failed to add Name Only Sasl mapping")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def __add_krb_entries(self):
|
def __add_krb_container(self):
|
||||||
self._ldap_mod("kerberos.ldif", self.sub_dict)
|
self._ldap_mod("kerberos.ldif", self.sub_dict)
|
||||||
|
|
||||||
def __add_default_acis(self):
|
def __add_default_acis(self):
|
||||||
self._ldap_mod("default-aci.ldif", self.sub_dict)
|
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):
|
def __template_file(self, path):
|
||||||
template = os.path.join(ipautil.SHARE_DIR, os.path.basename(path) + ".template")
|
template = os.path.join(ipautil.SHARE_DIR, os.path.basename(path) + ".template")
|
||||||
conf = ipautil.template_file(template, self.sub_dict)
|
conf = ipautil.template_file(template, self.sub_dict)
|
||||||
@ -327,21 +317,23 @@ class KrbInstance(service.Service):
|
|||||||
fd.write(conf)
|
fd.write(conf)
|
||||||
fd.close()
|
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("/var/kerberos/krb5kdc/kdc.conf")
|
||||||
self.__template_file("/etc/krb5.conf")
|
self.__template_file("/etc/krb5.conf")
|
||||||
self.__template_file("/usr/share/ipa/html/krb5.ini")
|
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/krb.con")
|
||||||
self.__template_file("/usr/share/ipa/html/krbrealm.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"
|
MIN_KRB5KDC_WITH_WORKERS = "1.9"
|
||||||
cpus = os.sysconf('SC_NPROCESSORS_ONLN')
|
cpus = os.sysconf('SC_NPROCESSORS_ONLN')
|
||||||
workers = False
|
workers = False
|
||||||
@ -401,89 +393,6 @@ class KrbInstance(service.Service):
|
|||||||
def __add_pwd_extop_module(self):
|
def __add_pwd_extop_module(self):
|
||||||
self._ldap_mod("pwd-extop-conf.ldif", self.sub_dict)
|
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):
|
def __create_ds_keytab(self):
|
||||||
ldap_principal = "ldap/" + self.fqdn + "@" + self.realm
|
ldap_principal = "ldap/" + self.fqdn + "@" + self.realm
|
||||||
installutils.kadmin_addprinc(ldap_principal)
|
installutils.kadmin_addprinc(ldap_principal)
|
||||||
|
Loading…
Reference in New Issue
Block a user