diff options
author | Martin Babinsky <mbabinsk@redhat.com> | 2016-11-03 17:54:14 +0100 |
---|---|---|
committer | Jan Cholasta <jcholast@redhat.com> | 2016-11-11 12:17:25 +0100 |
commit | 32599987fdc998e104846e8a176f70399cca2af2 (patch) | |
tree | 5d718e32a4b21626ef1f2d2a36edea8c53fc5bd1 /ipaserver | |
parent | 81bf72dc350b9c7daab669aaa796e96aee6ecbb8 (diff) | |
download | freeipa-32599987fdc998e104846e8a176f70399cca2af2.tar.gz freeipa-32599987fdc998e104846e8a176f70399cca2af2.tar.xz freeipa-32599987fdc998e104846e8a176f70399cca2af2.zip |
Turn Kerberos-related properties to Service class members
The Service class now accepts keytab path and service name part of Kerberos
principal as members. Kerberos principal is turned into a property computed
from service prefix, FQDN and realm. the handling of Kerberos principals and
keytabs in service installers was changed to use class members instead of
copy-pasted constants. This shall aid in the future refactoring of
principal/keytab handling code.
https://fedorahosted.org/freeipa/ticket/6392
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r-- | ipaserver/install/adtrustinstance.py | 27 | ||||
-rw-r--r-- | ipaserver/install/bindinstance.py | 23 | ||||
-rw-r--r-- | ipaserver/install/cainstance.py | 21 | ||||
-rw-r--r-- | ipaserver/install/dnskeysyncinstance.py | 21 | ||||
-rw-r--r-- | ipaserver/install/dogtaginstance.py | 5 | ||||
-rw-r--r-- | ipaserver/install/dsinstance.py | 13 | ||||
-rw-r--r-- | ipaserver/install/httpinstance.py | 11 | ||||
-rw-r--r-- | ipaserver/install/odsexporterinstance.py | 26 | ||||
-rw-r--r-- | ipaserver/install/service.py | 22 |
9 files changed, 95 insertions, 74 deletions
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py index 95988498c..cab5a7239 100644 --- a/ipaserver/install/adtrustinstance.py +++ b/ipaserver/install/adtrustinstance.py @@ -136,7 +136,8 @@ class ADTRUSTInstance(service.Service): self.host_netbios_name = None super(ADTRUSTInstance, self).__init__( - "smb", service_desc="CIFS", fstore=fstore) + "smb", service_desc="CIFS", fstore=fstore, service_prefix=u'cifs', + keytab=paths.SAMBA_KEYTAB) self.__setup_default_attributes() @@ -148,7 +149,6 @@ class ADTRUSTInstance(service.Service): # Constants self.smb_conf = paths.SMB_CONF - self.samba_keytab = paths.SAMBA_KEYTAB self.cifs_hosts = [] # Values obtained from API.env @@ -156,7 +156,6 @@ class ADTRUSTInstance(service.Service): self.host_netbios_name = make_netbios_name(self.fqdn) self.realm = self.realm or api.env.realm - self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm self.suffix = ipautil.realm_to_suffix(self.realm) self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \ installutils.realm_to_serverid(self.realm) @@ -173,7 +172,7 @@ class ADTRUSTInstance(service.Service): api.env.container_cifsdomains, self.suffix) - self.cifs_agent = DN(('krbprincipalname', self.cifs_principal.lower()), + self.cifs_agent = DN(('krbprincipalname', self.principal.lower()), api.env.container_service, self.suffix) self.host_princ = DN(('fqdn', self.fqdn), @@ -494,8 +493,8 @@ class ADTRUSTInstance(service.Service): try: current = self.admin_conn.get_entry(targets_dn) members = current.get('memberPrincipal', []) - if not(self.cifs_principal in members): - current["memberPrincipal"] = members + [self.cifs_principal] + if not(self.principal in members): + current["memberPrincipal"] = members + [self.principal] self.admin_conn.update_entry(current) else: self.print_msg('cifs principal already targeted, nothing to do.') @@ -530,7 +529,7 @@ class ADTRUSTInstance(service.Service): def __setup_principal(self): try: - api.Command.service_add(unicode(self.cifs_principal)) + api.Command.service_add(unicode(self.principal)) except errors.DuplicateEntry: # CIFS principal already exists, it is not the first time # adtrustinstance is managed @@ -544,21 +543,21 @@ class ADTRUSTInstance(service.Service): try: ipautil.run(["ipa-getkeytab", "--server", self.fqdn, - "--principal", self.cifs_principal, - "-k", self.samba_keytab]) + "--principal", self.principal, + "-k", self.keytab]) except ipautil.CalledProcessError: root_logger.critical("Failed to add key for %s" - % self.cifs_principal) + % self.principal) def clean_samba_keytab(self): - if os.path.exists(self.samba_keytab): + if os.path.exists(self.keytab): try: - ipautil.run(["ipa-rmkeytab", "--principal", self.cifs_principal, - "-k", self.samba_keytab]) + ipautil.run(["ipa-rmkeytab", "--principal", self.principal, + "-k", self.keytab]) except ipautil.CalledProcessError as e: if e.returncode != 5: root_logger.critical("Failed to remove old key for %s" - % self.cifs_principal) + % self.principal) def srv_rec(self, host, port, prio): return "%(prio)d 100 %(port)d %(host)s" % dict(host=host,prio=prio,port=port) diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index bdafd0ff6..d32ced7a6 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -620,7 +620,9 @@ class BindInstance(service.Service): service_desc="DNS", fstore=fstore, api=api, - service_user=constants.NAMED_USER + service_user=constants.NAMED_USER, + service_prefix=u'DNS', + keytab=paths.NAMED_KEYTAB ) self.dns_backup = DnsBackup(self) self.domain = None @@ -778,7 +780,7 @@ class BindInstance(service.Service): BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, ROOT_KEY=paths.NAMED_ROOT_KEY, - NAMED_KEYTAB=paths.NAMED_KEYTAB, + NAMED_KEYTAB=self.keytab, RFC1912_ZONES=paths.NAMED_RFC1912_ZONES, NAMED_PID=paths.NAMED_PID, NAMED_VAR_DIR=paths.NAMED_VAR_DIR, @@ -875,24 +877,23 @@ class BindInstance(service.Service): self.__add_master_records(fqdn, addrs) def __setup_principal(self): - dns_principal = "DNS/" + self.fqdn + "@" + self.realm - installutils.kadmin_addprinc(dns_principal) + installutils.kadmin_addprinc(self.principal) # Store the keytab on disk - self.fstore.backup_file(paths.NAMED_KEYTAB) - installutils.create_keytab(paths.NAMED_KEYTAB, dns_principal) - p = self.move_service(dns_principal) + self.fstore.backup_file(self.keytab) + installutils.create_keytab(self.keytab, self.principal) + p = self.move_service(self.principal) if p is None: # the service has already been moved, perhaps we're doing a DNS reinstall - dns_principal = DN(('krbprincipalname', dns_principal), + dns_principal = DN(('krbprincipalname', self.principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix) else: dns_principal = p # Make sure access is strictly reserved to the named user pent = pwd.getpwnam(self.service_user) - os.chown(paths.NAMED_KEYTAB, pent.pw_uid, pent.pw_gid) - os.chmod(paths.NAMED_KEYTAB, 0o400) + os.chown(self.keytab, pent.pw_uid, pent.pw_gid) + os.chmod(self.keytab, 0o400) # modify the principal so that it is marked as an ipa service so that # it can host the memberof attribute, then also add it to the @@ -1188,5 +1189,5 @@ class BindInstance(service.Service): if named_regular_running: self.named_regular.start() - installutils.remove_keytab(paths.NAMED_KEYTAB) + installutils.remove_keytab(self.keytab) installutils.remove_ccache(run_as=self.service_user) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 9e257b805..4953ff7a0 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -302,6 +302,7 @@ class CAInstance(DogtagInstance): subsystem="CA", service_desc="certificate server", host_name=host_name, + service_prefix=ipalib.constants.PKI_GSSAPI_SERVICE_NAME, ) # for external CAs @@ -323,6 +324,8 @@ class CAInstance(DogtagInstance): self.requestId = None self.log = log_mgr.get_logger(self) self.no_db_setup = False + self.keytab = os.path.join( + paths.PKI_TOMCAT, self.service_prefix + '.keytab') def configure_instance(self, host_name, dm_password, admin_password, pkcs12_info=None, master_host=None, csr_file=None, @@ -1229,23 +1232,19 @@ class CAInstance(DogtagInstance): sysupgrade.set_upgrade_state('dogtag', 'setup_lwca_key_retieval', True) def __setup_lightweight_ca_key_retrieval_kerberos(self): - service = ipalib.constants.PKI_GSSAPI_SERVICE_NAME - principal = '{}/{}@{}'.format(service, api.env.host, self.realm) pent = pwd.getpwnam(self.service_user) root_logger.info('Creating principal') - installutils.kadmin_addprinc(principal) + installutils.kadmin_addprinc(self.principal) self.suffix = ipautil.realm_to_suffix(self.realm) - self.move_service(principal) + self.move_service(self.principal) root_logger.info('Retrieving keytab') - keytab = os.path.join(paths.PKI_TOMCAT, service + '.keytab') - installutils.create_keytab(keytab, principal) - os.chmod(keytab, 0o600) - os.chown(keytab, pent.pw_uid, pent.pw_gid) + installutils.create_keytab(self.keytab, self.principal) + os.chmod(self.keytab, 0o600) + os.chown(self.keytab, pent.pw_uid, pent.pw_gid) def __setup_lightweight_ca_key_retrieval_custodia(self): - service = ipalib.constants.PKI_GSSAPI_SERVICE_NAME pent = pwd.getpwnam(self.service_user) root_logger.info('Creating Custodia keys') @@ -1261,9 +1260,9 @@ class CAInstance(DogtagInstance): objectclass=['top', 'nsContainer'], cn=['dogtag'], ) - keyfile = os.path.join(paths.PKI_TOMCAT, service + '.keys') + keyfile = os.path.join(paths.PKI_TOMCAT, self.service_prefix + '.keys') keystore = IPAKEMKeys({'server_keys': keyfile}) - keystore.generate_keys(service) + keystore.generate_keys(self.service_prefix) os.chmod(keyfile, 0o600) os.chown(keyfile, pent.pw_uid, pent.pw_gid) diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py index bcbeeec44..656242b3f 100644 --- a/ipaserver/install/dnskeysyncinstance.py +++ b/ipaserver/install/dnskeysyncinstance.py @@ -64,7 +64,9 @@ class DNSKeySyncInstance(service.Service): super(DNSKeySyncInstance, self).__init__( "ipa-dnskeysyncd", service_desc="DNS key synchronization service", - fstore=fstore + fstore=fstore, + service_prefix=u'ipa-dnskeysync', + keytab=paths.IPA_DNSKEYSYNCD_KEYTAB ) self.logger = logger self.extra_config = [u'dnssecVersion 1', ] # DNSSEC enabled @@ -406,24 +408,23 @@ class DNSKeySyncInstance(service.Service): def __setup_principal(self): assert self.ods_gid is not None - installutils.remove_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB) - dnssynckey_principal = "ipa-dnskeysyncd/" + self.fqdn + "@" + self.realm - installutils.kadmin_addprinc(dnssynckey_principal) + installutils.remove_keytab(self.keytab) + installutils.kadmin_addprinc(self.principal) # Store the keytab on disk - installutils.create_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB, dnssynckey_principal) - p = self.move_service(dnssynckey_principal) + installutils.create_keytab(self.keytab, self.principal) + p = self.move_service(self.principal) if p is None: # the service has already been moved, perhaps we're doing a DNS reinstall dnssynckey_principal_dn = DN( - ('krbprincipalname', dnssynckey_principal), + ('krbprincipalname', self.principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix) else: dnssynckey_principal_dn = p # Make sure access is strictly reserved to the named user - os.chown(paths.IPA_DNSKEYSYNCD_KEYTAB, 0, self.ods_gid) - os.chmod(paths.IPA_DNSKEYSYNCD_KEYTAB, 0o440) + os.chown(self.keytab, 0, self.ods_gid) + os.chmod(self.keytab, 0o440) dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), self.suffix) @@ -487,4 +488,4 @@ class DNSKeySyncInstance(service.Service): except Exception: pass - installutils.remove_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB) + installutils.remove_keytab(self.keytab) diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py index cf1e5e078..5d25e42d8 100644 --- a/ipaserver/install/dogtaginstance.py +++ b/ipaserver/install/dogtaginstance.py @@ -108,14 +108,15 @@ class DogtagInstance(service.Service): server_cert_name = None def __init__(self, realm, subsystem, service_desc, host_name=None, - nss_db=paths.PKI_TOMCAT_ALIAS_DIR): + nss_db=paths.PKI_TOMCAT_ALIAS_DIR, service_prefix=None): """Initializer""" super(DogtagInstance, self).__init__( 'pki-tomcatd', service_desc=service_desc, realm_name=realm, - service_user=constants.PKI_USER + service_user=constants.PKI_USER, + service_prefix=service_prefix ) self.admin_password = None diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index d26f8380c..7c5cf92c1 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -227,6 +227,8 @@ class DsInstance(service.Service): "dirsrv", service_desc="directory server", fstore=fstore, + service_prefix=u'ldap', + keytab=paths.DS_KEYTAB, service_user=DS_USER, realm_name=realm_name ) @@ -308,7 +310,6 @@ class DsInstance(service.Service): self.fqdn = fqdn self.dm_password = dm_password self.domain = domain_name - self.principal = "ldap/%s@%s" % (self.fqdn, self.realm) self.subject_base = subject_base self.idstart = idstart self.idmax = idmax @@ -1225,26 +1226,26 @@ class DsInstance(service.Service): def __get_ds_keytab(self): - self.fstore.backup_file(paths.DS_KEYTAB) + self.fstore.backup_file(self.keytab) try: - os.unlink(paths.DS_KEYTAB) + os.unlink(self.keytab) except OSError: pass installutils.install_service_keytab(self.api, self.principal, self.master_fqdn, - paths.DS_KEYTAB, + self.keytab, force_service_add=True) # Configure DS to use the keytab - vardict = {"KRB5_KTNAME": paths.DS_KEYTAB} + vardict = {"KRB5_KTNAME": self.keytab} ipautil.config_replace_variables(paths.SYSCONFIG_DIRSRV, replacevars=vardict) # Keytab must be owned by DS itself pent = pwd.getpwnam(self.service_user) - os.chown(paths.DS_KEYTAB, pent.pw_uid, pent.pw_gid) + os.chown(self.keytab, pent.pw_uid, pent.pw_gid) def __get_ds_cert(self): subject = self.subject_base or DN(('O', self.realm)) diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 2869116af..25d16f28e 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -124,7 +124,9 @@ class HTTPInstance(service.Service): "httpd", service_desc="the web interface", fstore=fstore, - service_user=HTTPD_USER) + service_prefix=u'HTTP', + service_user=HTTPD_USER, + keytab=paths.IPA_KEYTAB) self.cert_nickname = cert_nickname self.ca_is_configured = True @@ -139,7 +141,6 @@ class HTTPInstance(service.Service): self.domain = domain_name self.suffix = ipautil.realm_to_suffix(self.realm) self.pkcs12_info = pkcs12_info - self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm) self.dercert = None self.subject_base = subject_base self.sub_dict = dict( @@ -202,9 +203,9 @@ class HTTPInstance(service.Service): def __create_http_keytab(self): if not self.promote: - installutils.remove_keytab(paths.IPA_KEYTAB) + installutils.remove_keytab(self.keytab) installutils.kadmin_addprinc(self.principal) - installutils.create_keytab(paths.IPA_KEYTAB, self.principal) + installutils.create_keytab(self.keytab, self.principal) self.move_service(self.principal) pent = pwd.getpwnam(self.service_user) @@ -527,7 +528,7 @@ class HTTPInstance(service.Service): except ValueError as error: root_logger.debug(error) - installutils.remove_keytab(paths.IPA_KEYTAB) + installutils.remove_keytab(self.keytab) installutils.remove_ccache(ccache_path=paths.KRB5CC_HTTPD, run_as=self.service_user) diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py index a53ebe667..7caf27adb 100644 --- a/ipaserver/install/odsexporterinstance.py +++ b/ipaserver/install/odsexporterinstance.py @@ -24,7 +24,9 @@ class ODSExporterInstance(service.Service): super(ODSExporterInstance, self).__init__( "ipa-ods-exporter", service_desc="IPA OpenDNSSEC exporter daemon", - fstore=fstore + fstore=fstore, + keytab=paths.IPA_ODS_EXPORTER_KEYTAB, + service_prefix=u'ipa-ods-exporter' ) self.ods_uid = None self.ods_gid = None @@ -81,29 +83,29 @@ class ODSExporterInstance(service.Service): def __setup_principal(self): assert self.ods_uid is not None - for f in [paths.IPA_ODS_EXPORTER_CCACHE, paths.IPA_ODS_EXPORTER_KEYTAB]: + for f in [paths.IPA_ODS_EXPORTER_CCACHE, self.keytab]: try: os.remove(f) except OSError: pass - dns_exporter_principal = "ipa-ods-exporter/" + self.fqdn + "@" + self.realm - installutils.kadmin_addprinc(dns_exporter_principal) + installutils.kadmin_addprinc(self.principal) # Store the keytab on disk - installutils.create_keytab(paths.IPA_ODS_EXPORTER_KEYTAB, dns_exporter_principal) - p = self.move_service(dns_exporter_principal) + installutils.create_keytab(paths.IPA_ODS_EXPORTER_KEYTAB, + self.principal) + p = self.move_service(self.principal) if p is None: # the service has already been moved, perhaps we're doing a DNS reinstall dns_exporter_principal_dn = DN( - ('krbprincipalname', dns_exporter_principal), + ('krbprincipalname', self.principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix) else: dns_exporter_principal_dn = p # Make sure access is strictly reserved to the ods user - os.chmod(paths.IPA_ODS_EXPORTER_KEYTAB, 0o440) - os.chown(paths.IPA_ODS_EXPORTER_KEYTAB, 0, self.ods_gid) + os.chmod(self.keytab, 0o440) + os.chown(self.keytab, 0, self.ods_gid) dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), self.suffix) @@ -146,10 +148,8 @@ class ODSExporterInstance(service.Service): self.start() def remove_service(self): - dns_exporter_principal = ("ipa-ods-exporter/%s@%s" % (self.fqdn, - self.realm)) try: - api.Command.service_del(dns_exporter_principal) + api.Command.service_del(self.principal) except errors.NotFound: pass @@ -181,5 +181,5 @@ class ODSExporterInstance(service.Service): if signerd_running: signerd_service.start() - installutils.remove_keytab(paths.IPA_ODS_EXPORTER_KEYTAB) + installutils.remove_keytab(self.keytab) installutils.remove_ccache(ccache_path=paths.IPA_ODS_EXPORTER_CCACHE) diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index 79d6ceb8c..75a1304df 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -24,14 +24,20 @@ import datetime import traceback import tempfile +import six + from ipapython import ipautil, sysrestore from ipapython.dn import DN from ipapython.ipa_log_manager import root_logger +from ipapython import kerberos from ipalib import api, errors, certstore from ipaplatform import services from ipaplatform.paths import paths +if six.PY3: + unicode = str + # The service name as stored in cn=masters,cn=ipa,cn=etc. In the tuple # the first value is the *nix service name, the second the start order. SERVICE_LIST = { @@ -132,7 +138,8 @@ def find_providing_server(svcname, conn, host_name=None, api=api): class Service(object): def __init__(self, service_name, service_desc=None, sstore=None, fstore=None, api=api, realm_name=None, - service_user=None): + service_user=None, service_prefix=None, + keytab=None): self.service_name = service_name self.service_desc = service_desc self.service = services.service(service_name) @@ -153,7 +160,8 @@ class Service(object): self.realm = realm_name self.suffix = DN() - self.principal = None + self.service_prefix = service_prefix + self.keytab = keytab self.dercert = None self.api = api self.service_user = service_user @@ -165,6 +173,16 @@ class Service(object): """ return api.Backend.ldap2 + @property + def principal(self): + if any(attr is None for attr in (self.realm, self.fqdn, + self.service_prefix)): + return + + return unicode( + kerberos.Principal( + (self.service_prefix, self.fqdn), realm=self.realm)) + def _ldap_mod(self, ldif, sub_dict=None, raise_on_err=True, ldap_uri=None, dm_password=None): pw_name = None |