import os import subprocess from typing import List from zope import component from zope.interface import implementer from ceo_common.interfaces import IKerberosService, IConfig @implementer(IKerberosService) class KerberosService: def __init__( self, admin_principal: str, ): cfg = component.getUtility(IConfig) self.admin_principal = admin_principal self.realm = cfg.get('ldap_sasl_realm') # We don't need a credentials cache because the client forwards # their credentials to us os.environ['KRB5CCNAME'] = 'FILE:/dev/null' def _run(self, args: List[str]): subprocess.run(args, check=True) def addprinc(self, principal: str, password: str): self._run([ 'kadmin', '-k', '-p', self.admin_principal, 'addprinc', '-pw', password, '-policy', 'default', '+needchange', '+requires_preauth', principal ]) def delprinc(self, principal: str): self._run([ 'kadmin', '-k', '-p', self.admin_principal, 'delprinc', '-force', principal ]) def change_password(self, principal: str, password: str): self._run([ 'kadmin', '-k', '-p', self.admin_principal, 'cpw', '-pw', password, principal ]) self._run([ 'kadmin', '-k', '-p', self.admin_principal, 'modprinc', '+needchange', principal ])