From 195a65d5c2b2f2a318225a94e734ec41cdc34b1d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 8 Jun 2011 17:21:23 -0400 Subject: 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. --- install/share/Makefile.am | 2 - install/share/default-keytypes.ldif | 33 ---------- install/share/default-pwpolicy.ldif | 14 ---- install/share/kdc.conf.template | 1 - install/share/kerberos.ldif | 39 +++++++++++ install/share/krb5.conf.template | 7 +- ipaserver/install/installutils.py | 3 +- ipaserver/install/krbinstance.py | 127 +++++------------------------------- 8 files changed, 60 insertions(+), 166 deletions(-) delete mode 100644 install/share/default-keytypes.ldif delete mode 100644 install/share/default-pwpolicy.ldif diff --git a/install/share/Makefile.am b/install/share/Makefile.am index c6361099b..1ff2a4ea3 100644 --- a/install/share/Makefile.am +++ b/install/share/Makefile.am @@ -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 \ diff --git a/install/share/default-keytypes.ldif b/install/share/default-keytypes.ldif deleted file mode 100644 index 8093b6989..000000000 --- a/install/share/default-keytypes.ldif +++ /dev/null @@ -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 - diff --git a/install/share/default-pwpolicy.ldif b/install/share/default-pwpolicy.ldif deleted file mode 100644 index 1bb4a096e..000000000 --- a/install/share/default-pwpolicy.ldif +++ /dev/null @@ -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 - diff --git a/install/share/kdc.conf.template b/install/share/kdc.conf.template index 02f1dc111..0a51162da 100644 --- a/install/share/kdc.conf.template +++ b/install/share/kdc.conf.template @@ -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 diff --git a/install/share/kerberos.ldif b/install/share/kerberos.ldif index a4c603d8b..a40b63aa0 100644 --- a/install/share/kerberos.ldif +++ b/install/share/kerberos.ldif @@ -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 + diff --git a/install/share/krb5.conf.template b/install/share/krb5.conf.template index 46e26a4ba..d5e5af595 100644 --- a/install/share/krb5.conf.template +++ b/install/share/krb5.conf.template @@ -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 } diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index df63b8e8c..4192024d3 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -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) diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index 70f13fb4a..838811b33 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -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) -- cgit