From 4286f3885b173da9ceeb2d13d66f90336b9ef094 Mon Sep 17 00:00:00 2001 From: Martin Babinsky Date: Nov 11 2016 11:17:25 +0000 Subject: Service: common method for service keytab requests Since creation of service principals and keytab retrieval are common operations, Service class should provide means to add service entry to LDAP, retrieve its keytab to designated destination and change the owner to service user. https://fedorahosted.org/freeipa/ticket/6405 Reviewed-By: Stanislav Laznicka --- diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index 75a1304..da08dae 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -19,6 +19,7 @@ import sys import os +import pwd import socket import datetime import traceback @@ -165,6 +166,7 @@ class Service(object): self.dercert = None self.api = api self.service_user = service_user + self.dm_password = None # silence pylint @property def admin_conn(self): @@ -534,6 +536,58 @@ class Service(object): else: root_logger.debug("service %s container sucessfully removed", name) + def _add_service_principal(self): + try: + self.api.Command.service_add(self.principal, force=True) + except errors.DuplicateEntry: + pass + + def _run_getkeytab(self): + """ + backup and remove old service keytab (if present) and fetch a new one + using ipa-getkeytab. This assumes that the service principal is already + created in LDAP. By default GSSAPI authentication is used unless: + * LDAPI socket is used and effective process UID is 0, then + autobind is used by EXTERNAL SASL mech + * self.dm_password is not none, then DM credentials are used to + fetch keytab + """ + self.fstore.backup_file(self.keytab) + try: + os.unlink(self.keytab) + except OSError: + pass + + ldap_uri = self.api.env.ldap_uri + args = [paths.IPA_GETKEYTAB, + '-k', self.keytab, + '-p', self.principal, + '-H', ldap_uri] + nolog = tuple() + + if ldap_uri.startswith("ldapi://") and os.geteuid() == 0: + args.extend(["-Y", "EXTERNAL"]) + elif self.dm_password is not None: + args.extend( + ['-D', 'cn=Directory Manager', + '-w', self.dm_password]) + nolog += (self.dm_password,) + + ipautil.run(args, nolog=nolog) + + def _request_service_keytab(self): + if any(attr is None for attr in (self.principal, self.keytab, + self.service_user)): + raise NotImplementedError( + "service must have defined principal " + "name, keytab, and username") + + self._add_service_principal() + self._run_getkeytab() + + pent = pwd.getpwnam(self.service_user) + os.chown(self.keytab, pent.pw_uid, pent.pw_gid) + class SimpleServiceInstance(Service): def create_instance(self, gensvc_name=None, fqdn=None, ldap_suffix=None,