2007-06-28 18:09:54 -05:00
|
|
|
# Authors: Simo Sorce <ssorce@redhat.com>
|
|
|
|
#
|
|
|
|
# Copyright (C) 2007 Red Hat
|
|
|
|
# see file 'COPYING' for use and warranty information
|
|
|
|
#
|
2010-12-09 06:59:11 -06:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
2007-06-28 18:09:54 -05:00
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2010-12-09 06:59:11 -06:00
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2007-06-28 18:09:54 -05:00
|
|
|
#
|
|
|
|
|
|
|
|
import shutil
|
On 10/4/07, Rob Crittenden <rcritten@redhat.com> wrote:
> William Jon McCann wrote:
> > Hi,
> >
> > After playing with the install (repeatedly) I ended up with a lot of
> > duplicate values in:
> > /etc/sysconfig/dirsrv
> > /etc/sysconfig/ipa-kpasswd
> >
> > Here is a patch that should fix this. It modifies the file "in-place"
> > and removes lines that matching the key (or commented key) and then
> > appends the new key=value.
> >
> > Jon
>
> Cool, I've wanted to fix this for a while (and recently aborted a switch
> from open with "a" to "w").
>
> What happens if the file doesn't exist yet? Do we need to wrap the
> fileinput loop in either a try/except or just look to see if the file
> exists first (my vote)?
>
> Something like:
>
> def update_key_val_in_file(filename, key, val):
> if os.path.exists(filename):
> pattern = "^[\s#]*%s\s*=" % re.escape(key)
> p = re.compile(pattern)
> for line in fileinput.input(filename, inplace=1):
> if not p.search(line):
> sys.stdout.write(line)
> fileinput.close()
> f = open(filename, "a")
> f.write("%s=%s\n" % (key, val))
> f.close()
Good point. In genera,l I prefer doing a try because it is a little
less racy but in this case it doesn't make a difference.
Updated patch attached.
Thanks,
Jon
0000-12-31 18:09:24 -05:50
|
|
|
import fileinput
|
|
|
|
import re
|
|
|
|
import sys
|
2007-08-01 14:06:45 -05:00
|
|
|
import os
|
|
|
|
import pwd
|
|
|
|
import socket
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
import service
|
2007-12-18 12:03:34 -06:00
|
|
|
import installutils
|
2009-02-05 14:03:08 -06:00
|
|
|
from ipapython import sysrestore
|
|
|
|
from ipapython import ipautil
|
2011-09-13 02:47:13 -05:00
|
|
|
from ipapython import services as ipaservices
|
2009-02-04 09:53:34 -06:00
|
|
|
from ipalib import util
|
2009-04-23 07:51:59 -05:00
|
|
|
from ipalib import errors
|
2011-11-15 13:39:31 -06:00
|
|
|
from ipapython.ipa_log_manager import *
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2009-02-04 09:53:34 -06:00
|
|
|
from ipaserver import ipaldap
|
2011-01-11 09:27:48 -06:00
|
|
|
from ipaserver.install import replication
|
2011-01-28 14:45:19 -06:00
|
|
|
from ipaserver.install import dsinstance
|
2007-11-19 18:34:10 -06:00
|
|
|
|
|
|
|
import ldap
|
|
|
|
from ldap import LDAPError
|
|
|
|
from ldap import ldapobject
|
|
|
|
|
0000-12-31 18:09:24 -05:50
|
|
|
from pyasn1.type import univ, namedtype
|
2007-11-16 19:16:11 -06:00
|
|
|
import pyasn1.codec.ber.encoder
|
0000-12-31 18:09:24 -05:50
|
|
|
import pyasn1.codec.ber.decoder
|
2007-11-16 19:16:11 -06:00
|
|
|
import struct
|
2007-06-28 18:09:54 -05:00
|
|
|
|
2010-10-29 15:23:21 -05:00
|
|
|
import certs
|
2010-11-15 16:06:32 -06:00
|
|
|
from distutils import version
|
2010-10-29 15:23:21 -05:00
|
|
|
|
On 10/4/07, Rob Crittenden <rcritten@redhat.com> wrote:
> William Jon McCann wrote:
> > Hi,
> >
> > After playing with the install (repeatedly) I ended up with a lot of
> > duplicate values in:
> > /etc/sysconfig/dirsrv
> > /etc/sysconfig/ipa-kpasswd
> >
> > Here is a patch that should fix this. It modifies the file "in-place"
> > and removes lines that matching the key (or commented key) and then
> > appends the new key=value.
> >
> > Jon
>
> Cool, I've wanted to fix this for a while (and recently aborted a switch
> from open with "a" to "w").
>
> What happens if the file doesn't exist yet? Do we need to wrap the
> fileinput loop in either a try/except or just look to see if the file
> exists first (my vote)?
>
> Something like:
>
> def update_key_val_in_file(filename, key, val):
> if os.path.exists(filename):
> pattern = "^[\s#]*%s\s*=" % re.escape(key)
> p = re.compile(pattern)
> for line in fileinput.input(filename, inplace=1):
> if not p.search(line):
> sys.stdout.write(line)
> fileinput.close()
> f = open(filename, "a")
> f.write("%s=%s\n" % (key, val))
> f.close()
Good point. In genera,l I prefer doing a try because it is a little
less racy but in this case it doesn't make a difference.
Updated patch attached.
Thanks,
Jon
0000-12-31 18:09:24 -05:50
|
|
|
def update_key_val_in_file(filename, key, val):
|
|
|
|
if os.path.exists(filename):
|
2007-12-13 03:31:28 -06:00
|
|
|
pattern = "^[\s#]*%s\s*=\s*%s\s*" % (re.escape(key), re.escape(val))
|
|
|
|
p = re.compile(pattern)
|
|
|
|
for line in fileinput.input(filename):
|
|
|
|
if p.search(line):
|
|
|
|
fileinput.close()
|
|
|
|
return
|
|
|
|
fileinput.close()
|
|
|
|
|
On 10/4/07, Rob Crittenden <rcritten@redhat.com> wrote:
> William Jon McCann wrote:
> > Hi,
> >
> > After playing with the install (repeatedly) I ended up with a lot of
> > duplicate values in:
> > /etc/sysconfig/dirsrv
> > /etc/sysconfig/ipa-kpasswd
> >
> > Here is a patch that should fix this. It modifies the file "in-place"
> > and removes lines that matching the key (or commented key) and then
> > appends the new key=value.
> >
> > Jon
>
> Cool, I've wanted to fix this for a while (and recently aborted a switch
> from open with "a" to "w").
>
> What happens if the file doesn't exist yet? Do we need to wrap the
> fileinput loop in either a try/except or just look to see if the file
> exists first (my vote)?
>
> Something like:
>
> def update_key_val_in_file(filename, key, val):
> if os.path.exists(filename):
> pattern = "^[\s#]*%s\s*=" % re.escape(key)
> p = re.compile(pattern)
> for line in fileinput.input(filename, inplace=1):
> if not p.search(line):
> sys.stdout.write(line)
> fileinput.close()
> f = open(filename, "a")
> f.write("%s=%s\n" % (key, val))
> f.close()
Good point. In genera,l I prefer doing a try because it is a little
less racy but in this case it doesn't make a difference.
Updated patch attached.
Thanks,
Jon
0000-12-31 18:09:24 -05:50
|
|
|
pattern = "^[\s#]*%s\s*=" % re.escape(key)
|
|
|
|
p = re.compile(pattern)
|
|
|
|
for line in fileinput.input(filename, inplace=1):
|
|
|
|
if not p.search(line):
|
|
|
|
sys.stdout.write(line)
|
|
|
|
fileinput.close()
|
|
|
|
f = open(filename, "a")
|
|
|
|
f.write("%s=%s\n" % (key, val))
|
|
|
|
f.close()
|
2008-01-22 05:58:06 -06:00
|
|
|
|
|
|
|
class KpasswdInstance(service.SimpleServiceInstance):
|
|
|
|
def __init__(self):
|
2011-07-20 17:11:05 -05:00
|
|
|
service.SimpleServiceInstance.__init__(self, "kadmin")
|
2008-03-27 18:01:38 -05:00
|
|
|
|
0000-12-31 18:09:24 -05:50
|
|
|
class KrbInstance(service.Service):
|
2008-03-27 18:01:38 -05:00
|
|
|
def __init__(self, fstore=None):
|
0000-12-31 18:09:24 -05:50
|
|
|
service.Service.__init__(self, "krb5kdc")
|
2007-08-01 14:06:45 -05:00
|
|
|
self.fqdn = None
|
|
|
|
self.realm = None
|
2009-05-12 05:51:46 -05:00
|
|
|
self.domain = None
|
2007-08-01 14:06:45 -05:00
|
|
|
self.host = None
|
2007-06-28 18:09:54 -05:00
|
|
|
self.admin_password = None
|
|
|
|
self.master_password = None
|
|
|
|
self.suffix = None
|
|
|
|
self.kdc_password = None
|
|
|
|
self.sub_dict = None
|
2010-10-29 15:23:21 -05:00
|
|
|
self.pkcs12_info = None
|
|
|
|
self.self_signed_ca = None
|
2007-06-28 18:09:54 -05:00
|
|
|
|
2008-03-27 18:01:38 -05:00
|
|
|
if fstore:
|
|
|
|
self.fstore = fstore
|
|
|
|
else:
|
|
|
|
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
|
|
|
|
2011-06-09 11:42:03 -05:00
|
|
|
def get_realm_suffix(self):
|
|
|
|
return "cn=%s,cn=kerberos,%s" % (self.realm, self.suffix)
|
|
|
|
|
2009-12-07 22:17:00 -06:00
|
|
|
def move_service_to_host(self, principal):
|
|
|
|
"""
|
|
|
|
Used to move a host/ service principal created by kadmin.local from
|
|
|
|
cn=kerberos to reside under the host entry.
|
|
|
|
"""
|
|
|
|
|
2011-06-09 11:42:03 -05:00
|
|
|
service_dn = "krbprincipalname=%s,%s" % (principal, self.get_realm_suffix())
|
2011-01-05 06:46:30 -06:00
|
|
|
service_entry = self.admin_conn.getEntry(service_dn, ldap.SCOPE_BASE)
|
|
|
|
self.admin_conn.deleteEntry(service_dn)
|
2009-12-07 22:17:00 -06:00
|
|
|
|
|
|
|
# Create a host entry for this master
|
|
|
|
host_dn = "fqdn=%s,cn=computers,cn=accounts,%s" % (self.fqdn, self.suffix)
|
|
|
|
host_entry = ipaldap.Entry(host_dn)
|
2011-12-07 01:50:31 -06:00
|
|
|
host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'ipaservice', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux', 'ipasshhost'])
|
2010-08-31 15:59:27 -05:00
|
|
|
host_entry.setValues('krbextradata', service_entry.getValues('krbextradata'))
|
2009-12-07 22:17:00 -06:00
|
|
|
host_entry.setValue('krblastpwdchange', service_entry.getValue('krblastpwdchange'))
|
2011-06-08 16:21:23 -05:00
|
|
|
if 'krbpasswordexpiration' in service_entry.toDict():
|
|
|
|
host_entry.setValue('krbpasswordexpiration', service_entry.getValue('krbpasswordexpiration'))
|
2009-12-07 22:17:00 -06:00
|
|
|
host_entry.setValue('krbprincipalname', service_entry.getValue('krbprincipalname'))
|
2010-08-31 15:59:27 -05:00
|
|
|
if 'krbticketflags' in service_entry.toDict():
|
|
|
|
host_entry.setValue('krbticketflags', service_entry.getValue('krbticketflags'))
|
2009-12-07 22:17:00 -06:00
|
|
|
host_entry.setValue('krbprincipalkey', service_entry.getValue('krbprincipalkey'))
|
|
|
|
host_entry.setValue('serverhostname', self.fqdn.split('.',1)[0])
|
|
|
|
host_entry.setValue('cn', self.fqdn)
|
|
|
|
host_entry.setValue('fqdn', self.fqdn)
|
2010-10-26 09:26:06 -05:00
|
|
|
host_entry.setValue('ipauniqueid', 'autogenerate')
|
2009-12-16 15:04:53 -06:00
|
|
|
host_entry.setValue('managedby', host_dn)
|
2011-01-05 06:46:30 -06:00
|
|
|
self.admin_conn.addEntry(host_entry)
|
2009-12-07 22:17:00 -06:00
|
|
|
|
2011-01-28 14:45:19 -06:00
|
|
|
def __common_setup(self, realm_name, host_name, domain_name, admin_password):
|
2008-03-27 18:01:38 -05:00
|
|
|
self.fqdn = host_name
|
2007-08-01 14:06:45 -05:00
|
|
|
self.realm = realm_name.upper()
|
|
|
|
self.host = host_name.split(".")[0]
|
2010-12-01 10:22:56 -06:00
|
|
|
self.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0]
|
2008-02-15 19:47:29 -06:00
|
|
|
self.domain = domain_name
|
2009-02-04 09:53:34 -06:00
|
|
|
self.suffix = util.realm_to_suffix(self.realm)
|
2007-12-12 12:15:56 -06:00
|
|
|
self.kdc_password = ipautil.ipa_generate_password()
|
0000-12-31 18:09:24 -05:50
|
|
|
self.admin_password = admin_password
|
2009-05-12 05:51:46 -05:00
|
|
|
self.dm_password = admin_password
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
self.__setup_sub_dict()
|
|
|
|
|
|
|
|
# get a connection to the DS
|
2011-01-05 06:46:30 -06:00
|
|
|
self.ldap_connect()
|
2007-09-20 14:10:21 -05:00
|
|
|
|
2008-01-14 11:43:26 -06:00
|
|
|
self.backup_state("running", self.is_running())
|
2007-10-03 16:37:13 -05:00
|
|
|
try:
|
|
|
|
self.stop()
|
|
|
|
except:
|
|
|
|
# It could have been not running
|
|
|
|
pass
|
2007-09-20 14:10:21 -05:00
|
|
|
|
0000-12-31 18:09:24 -05:50
|
|
|
def __common_post_setup(self):
|
2007-12-13 03:31:28 -06:00
|
|
|
self.step("starting the KDC", self.__start_instance)
|
2008-01-14 11:43:26 -06:00
|
|
|
self.step("configuring KDC to start on boot", self.__enable)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2011-01-28 14:45:19 -06:00
|
|
|
def create_instance(self, realm_name, host_name, domain_name, admin_password, master_password, setup_pkinit=False, pkcs12_info=None, self_signed_ca=False, subject_base=None):
|
0000-12-31 18:09:24 -05:50
|
|
|
self.master_password = master_password
|
2010-10-29 15:23:21 -05:00
|
|
|
self.pkcs12_info = pkcs12_info
|
|
|
|
self.self_signed_ca = self_signed_ca
|
|
|
|
self.subject_base = subject_base
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2011-01-28 14:45:19 -06:00
|
|
|
self.__common_setup(realm_name, host_name, domain_name, admin_password)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2007-12-13 03:31:28 -06:00
|
|
|
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
|
2011-06-08 16:21:23 -05:00
|
|
|
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)
|
2008-02-05 15:50:12 -06:00
|
|
|
self.step("adding default ACIs", self.__add_default_acis)
|
2007-12-13 03:31:28 -06:00
|
|
|
self.step("creating a keytab for the directory", self.__create_ds_keytab)
|
2007-12-13 15:44:57 -06:00
|
|
|
self.step("creating a keytab for the machine", self.__create_host_keytab)
|
2008-04-14 16:12:40 -05:00
|
|
|
self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
|
2010-10-29 15:23:21 -05:00
|
|
|
if setup_pkinit:
|
|
|
|
self.step("creating X509 Certificate for PKINIT", self.__setup_pkinit)
|
2010-11-02 17:02:59 -05:00
|
|
|
self.step("creating principal for anonymous PKINIT", self.__add_anonymous_pkinit_principal)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
self.__common_post_setup()
|
|
|
|
|
2010-09-29 12:55:54 -05:00
|
|
|
self.start_creation("Configuring Kerberos KDC", 30)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2010-05-03 14:21:51 -05:00
|
|
|
self.kpasswd = KpasswdInstance()
|
2010-12-04 14:42:14 -06:00
|
|
|
self.kpasswd.create_instance('KPASSWD', self.fqdn, self.admin_password, self.suffix)
|
2008-01-22 05:58:06 -06:00
|
|
|
|
2011-01-28 14:45:19 -06:00
|
|
|
def create_replica(self, realm_name,
|
2011-01-11 09:27:48 -06:00
|
|
|
master_fqdn, host_name,
|
2010-11-03 17:17:36 -05:00
|
|
|
domain_name, admin_password,
|
|
|
|
setup_pkinit=False, pkcs12_info=None,
|
|
|
|
self_signed_ca=False, subject_base=None):
|
|
|
|
self.pkcs12_info = pkcs12_info
|
|
|
|
self.self_signed_ca = self_signed_ca
|
|
|
|
self.subject_base = subject_base
|
2011-01-11 09:27:48 -06:00
|
|
|
self.master_fqdn = master_fqdn
|
2007-12-13 03:31:28 -06:00
|
|
|
|
2011-01-28 14:45:19 -06:00
|
|
|
self.__common_setup(realm_name, host_name, domain_name, admin_password)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2007-12-13 03:31:28 -06:00
|
|
|
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
|
|
|
|
self.step("writing stash file from DS", self.__write_stash_from_ds)
|
2011-06-08 16:21:23 -05:00
|
|
|
self.step("configuring KDC", self.__configure_instance)
|
2007-12-13 03:31:28 -06:00
|
|
|
self.step("creating a keytab for the directory", self.__create_ds_keytab)
|
2007-12-13 15:44:57 -06:00
|
|
|
self.step("creating a keytab for the machine", self.__create_host_keytab)
|
2008-04-14 16:12:40 -05:00
|
|
|
self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
|
2010-11-03 17:17:36 -05:00
|
|
|
if setup_pkinit:
|
|
|
|
self.step("installing X509 Certificate for PKINIT", self.__setup_pkinit)
|
2011-02-02 09:24:30 -06:00
|
|
|
self.step("enable GSSAPI for replication", self.__convert_to_gssapi_replication)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
self.__common_post_setup()
|
|
|
|
|
2010-09-29 12:55:54 -05:00
|
|
|
self.start_creation("Configuring Kerberos KDC", 30)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2010-05-03 14:21:51 -05:00
|
|
|
self.kpasswd = KpasswdInstance()
|
2010-12-04 14:42:14 -06:00
|
|
|
self.kpasswd.create_instance('KPASSWD', self.fqdn, self.admin_password, self.suffix)
|
2008-01-22 05:58:06 -06:00
|
|
|
|
2008-03-27 18:01:38 -05:00
|
|
|
|
2008-01-14 11:43:26 -06:00
|
|
|
def __enable(self):
|
|
|
|
self.backup_state("enabled", self.is_enabled())
|
2010-12-04 14:42:14 -06:00
|
|
|
# We do not let the system start IPA components on its own,
|
|
|
|
# Instead we reply on the IPA init script to start only enabled
|
|
|
|
# components as found in our LDAP configuration tree
|
|
|
|
self.ldap_enable('KDC', self.fqdn, self.admin_password, self.suffix)
|
2008-01-14 11:43:26 -06:00
|
|
|
|
2007-12-13 03:31:28 -06:00
|
|
|
def __start_instance(self):
|
|
|
|
try:
|
|
|
|
self.start()
|
|
|
|
except:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("krb5kdc service failed to start")
|
2007-12-13 03:31:28 -06:00
|
|
|
|
2007-06-28 18:09:54 -05:00
|
|
|
def __setup_sub_dict(self):
|
2007-08-01 14:06:45 -05:00
|
|
|
self.sub_dict = dict(FQDN=self.fqdn,
|
|
|
|
IP=self.ip,
|
2007-06-28 18:09:54 -05:00
|
|
|
PASSWORD=self.kdc_password,
|
|
|
|
SUFFIX=self.suffix,
|
2007-08-01 14:06:45 -05:00
|
|
|
DOMAIN=self.domain,
|
|
|
|
HOST=self.host,
|
2011-01-28 14:45:19 -06:00
|
|
|
SERVER_ID=dsinstance.realm_to_serverid(self.realm),
|
2007-08-01 14:06:45 -05:00
|
|
|
REALM=self.realm)
|
2007-06-28 18:09:54 -05:00
|
|
|
|
0000-12-31 18:09:24 -05:50
|
|
|
def __configure_sasl_mappings(self):
|
2007-11-19 18:34:10 -06:00
|
|
|
# we need to remove any existing SASL mappings in the directory as otherwise they
|
2010-12-20 20:19:36 -06:00
|
|
|
# they may conflict.
|
0000-12-31 18:09:24 -05:50
|
|
|
|
2007-11-19 18:34:10 -06:00
|
|
|
try:
|
2011-01-05 06:46:30 -06:00
|
|
|
res = self.admin_conn.search_s("cn=mapping,cn=sasl,cn=config",
|
2010-12-20 20:19:36 -06:00
|
|
|
ldap.SCOPE_ONELEVEL,
|
|
|
|
"(objectclass=nsSaslMapping)")
|
|
|
|
for r in res:
|
|
|
|
try:
|
2011-01-05 06:46:30 -06:00
|
|
|
self.admin_conn.delete_s(r.dn)
|
2010-12-20 20:19:36 -06:00
|
|
|
except LDAPError, e:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("Error during SASL mapping removal: %s" % str(e))
|
2010-12-20 20:19:36 -06:00
|
|
|
raise e
|
|
|
|
except LDAPError, e:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("Error while enumerating SASL mappings %s" % str(e))
|
2008-06-05 13:41:15 -05:00
|
|
|
raise e
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
entry = ipaldap.Entry("cn=Full Principal,cn=mapping,cn=sasl,cn=config")
|
|
|
|
entry.setValues("objectclass", "top", "nsSaslMapping")
|
|
|
|
entry.setValues("cn", "Full Principal")
|
|
|
|
entry.setValues("nsSaslMapRegexString", '\(.*\)@\(.*\)')
|
|
|
|
entry.setValues("nsSaslMapBaseDNTemplate", self.suffix)
|
|
|
|
entry.setValues("nsSaslMapFilterTemplate", '(krbPrincipalName=\\1@\\2)')
|
|
|
|
|
|
|
|
try:
|
ticket #1870 - subclass SimpleLDAPObject
We use convenience types (classes) in IPA which make working with LDAP
easier and more robust. It would be really nice if the basic python-ldap
library understood our utility types and could accept them as parameters
to the basic ldap functions and/or the basic ldap functions returned our
utility types.
Normally such a requirement would trivially be handled in an object-
oriented language (which Python is) by subclassing to extend and modify
the functionality. For some reason we didn't do this with the python-ldap
classes.
python-ldap objects are primarily used in two different places in our
code, ipaserver.ipaldap.py for the IPAdmin class and in
ipaserver/plugins/ldap2.py for the ldap2 class's .conn member.
In IPAdmin we use a IPA utility class called Entry to make it easier to
use the results returned by LDAP. The IPAdmin class is derived from
python-ldap.SimpleLDAPObject. But for some reason when we added the
support for the use of the Entry class in SimpleLDAPObject we didn't
subclass SimpleLDAPObject and extend it for use with the Entry class as
would be the normal expected methodology in an object-oriented language,
rather we used an obscure feature of the Python language to override all
methods of the SimpleLDAPObject class by wrapping those class methods in
another function call. The reason why this isn't a good approach is:
* It violates object-oriented methodology.
* Other classes cannot be derived and inherit the customization (because
the method wrapping occurs in a class instance, not within the class
type).
* It's non-obvious and obscure
* It's inefficient.
Here is a summary of what the code was doing:
It iterated over every member of the SimpleLDAPObject class and if it was
callable it wrapped the method. The wrapper function tested the name of
the method being wrapped, if it was one of a handful of methods we wanted
to customize we modified a parameter and called the original method. If
the method wasn't of interest to use we still wrapped the method.
It was inefficient because every non-customized method (the majority)
executed a function call for the wrapper, the wrapper during run-time used
logic to determine if the method was being overridden and then called the
original method. So every call to ldap was doing extra function calls and
logic processing which for the majority of cases produced nothing useful
(and was non-obvious from brief code reading some methods were being
overridden).
Object-orientated languages have support built in for calling the right
method for a given class object that do not involve extra function call
overhead to realize customized class behaviour. Also when programmers look
for customized class behaviour they look for derived classes. They might
also want to utilize the customized class as the base class for their use.
Also the wrapper logic was fragile, it did things like: if the method name
begins with "add" I'll unconditionally modify the first and second
argument. It would be some much cleaner if the "add", "add_s", etc.
methods were overridden in a subclass where the logic could be seen and
where it would apply to only the explicit functions and parameters being
overridden.
Also we would really benefit if there were classes which could be used as
a base class which had specific ldap customization.
At the moment our ldap customization needs are:
1) Support DN objects being passed to ldap operations
2) Support Entry & Entity objects being passed into and returned from
ldap operations.
We want to subclass the ldap SimpleLDAPObject class, that is the base
ldap class with all the ldap methods we're using. IPASimpleLDAPObject
class would subclass SimpleLDAPObject class which knows about DN
objects (and possilby other IPA specific types that are universally
used in IPA). Then IPAEntrySimpleLDAPObject would subclass
IPASimpleLDAPObject which knows about Entry objects.
The reason for the suggested class hierarchy is because DN objects will be
used whenever we talk to LDAP (in the future we may want to add other IPA
specific classes which will always be used). We don't add Entry support to
the the IPASimpleLDAPObject class because Entry objects are (currently)
only used in IPAdmin.
What this patch does is:
* Introduce IPASimpleLDAPObject derived from
SimpleLDAPObject. IPASimpleLDAPObject is DN object aware.
* Introduce IPAEntryLDAPObject derived from
IPASimpleLDAPObject. IPAEntryLDAPObject is Entry object aware.
* Derive IPAdmin from IPAEntryLDAPObject and remove the funky method
wrapping from IPAdmin.
* Code which called add_s() with an Entry or Entity object now calls
addEntry(). addEntry() always existed, it just wasn't always
used. add_s() had been modified to accept Entry or Entity object
(why didn't we just call addEntry()?). The add*() ldap routine in
IPAEntryLDAPObject have been subclassed to accept Entry and Entity
objects, but that should proably be removed in the future and just
use addEntry().
* Replace the call to ldap.initialize() in ldap2.create_connection()
with a class constructor for IPASimpleLDAPObject. The
ldap.initialize() is a convenience function in python-ldap, but it
always returns a SimpleLDAPObject created via the SimpleLDAPObject
constructor, thus ldap.initialize() did not allow subclassing, yet
has no particular ease-of-use advantage thus we better off using the
obvious class constructor mechanism.
* Fix the use of _handle_errors(), it's not necessary to construct an
empty dict to pass to it.
If we follow the standard class derivation pattern for ldap we can make us
of our own ldap utilities in a far easier, cleaner and more efficient
manner.
2011-09-26 16:33:32 -05:00
|
|
|
self.admin_conn.addEntry(entry)
|
0000-12-31 18:09:24 -05:50
|
|
|
except ldap.ALREADY_EXISTS:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("failed to add Full Principal Sasl mapping")
|
0000-12-31 18:09:24 -05:50
|
|
|
raise e
|
|
|
|
|
|
|
|
entry = ipaldap.Entry("cn=Name Only,cn=mapping,cn=sasl,cn=config")
|
|
|
|
entry.setValues("objectclass", "top", "nsSaslMapping")
|
|
|
|
entry.setValues("cn", "Name Only")
|
2009-09-29 11:41:20 -05:00
|
|
|
entry.setValues("nsSaslMapRegexString", '^[^:@]+$')
|
0000-12-31 18:09:24 -05:50
|
|
|
entry.setValues("nsSaslMapBaseDNTemplate", self.suffix)
|
2009-09-29 11:41:20 -05:00
|
|
|
entry.setValues("nsSaslMapFilterTemplate", '(krbPrincipalName=&@%s)' % self.realm)
|
0000-12-31 18:09:24 -05:50
|
|
|
|
|
|
|
try:
|
ticket #1870 - subclass SimpleLDAPObject
We use convenience types (classes) in IPA which make working with LDAP
easier and more robust. It would be really nice if the basic python-ldap
library understood our utility types and could accept them as parameters
to the basic ldap functions and/or the basic ldap functions returned our
utility types.
Normally such a requirement would trivially be handled in an object-
oriented language (which Python is) by subclassing to extend and modify
the functionality. For some reason we didn't do this with the python-ldap
classes.
python-ldap objects are primarily used in two different places in our
code, ipaserver.ipaldap.py for the IPAdmin class and in
ipaserver/plugins/ldap2.py for the ldap2 class's .conn member.
In IPAdmin we use a IPA utility class called Entry to make it easier to
use the results returned by LDAP. The IPAdmin class is derived from
python-ldap.SimpleLDAPObject. But for some reason when we added the
support for the use of the Entry class in SimpleLDAPObject we didn't
subclass SimpleLDAPObject and extend it for use with the Entry class as
would be the normal expected methodology in an object-oriented language,
rather we used an obscure feature of the Python language to override all
methods of the SimpleLDAPObject class by wrapping those class methods in
another function call. The reason why this isn't a good approach is:
* It violates object-oriented methodology.
* Other classes cannot be derived and inherit the customization (because
the method wrapping occurs in a class instance, not within the class
type).
* It's non-obvious and obscure
* It's inefficient.
Here is a summary of what the code was doing:
It iterated over every member of the SimpleLDAPObject class and if it was
callable it wrapped the method. The wrapper function tested the name of
the method being wrapped, if it was one of a handful of methods we wanted
to customize we modified a parameter and called the original method. If
the method wasn't of interest to use we still wrapped the method.
It was inefficient because every non-customized method (the majority)
executed a function call for the wrapper, the wrapper during run-time used
logic to determine if the method was being overridden and then called the
original method. So every call to ldap was doing extra function calls and
logic processing which for the majority of cases produced nothing useful
(and was non-obvious from brief code reading some methods were being
overridden).
Object-orientated languages have support built in for calling the right
method for a given class object that do not involve extra function call
overhead to realize customized class behaviour. Also when programmers look
for customized class behaviour they look for derived classes. They might
also want to utilize the customized class as the base class for their use.
Also the wrapper logic was fragile, it did things like: if the method name
begins with "add" I'll unconditionally modify the first and second
argument. It would be some much cleaner if the "add", "add_s", etc.
methods were overridden in a subclass where the logic could be seen and
where it would apply to only the explicit functions and parameters being
overridden.
Also we would really benefit if there were classes which could be used as
a base class which had specific ldap customization.
At the moment our ldap customization needs are:
1) Support DN objects being passed to ldap operations
2) Support Entry & Entity objects being passed into and returned from
ldap operations.
We want to subclass the ldap SimpleLDAPObject class, that is the base
ldap class with all the ldap methods we're using. IPASimpleLDAPObject
class would subclass SimpleLDAPObject class which knows about DN
objects (and possilby other IPA specific types that are universally
used in IPA). Then IPAEntrySimpleLDAPObject would subclass
IPASimpleLDAPObject which knows about Entry objects.
The reason for the suggested class hierarchy is because DN objects will be
used whenever we talk to LDAP (in the future we may want to add other IPA
specific classes which will always be used). We don't add Entry support to
the the IPASimpleLDAPObject class because Entry objects are (currently)
only used in IPAdmin.
What this patch does is:
* Introduce IPASimpleLDAPObject derived from
SimpleLDAPObject. IPASimpleLDAPObject is DN object aware.
* Introduce IPAEntryLDAPObject derived from
IPASimpleLDAPObject. IPAEntryLDAPObject is Entry object aware.
* Derive IPAdmin from IPAEntryLDAPObject and remove the funky method
wrapping from IPAdmin.
* Code which called add_s() with an Entry or Entity object now calls
addEntry(). addEntry() always existed, it just wasn't always
used. add_s() had been modified to accept Entry or Entity object
(why didn't we just call addEntry()?). The add*() ldap routine in
IPAEntryLDAPObject have been subclassed to accept Entry and Entity
objects, but that should proably be removed in the future and just
use addEntry().
* Replace the call to ldap.initialize() in ldap2.create_connection()
with a class constructor for IPASimpleLDAPObject. The
ldap.initialize() is a convenience function in python-ldap, but it
always returns a SimpleLDAPObject created via the SimpleLDAPObject
constructor, thus ldap.initialize() did not allow subclassing, yet
has no particular ease-of-use advantage thus we better off using the
obvious class constructor mechanism.
* Fix the use of _handle_errors(), it's not necessary to construct an
empty dict to pass to it.
If we follow the standard class derivation pattern for ldap we can make us
of our own ldap utilities in a far easier, cleaner and more efficient
manner.
2011-09-26 16:33:32 -05:00
|
|
|
self.admin_conn.addEntry(entry)
|
0000-12-31 18:09:24 -05:50
|
|
|
except ldap.ALREADY_EXISTS:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("failed to add Name Only Sasl mapping")
|
0000-12-31 18:09:24 -05:50
|
|
|
raise e
|
|
|
|
|
2011-06-08 16:21:23 -05:00
|
|
|
def __add_krb_container(self):
|
2009-05-12 05:51:46 -05:00
|
|
|
self._ldap_mod("kerberos.ldif", self.sub_dict)
|
2007-06-28 18:09:54 -05:00
|
|
|
|
2007-12-13 03:31:28 -06:00
|
|
|
def __add_default_acis(self):
|
2009-05-12 05:51:46 -05:00
|
|
|
self._ldap_mod("default-aci.ldif", self.sub_dict)
|
2007-12-13 03:31:28 -06:00
|
|
|
|
2011-08-30 09:32:40 -05:00
|
|
|
def __template_file(self, path, chmod=0644):
|
2008-01-11 04:36:25 -06:00
|
|
|
template = os.path.join(ipautil.SHARE_DIR, os.path.basename(path) + ".template")
|
|
|
|
conf = ipautil.template_file(template, self.sub_dict)
|
2008-03-27 18:01:38 -05:00
|
|
|
self.fstore.backup_file(path)
|
2008-01-11 04:36:25 -06:00
|
|
|
fd = open(path, "w+")
|
|
|
|
fd.write(conf)
|
|
|
|
fd.close()
|
2011-08-30 09:32:40 -05:00
|
|
|
if chmod is not None:
|
|
|
|
os.chmod(path, chmod)
|
2008-01-11 04:36:25 -06:00
|
|
|
|
2011-06-08 16:21:23 -05:00
|
|
|
def __init_ipa_kdb(self):
|
|
|
|
#populate the directory with the realm structure
|
2011-10-11 11:44:33 -05:00
|
|
|
args = ["kdb5_util", "create", "-s",
|
2011-06-08 16:21:23 -05:00
|
|
|
"-r", self.realm,
|
|
|
|
"-x", "ipa-setup-override-restrictions"]
|
2011-10-11 11:44:33 -05:00
|
|
|
dialogue = (
|
|
|
|
# Enter KDC database master key:
|
|
|
|
self.master_password + '\n',
|
|
|
|
# Re-enter KDC database master key to verify:
|
|
|
|
self.master_password + '\n',
|
|
|
|
)
|
2011-06-08 16:21:23 -05:00
|
|
|
try:
|
2011-10-11 11:44:33 -05:00
|
|
|
ipautil.run(args, nolog=(self.master_password), stdin=''.join(dialogue))
|
2011-06-08 16:21:23 -05:00
|
|
|
except ipautil.CalledProcessError, e:
|
|
|
|
print "Failed to initialize the realm container"
|
|
|
|
|
|
|
|
def __configure_instance(self):
|
2011-08-30 09:32:40 -05:00
|
|
|
self.__template_file("/var/kerberos/krb5kdc/kdc.conf", chmod=None)
|
2008-01-11 04:36:25 -06:00
|
|
|
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")
|
2007-10-29 11:00:48 -05:00
|
|
|
|
2010-11-15 16:06:32 -06:00
|
|
|
MIN_KRB5KDC_WITH_WORKERS = "1.9"
|
|
|
|
cpus = os.sysconf('SC_NPROCESSORS_ONLN')
|
|
|
|
workers = False
|
2010-11-22 13:52:09 -06:00
|
|
|
(stdout, stderr, rc) = ipautil.run(['klist', '-V'], raiseonerr=False)
|
2010-11-15 16:06:32 -06:00
|
|
|
if rc == 0:
|
|
|
|
verstr = stdout.split()[-1]
|
|
|
|
ver = version.LooseVersion(verstr)
|
|
|
|
min = version.LooseVersion(MIN_KRB5KDC_WITH_WORKERS)
|
|
|
|
if ver >= min:
|
|
|
|
workers = True
|
2011-10-12 06:18:21 -05:00
|
|
|
# Write down config file
|
|
|
|
# We write realm and also number of workers (for multi-CPU systems)
|
|
|
|
replacevars = {'KRB5REALM':self.realm}
|
|
|
|
appendvars = {}
|
2010-11-15 16:06:32 -06:00
|
|
|
if workers and cpus > 1:
|
2011-10-25 10:41:32 -05:00
|
|
|
appendvars = {'KRB5KDC_ARGS': "'-w %s'" % str(cpus)}
|
2011-10-12 06:18:21 -05:00
|
|
|
ipautil.backup_config_and_replace_variables(self.fstore, "/etc/sysconfig/krb5kdc",
|
|
|
|
replacevars=replacevars,
|
|
|
|
appendvars=appendvars)
|
|
|
|
ipaservices.restore_context("/etc/sysconfig/krb5kdc")
|
2010-11-15 16:06:32 -06:00
|
|
|
|
0000-12-31 18:09:24 -05:50
|
|
|
def __write_stash_from_ds(self):
|
2007-10-03 16:37:13 -05:00
|
|
|
try:
|
2011-06-09 11:42:03 -05:00
|
|
|
entry = self.admin_conn.getEntry(self.get_realm_suffix(),
|
|
|
|
ldap.SCOPE_SUBTREE)
|
2009-08-11 16:08:09 -05:00
|
|
|
except errors.NotFound, e:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("Could not find master key in DS")
|
0000-12-31 18:09:24 -05:50
|
|
|
raise e
|
|
|
|
|
|
|
|
krbMKey = pyasn1.codec.ber.decoder.decode(entry.krbmkey)
|
|
|
|
keytype = int(krbMKey[0][1][0])
|
|
|
|
keydata = str(krbMKey[0][1][1])
|
|
|
|
|
|
|
|
format = '=hi%ss' % len(keydata)
|
|
|
|
s = struct.pack(format, keytype, len(keydata), keydata)
|
|
|
|
try:
|
|
|
|
fd = open("/var/kerberos/krb5kdc/.k5."+self.realm, "w")
|
|
|
|
fd.write(s)
|
2008-08-19 15:39:33 -05:00
|
|
|
fd.close()
|
0000-12-31 18:09:24 -05:50
|
|
|
except os.error, e:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.critical("failed to write stash file")
|
0000-12-31 18:09:24 -05:50
|
|
|
raise e
|
2007-07-02 14:51:04 -05:00
|
|
|
|
2007-08-15 20:35:35 -05:00
|
|
|
#add the password extop module
|
2007-07-02 14:51:04 -05:00
|
|
|
def __add_pwd_extop_module(self):
|
2009-05-12 05:51:46 -05:00
|
|
|
self._ldap_mod("pwd-extop-conf.ldif", self.sub_dict)
|
2007-08-01 14:58:52 -05:00
|
|
|
|
2007-08-01 14:06:45 -05:00
|
|
|
def __create_ds_keytab(self):
|
2007-12-18 12:03:34 -06:00
|
|
|
ldap_principal = "ldap/" + self.fqdn + "@" + self.realm
|
|
|
|
installutils.kadmin_addprinc(ldap_principal)
|
2009-12-07 22:17:00 -06:00
|
|
|
self.move_service(ldap_principal)
|
2008-01-14 11:43:26 -06:00
|
|
|
|
2008-03-27 18:01:38 -05:00
|
|
|
self.fstore.backup_file("/etc/dirsrv/ds.keytab")
|
2007-12-18 12:03:34 -06:00
|
|
|
installutils.create_keytab("/etc/dirsrv/ds.keytab", ldap_principal)
|
2007-08-31 17:40:01 -05:00
|
|
|
|
2011-10-10 07:25:15 -05:00
|
|
|
update_key_val_in_file("/etc/sysconfig/dirsrv", "KRB5_KTNAME", "/etc/dirsrv/ds.keytab")
|
On 10/4/07, Rob Crittenden <rcritten@redhat.com> wrote:
> William Jon McCann wrote:
> > Hi,
> >
> > After playing with the install (repeatedly) I ended up with a lot of
> > duplicate values in:
> > /etc/sysconfig/dirsrv
> > /etc/sysconfig/ipa-kpasswd
> >
> > Here is a patch that should fix this. It modifies the file "in-place"
> > and removes lines that matching the key (or commented key) and then
> > appends the new key=value.
> >
> > Jon
>
> Cool, I've wanted to fix this for a while (and recently aborted a switch
> from open with "a" to "w").
>
> What happens if the file doesn't exist yet? Do we need to wrap the
> fileinput loop in either a try/except or just look to see if the file
> exists first (my vote)?
>
> Something like:
>
> def update_key_val_in_file(filename, key, val):
> if os.path.exists(filename):
> pattern = "^[\s#]*%s\s*=" % re.escape(key)
> p = re.compile(pattern)
> for line in fileinput.input(filename, inplace=1):
> if not p.search(line):
> sys.stdout.write(line)
> fileinput.close()
> f = open(filename, "a")
> f.write("%s=%s\n" % (key, val))
> f.close()
Good point. In genera,l I prefer doing a try because it is a little
less racy but in this case it doesn't make a difference.
Updated patch attached.
Thanks,
Jon
0000-12-31 18:09:24 -05:50
|
|
|
update_key_val_in_file("/etc/sysconfig/dirsrv", "export KRB5_KTNAME", "/etc/dirsrv/ds.keytab")
|
2011-01-28 14:45:19 -06:00
|
|
|
pent = pwd.getpwnam(dsinstance.DS_USER)
|
2007-08-30 14:31:27 -05:00
|
|
|
os.chown("/etc/dirsrv/ds.keytab", pent.pw_uid, pent.pw_gid)
|
2007-08-08 21:19:03 -05:00
|
|
|
|
2007-12-13 15:44:57 -06:00
|
|
|
def __create_host_keytab(self):
|
2007-12-18 12:03:34 -06:00
|
|
|
host_principal = "host/" + self.fqdn + "@" + self.realm
|
|
|
|
installutils.kadmin_addprinc(host_principal)
|
2008-01-14 11:43:26 -06:00
|
|
|
|
2008-03-27 18:01:38 -05:00
|
|
|
self.fstore.backup_file("/etc/krb5.keytab")
|
2007-12-18 12:03:34 -06:00
|
|
|
installutils.create_keytab("/etc/krb5.keytab", host_principal)
|
2007-12-13 15:44:57 -06:00
|
|
|
|
|
|
|
# Make sure access is strictly reserved to root only for now
|
|
|
|
os.chown("/etc/krb5.keytab", 0, 0)
|
|
|
|
os.chmod("/etc/krb5.keytab", 0600)
|
|
|
|
|
2009-12-07 22:17:00 -06:00
|
|
|
self.move_service_to_host(host_principal)
|
|
|
|
|
2010-10-29 15:23:21 -05:00
|
|
|
def __setup_pkinit(self):
|
|
|
|
if self.self_signed_ca:
|
2010-12-08 15:35:12 -06:00
|
|
|
ca_db = certs.CertDB(self.realm,
|
2010-10-29 15:23:21 -05:00
|
|
|
subject_base=self.subject_base)
|
|
|
|
else:
|
2010-12-08 15:35:12 -06:00
|
|
|
ca_db = certs.CertDB(self.realm, host_name=self.fqdn,
|
2010-10-29 15:23:21 -05:00
|
|
|
subject_base=self.subject_base)
|
|
|
|
|
2010-11-03 17:17:36 -05:00
|
|
|
if self.pkcs12_info:
|
|
|
|
ca_db.install_pem_from_p12(self.pkcs12_info[0],
|
|
|
|
self.pkcs12_info[1],
|
|
|
|
"/var/kerberos/krb5kdc/kdc.pem")
|
2010-10-29 15:23:21 -05:00
|
|
|
else:
|
|
|
|
if self.self_signed_ca:
|
|
|
|
ca_db.create_kdc_cert("KDC-Cert", self.fqdn,
|
|
|
|
"/var/kerberos/krb5kdc")
|
|
|
|
else:
|
2010-11-03 17:17:36 -05:00
|
|
|
raise RuntimeError("PKI not supported yet\n")
|
2010-10-29 15:23:21 -05:00
|
|
|
|
|
|
|
# Finally copy the cacert in the krb directory so we don't
|
|
|
|
# have any selinux issues with the file context
|
2010-12-08 15:35:12 -06:00
|
|
|
shutil.copyfile("/etc/ipa/ca.crt", "/var/kerberos/krb5kdc/cacert.pem")
|
2010-10-29 15:23:21 -05:00
|
|
|
|
2010-11-02 17:02:59 -05:00
|
|
|
def __add_anonymous_pkinit_principal(self):
|
|
|
|
princ = "WELLKNOWN/ANONYMOUS"
|
|
|
|
princ_realm = "%s@%s" % (princ, self.realm)
|
|
|
|
|
|
|
|
# Create the special anonymous principal
|
|
|
|
installutils.kadmin_addprinc(princ_realm)
|
2011-06-09 11:42:03 -05:00
|
|
|
dn = "krbprincipalname=%s,%s" % (princ_realm, self.get_realm_suffix())
|
2011-01-05 06:46:30 -06:00
|
|
|
self.admin_conn.inactivateEntry(dn, False)
|
2010-11-02 17:02:59 -05:00
|
|
|
|
2011-01-11 09:27:48 -06:00
|
|
|
def __convert_to_gssapi_replication(self):
|
|
|
|
repl = replication.ReplicationManager(self.realm,
|
|
|
|
self.fqdn,
|
|
|
|
self.dm_password)
|
|
|
|
repl.convert_to_gssapi_replication(self.master_fqdn,
|
|
|
|
r_binddn="cn=Directory Manager",
|
|
|
|
r_bindpw=self.dm_password)
|
|
|
|
|
2008-01-11 05:57:36 -06:00
|
|
|
def uninstall(self):
|
2010-05-03 14:21:51 -05:00
|
|
|
if self.is_configured():
|
|
|
|
self.print_msg("Unconfiguring %s" % self.service_name)
|
2008-01-22 05:58:06 -06:00
|
|
|
|
2008-01-11 05:57:36 -06:00
|
|
|
running = self.restore_state("running")
|
|
|
|
enabled = self.restore_state("enabled")
|
2007-08-06 09:51:23 -05:00
|
|
|
|
2008-05-13 15:29:01 -05:00
|
|
|
try:
|
2008-01-11 05:57:36 -06:00
|
|
|
self.stop()
|
2008-05-13 15:29:01 -05:00
|
|
|
except:
|
|
|
|
pass
|
2008-01-11 05:57:36 -06:00
|
|
|
|
2011-08-31 10:39:53 -05:00
|
|
|
for f in ["/var/kerberos/krb5kdc/kdc.conf", "/etc/krb5.conf"]:
|
2008-03-27 18:01:38 -05:00
|
|
|
try:
|
|
|
|
self.fstore.restore_file(f)
|
|
|
|
except ValueError, error:
|
2011-11-15 13:39:31 -06:00
|
|
|
root_logger.debug(error)
|
2008-03-27 18:01:38 -05:00
|
|
|
pass
|
|
|
|
|
2008-01-11 05:57:36 -06:00
|
|
|
if not enabled is None and not enabled:
|
2011-09-13 02:47:13 -05:00
|
|
|
self.disable()
|
2008-01-11 05:57:36 -06:00
|
|
|
|
|
|
|
if not running is None and running:
|
|
|
|
self.start()
|
2010-05-03 14:21:51 -05:00
|
|
|
|
|
|
|
self.kpasswd = KpasswdInstance()
|
|
|
|
self.kpasswd.uninstall()
|