From 04e9056ec2b6e0360f3f3545fd638ecc17aaad2c Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 3 May 2010 15:21:51 -0400 Subject: Make the installer/uninstaller more aware of its state We have had a state file for quite some time that is used to return the system to its pre-install state. We can use that to determine what has been configured. This patch: - uses the state file to determine if dogtag was installed - prevents someone from trying to re-install an installed server - displays some output when uninstalling - re-arranges the ipa_kpasswd installation so the state is properly saved - removes pkiuser if it was added by the installer - fetches and installs the CA on both masters and clients --- install/tools/ipa-server-install | 14 ++++++-------- ipa-client/ipa-install/ipa-client-install | 7 +++---- ipapython/sysrestore.py | 11 +++++++++++ ipaserver/install/bindinstance.py | 3 +++ ipaserver/install/cainstance.py | 19 +++++++++++++++++++ ipaserver/install/dsinstance.py | 3 +++ ipaserver/install/httpinstance.py | 3 +++ ipaserver/install/krbinstance.py | 11 ++++++++--- ipaserver/install/ntpinstance.py | 3 +++ ipaserver/install/service.py | 6 ++++++ 10 files changed, 65 insertions(+), 15 deletions(-) diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 149cdd78..4fd520a6 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -375,7 +375,7 @@ def check_dirsrv(unattended): print "\t636" sys.exit(1) -def uninstall(ca=False, dm_password=None): +def uninstall(dm_password=None): if dm_password: api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dm_password) @@ -387,13 +387,9 @@ def uninstall(ca=False, dm_password=None): pass ntpinstance.NTPInstance(fstore).uninstall() - if ca: - try: - from ipaserver.install import cainstance - except ImportError: - print >> sys.stderr, "Import failed: %s" % sys.exc_value - sys.exit(1) + if cainstance.CADSInstance().is_configured(): cainstance.CADSInstance().uninstall() + if cainstance.CAInstance().is_configured(): cainstance.CAInstance().uninstall() bindinstance.BindInstance(fstore).uninstall() httpinstance.HTTPInstance(fstore).uninstall() @@ -455,6 +451,8 @@ def main(): else: standard_logging_setup("/var/log/ipaserver-install.log", options.debug) print "\nThe log file for this installation can be found in /var/log/ipaserver-install.log" + if dsinstance.DsInstance().is_configured() or cainstance.CADSInstance().is_configured(): + sys.exit("IPA server is already configured on this system.") global fstore fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore') @@ -496,7 +494,7 @@ def main(): sys.exit("\nUnable to connect to LDAP server %s" % api.env.host) conn.disconnect() - return uninstall(not certs.ipa_self_signed(), dm_password) + return uninstall(dm_password) # This will override any settings passed in on the cmdline options._update_loose(read_cache()) diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install index 0be4a4c3..4b7a22c2 100755 --- a/ipa-client/ipa-install/ipa-client-install +++ b/ipa-client/ipa-install/ipa-client-install @@ -535,10 +535,9 @@ def main(): print "Configured /etc/ldap.conf" # Get the CA certificate - if not options.on_master: - run(["/usr/bin/wget", "-O", "/etc/ipa/ca.crt", "http://%s/ipa/config/ca.crt" % cli_server]) - # Add the CA to the default NSS database and trust it - run(["/usr/bin/certutil", "-A", "-d", "/etc/pki/nssdb", "-n", "IPA CA", "-t", "CT,C,C", "-a", "-i", "/etc/ipa/ca.crt"]) + run(["/usr/bin/wget", "-O", "/etc/ipa/ca.crt", "http://%s/ipa/config/ca.crt" % cli_server]) + # Add the CA to the default NSS database and trust it + run(["/usr/bin/certutil", "-A", "-d", "/etc/pki/nssdb", "-n", "IPA CA", "-t", "CT,C,C", "-a", "-i", "/etc/ipa/ca.crt"]) if not options.on_master: configure_certmonger(fstore, subject_base, cli_realm, options) diff --git a/ipapython/sysrestore.py b/ipapython/sysrestore.py index ddc3ee05..d3c7a501 100644 --- a/ipapython/sysrestore.py +++ b/ipapython/sysrestore.py @@ -314,3 +314,14 @@ class StateFile: self.save() return value + + def has_state(self, module): + """Return True or False if there is any state stored for @module. + + Can be used to determine if a service is configured. + """ + + if self.modules.has_key(module): + return True + else: + return False diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index d584e0af..b57fc9f0 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -377,6 +377,9 @@ class BindInstance(service.Service): resolv_fd.close() def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring %s" % self.service_name) + running = self.restore_state("running") enabled = self.restore_state("enabled") diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index bb7e00e2..9e55333d 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -336,6 +336,9 @@ class CADSInstance(service.Service): logging.critical("Failed to restart the directory server. See the installation log for details.") def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring CA directory server") + running = self.restore_state("running") enabled = self.restore_state("enabled") serverid = self.restore_state("serverid") @@ -351,6 +354,7 @@ class CADSInstance(service.Service): if not serverid is None: dsinstance.erase_ds_instance_data(serverid) + self.service_name="pkids" ds_user = self.restore_state("user") user_exists = self.restore_state("user_exists") @@ -1028,6 +1032,13 @@ class CAInstance(service.Service): self.__restart_instance() def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring CA") + + enabled = self.restore_state("enabled") + if not enabled is None and not enabled: + self.chkconfig_off() + try: ipautil.run(["/usr/bin/pkiremove", "-pki_instance_root=/var/lib", "-pki_instance_name=%s" % PKI_INSTANCE_NAME, "--force"]) @@ -1039,6 +1050,14 @@ class CAInstance(service.Service): except ipautil.CalledProcessError, e: pass + pki_user = self.restore_state("user") + user_exists = self.restore_state("user_exists") + if not pki_user is None and not user_exists is None and not user_exists: + try: + ipautil.run(["/usr/sbin/userdel", pki_user]) + except ipautil.CalledProcessError, e: + logging.critical("failed to delete user %s" % e) + if __name__ == "__main__": installutils.standard_logging_setup("install.log", False) cs = CADSInstance() diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 61887dde..3987f08e 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -430,6 +430,9 @@ class DsInstance(service.Service): logging.debug("Unable to set admin password %s" % e) def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring directory server") + running = self.restore_state("running") enabled = self.restore_state("enabled") diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 3ff5cf8a..48a908f1 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -242,6 +242,9 @@ class HTTPInstance(service.Service): os.chmod("/usr/share/ipa/html/ca.crt", 0444) def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring web server") + running = self.restore_state("running") enabled = self.restore_state("enabled") diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index 71aeeb20..23ed1001 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -85,8 +85,6 @@ class KrbInstance(service.Service): self.kdc_password = None self.sub_dict = None - self.kpasswd = KpasswdInstance() - if fstore: self.fstore = fstore else: @@ -181,6 +179,8 @@ class KrbInstance(service.Service): self.start_creation("Configuring Kerberos KDC") + self.kpasswd = KpasswdInstance() + self.kpasswd.create_instance() def create_replica(self, ds_user, realm_name, host_name, domain_name, admin_password, ldap_passwd_filename, kpasswd_filename): @@ -200,6 +200,7 @@ class KrbInstance(service.Service): self.start_creation("Configuring Kerberos KDC") + self.kpasswd = KpasswdInstance() self.kpasswd.create_instance() def __copy_ldap_passwd(self, filename): @@ -473,7 +474,8 @@ class KrbInstance(service.Service): update_key_val_in_file("/etc/sysconfig/ipa_kpasswd", "export KRB5_KTNAME", "/var/kerberos/krb5kdc/kpasswd.keytab") def uninstall(self): - self.kpasswd.uninstall() + if self.is_configured(): + self.print_msg("Unconfiguring %s" % self.service_name) running = self.restore_state("running") enabled = self.restore_state("enabled") @@ -495,3 +497,6 @@ class KrbInstance(service.Service): if not running is None and running: self.start() + + self.kpasswd = KpasswdInstance() + self.kpasswd.uninstall() diff --git a/ipaserver/install/ntpinstance.py b/ipaserver/install/ntpinstance.py index 2c53b561..320522de 100644 --- a/ipaserver/install/ntpinstance.py +++ b/ipaserver/install/ntpinstance.py @@ -87,6 +87,9 @@ class NTPInstance(service.Service): self.start_creation("Configuring ntpd") def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring %s" % self.service_name) + running = self.restore_state("running") enabled = self.restore_state("enabled") diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index d9db9ba4..4958721e 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -186,6 +186,9 @@ class Service: logging.critical("Could not add certificate to service %s entry: %s" % (self.principal, str(e))) conn.unbind() + def is_configured(self): + return self.sstore.has_state(self.service_name) + def set_output(self, fd): self.output_fd = fd @@ -257,6 +260,9 @@ class SimpleServiceInstance(Service): self.chkconfig_on() def uninstall(self): + if self.is_configured(): + self.print_msg("Unconfiguring %s" % self.service_name) + running = self.restore_state("running") enabled = not self.restore_state("enabled") -- cgit