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 \
|
||||
default-aci.ldif \
|
||||
default-hbac.ldif \
|
||||
default-keytypes.ldif \
|
||||
default-pwpolicy.ldif \
|
||||
delegation.ldif \
|
||||
replica-acis.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]
|
||||
$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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user