[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Freeipa-devel] [PATCH] more robust installation error handling



This needs more work but it is a first crack at trying to catch more error conditions during installation. What it currently lacks is completely bailing out, offering the user a choice to continue and/or doing a rollback.

I also didn't add any code to exit out if an existing DS is found. Not sure if we want to do that or not.

I also incorporated most of the patch to handle when SELinux is disabled from Jon McCann. I just do the selinux check slightly differently.

I also noticed an error when I had old service keytabs and included something to handle SASL/GSSAPI authentication failures when getting a connection.

rob
# HG changeset patch
# User rcritten redhat com
# Date 1191440326 14400
# Node ID 402790fcade32008b44166bda29574b9d7fdd59d
# Parent  6e4cbcfb88f6bbfc347ac97bf5cf08f65cd86ddc
Try to catch more error conditions during installation
Incorporated patch to handle when SELinux is diabled from Jon McCann
Handle SASL/GSSAPI authentication failures when getting a connection

diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-python/ipaerror.py
--- a/ipa-python/ipaerror.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-python/ipaerror.py	Wed Oct 03 15:38:46 2007 -0400
@@ -144,3 +144,8 @@ CONNECTION_NO_CCACHE = gen_error_code(
         CONNECTION_CATEGORY,
         0x0002,
         "No Kerberos credentials cache is available. Connection cannot be made.")
+
+CONNECTION_GSSAPI_CREDENTIALS = gen_error_code(
+        CONNECTION_CATEGORY,
+        0x0003,
+        "GSSAPI Authorization error")
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-python/ipautil.py
--- a/ipa-python/ipautil.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-python/ipautil.py	Wed Oct 03 15:38:46 2007 -0400
@@ -62,7 +62,7 @@ def run(args, stdin=None):
     logging.info(stderr)
 
     if p.returncode != 0:
-        raise subprocess.CalledProcessError(p.returncode, args[0])
+        raise subprocess.CalledProcessError(p.returncode, ' '.join(args))
 
 def file_exists(filename):
     try:
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-server/ipa-install/ipa-server-install
--- a/ipa-server/ipa-install/ipa-server-install	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-server/ipa-install/ipa-server-install	Wed Oct 03 15:38:46 2007 -0400
@@ -29,10 +29,12 @@ import sys
 import sys
 sys.path.append("/usr/share/ipa")
 
+import os
 import socket
 import logging
 import pwd
 import getpass
+import subprocess
 from optparse import OptionParser
 import ipaserver.dsinstance
 import ipaserver.krbinstance
@@ -378,32 +380,46 @@ def main():
     ds.restart()
     krb.restart()
 
-    # Allow apache to connect to the turbogears web gui
-    run(["/usr/sbin/setsebool", "-P", "httpd_can_network_connect", "true"])
-
-    # Start the web gui
-    run(["/sbin/service", "ipa-webgui", "start"])
-
-    # Set the web gui to start on boot
-    run(["/sbin/chkconfig", "ipa-webgui", "on"])
-
-    # Restart apache
-    run(["/sbin/service", "httpd", "restart"])
-
-    # Set apache to start on boot
-    run(["/sbin/chkconfig", "httpd", "on"])
-
-    # Set fedora-ds to start on boot
-    run(["/sbin/chkconfig", "dirsrv", "on"])
-
-    # Set the KDC to start on boot
-    run(["/sbin/chkconfig", "krb5kdc", "on"])
-
-    # Set the Kpasswd to start on boot
-    run(["/sbin/chkconfig", "ipa-kpasswd", "on"])
-
-    # Start Kpasswd
-    run(["/sbin/service", "ipa-kpasswd", "start"])
+    try:
+        selinux=0
+        try:
+            if (os.path.exists('/usr/sbin/selinuxenabled')):
+                run(["/usr/sbin/selinuxenabled"])
+                selinux=1
+        except subprocess.CalledProcessError, e:
+            # selinuxenabled returns 1 if not enabled
+            pass
+
+        if selinux:
+            # Allow apache to connect to the turbogears web gui
+            run(["/usr/sbin/setsebool", "-P", "httpd_can_network_connect", "true"])
+
+        # Start the web gui
+        run(["/sbin/service", "ipa-webgui", "start"])
+
+        # Set the web gui to start on boot
+        run(["/sbin/chkconfig", "ipa-webgui", "on"])
+
+        # Restart apache
+        run(["/sbin/service", "httpd", "restart"])
+
+        # Set apache to start on boot
+        run(["/sbin/chkconfig", "httpd", "on"])
+
+        # Set fedora-ds to start on boot
+        run(["/sbin/chkconfig", "dirsrv", "on"])
+
+        # Set the KDC to start on boot
+        run(["/sbin/chkconfig", "krb5kdc", "on"])
+
+        # Set the Kpasswd to start on boot
+        run(["/sbin/chkconfig", "ipa-kpasswd", "on"])
+
+        # Start Kpasswd
+        run(["/sbin/service", "ipa-kpasswd", "start"])
+    except subprocess.CalledProcessError, e:
+        print "Installation failed:", e
+        return 1
 
     # Set the admin user kerberos password
     ds.change_admin_password(admin_password)
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-server/ipaserver/bindinstance.py
--- a/ipa-server/ipaserver/bindinstance.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-server/ipaserver/bindinstance.py	Wed Oct 03 15:38:46 2007 -0400
@@ -68,7 +68,10 @@ class BindInstance:
         self.__setup_zone()
         self.__setup_named_conf()
 
-        self.start()
+        try:
+            self.start()
+        except:
+            print "named service failed to start"
 
     def stop(self):
         run(["/sbin/service", "named", "stop"])
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-server/ipaserver/dsinstance.py
--- a/ipa-server/ipaserver/dsinstance.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-server/ipaserver/dsinstance.py	Wed Oct 03 15:38:46 2007 -0400
@@ -91,7 +91,11 @@ class DsInstance:
         self.__add_default_schemas()
         self.__enable_ssl()
         self.__certmap_conf()
-        self.restart()
+        try:
+            self.restart()
+        except:
+            # TODO: roll back here?
+            print "Failed to restart the ds instance"
         self.__add_default_layout()
         self.__create_test_users()
 
@@ -126,8 +130,12 @@ class DsInstance:
 	except KeyError:
             logging.debug("adding ds user %s" % self.ds_user)
             args = ["/usr/sbin/useradd", "-c", "DS System User", "-d", "/var/lib/dirsrv", "-M", "-r", "-s", "/sbin/nologin", self.ds_user]
-            run(args)
-            logging.debug("done adding user")
+            try:
+                run(args)
+                logging.debug("done adding user")
+            except subprocess.CalledProcessError, e:
+                print "Failed to add user", e
+                logging.debug("failed to add user %s" % e)
 
     def __create_instance(self):
         logging.debug("creating ds instance . . . ")
@@ -141,11 +149,19 @@ class DsInstance:
         else:
             args = ["/usr/bin/ds_newinst.pl", inf_fd.name]
             logging.debug("calling ds_newinst.pl")
-        run(args)
-        logging.debug("completed creating ds instance")
+        try:
+            run(args)
+            logging.debug("completed creating ds instance")
+        except subprocess.CalledProcessError, e:
+            print "failed to restart ds instance", e
+            logging.debug("failed to restart ds instance %s" % e)
         logging.debug("restarting ds instance")
-        self.restart()
-        logging.debug("done restarting ds instance")
+        try:
+            self.restart()
+            logging.debug("done restarting ds instance")
+        except subprocess.CalledProcessError, e:
+            print "failed to restart ds instance", e
+            logging.debug("failed to restart ds instance %s" % e)
 
     def __add_default_schemas(self):
         shutil.copyfile(SHARE_DIR + "60kerberos.ldif",
@@ -158,8 +174,12 @@ class DsInstance:
         dirname = self.config_dirname()
         args = ["/usr/share/ipa/ipa-server-setupssl", self.dm_password,
                 dirname, self.host_name]
-        run(args)
-        logging.debug("done configuring ssl for ds instance")
+        try:
+            run(args)
+            logging.debug("done configuring ssl for ds instance")
+        except subprocess.CalledProcessError, e:
+            print "Failed to enable ssl in ds instance", e
+            logging.debug("Failed to configure ssl in ds instance %s" % e)
         
     def __add_default_layout(self):
         txt = template_file(SHARE_DIR + "bootstrap-template.ldif", self.sub_dict)
@@ -167,8 +187,12 @@ class DsInstance:
         logging.debug("adding default ds layout")
         args = ["/usr/bin/ldapmodify", "-xv", "-D", "cn=Directory Manager",
                 "-w", self.dm_password, "-f", inf_fd.name]
-        run(args)
-        logging.debug("done adding default ds layout")
+        try:
+            run(args)
+            logging.debug("done adding default ds layout")
+        except subprocess.CalledProcessError, e:
+            print "Failed to add default ds layout", e
+            logging.debug("Failed to add default ds layout %s" % e)
         
     def __create_test_users(self):
         logging.debug("create test users ldif")
@@ -194,6 +218,10 @@ class DsInstance:
                 "-D", "cn=Directory Manager", "-w", self.dm_password,
                 "-P", dirname+"/cert8.db", "-ZZZ", "-s", password,
                 "uid=admin,cn=sysaccounts,cn=etc,"+self.suffix]
-        run(args)
-        logging.debug("ldappasswd done")
-
+        try:
+            run(args)
+            logging.debug("ldappasswd done")
+        except subprocess.CalledProcessError, e:
+            print "Unable to set admin password", e
+            logging.debug("Unable to set admin password %s" % e)
+
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-server/ipaserver/krbinstance.py
--- a/ipa-server/ipaserver/krbinstance.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-server/ipaserver/krbinstance.py	Wed Oct 03 15:38:46 2007 -0400
@@ -74,7 +74,11 @@ class KrbInstance:
 	self.suffix = realm_to_suffix(self.realm)
         self.kdc_password = generate_kdc_password()
 
-        self.stop()
+        try:
+            self.stop()
+        except:
+            # It could have been not running
+            pass
 
 	self.__configure_kdc_account_password()
 
@@ -94,7 +98,10 @@ class KrbInstance:
 
         self.__add_pwd_extop_module()
 
-        self.start()
+        try:
+            self.start()
+        except:
+            print "krb5kdc service failed to start"
 
     def stop(self):
         run(["/sbin/service", "krb5kdc", "stop"])
@@ -127,13 +134,19 @@ class KrbInstance:
 	#TODO: test that the ldif is ok with any random charcter we may use in the password
         kerberos_txt = template_file(SHARE_DIR + "kerberos.ldif", self.sub_dict)
         kerberos_fd = write_tmp_file(kerberos_txt)
-        ldap_mod(kerberos_fd, "cn=Directory Manager", self.admin_password)
+        try:
+            ldap_mod(kerberos_fd, "cn=Directory Manager", self.admin_password)
+        except subprocess.CalledProcessError, e:
+            print "Failed to load kerberos.ldif", e
         kerberos_fd.close()
 
 	#Change the default ACL to avoid anonimous access to kerberos keys and othe hashes
         aci_txt = template_file(SHARE_DIR + "default-aci.ldif", self.sub_dict)
         aci_fd = write_tmp_file(aci_txt) 
-        ldap_mod(aci_fd, "cn=Directory Manager", self.admin_password)
+        try:
+            ldap_mod(aci_fd, "cn=Directory Manager", self.admin_password)
+        except subprocess.CalledProcessError, e:
+            print "Failed to load default-aci.ldif", e
         aci_fd.close()
 
     def __create_instance(self):
@@ -149,20 +162,33 @@ class KrbInstance:
 
         #populate the directory with the realm structure
         args = ["/usr/kerberos/sbin/kdb5_ldap_util", "-D", "uid=kdc,cn=sysaccounts,cn=etc,"+self.suffix, "-w", self.kdc_password, "create", "-s", "-P", self.master_password, "-r", self.realm, "-subtrees", self.suffix, "-sscope", "sub"]
-        run(args)
+        try:
+            run(args)
+        except subprocess.CalledProcessError, e:
+            print "Failed to populate the realm structure in kerberos", e
 
     #add the password extop module
     def __add_pwd_extop_module(self):
         extop_txt = template_file(SHARE_DIR + "pwd-extop-conf.ldif", self.sub_dict)
         extop_fd = write_tmp_file(extop_txt)
-        ldap_mod(extop_fd, "cn=Directory Manager", self.admin_password)
+        try:
+            ldap_mod(extop_fd, "cn=Directory Manager", self.admin_password)
+        except subprocess.CalledProcessError, e:
+            print "Failed to load pwd-extop-conf.ldif", e
         extop_fd.close()
 
         #add an ACL to let the DS user read the master key
         args = ["/usr/bin/setfacl", "-m", "u:"+self.ds_user+":r", "/var/kerberos/krb5kdc/.k5."+self.realm]
-        run(args)
+        try:
+            run(args)
+        except subprocess.CalledProcessError, e:
+            print "Failed to set the ACL on the master key", e
 
     def __create_ds_keytab(self):
+        try:
+            os.remove("/etc/dirsrv/ds.keytab")
+        except os.OSError:
+            print "Failed to remove /etc/dirsrv/ds.keytab."
         (kwrite, kread, kerr) = os.popen3("/usr/kerberos/sbin/kadmin.local")
         kwrite.write("addprinc -randkey ldap/"+self.fqdn+"@"+self.realm+"\n")
         kwrite.flush()
@@ -218,6 +244,10 @@ class KrbInstance:
         os.chown("/var/kerberos/krb5kdc/kpasswd.keytab", pent.pw_uid, pent.pw_gid)
 
     def __create_http_keytab(self):
+        try:
+            os.remove("/etc/httpd/conf/ipa.keytab")
+        except os.OSError:
+            print "Failed to remove /etc/httpd/conf/ipa.keytab."
         (kwrite, kread, kerr) = os.popen3("/usr/kerberos/sbin/kadmin.local")
         kwrite.write("addprinc -randkey HTTP/"+self.fqdn+"@"+self.realm+"\n")
         kwrite.flush()
diff -r 6e4cbcfb88f6 -r 402790fcade3 ipa-server/xmlrpc-server/funcs.py
--- a/ipa-server/xmlrpc-server/funcs.py	Tue Oct 02 17:26:09 2007 -0400
+++ b/ipa-server/xmlrpc-server/funcs.py	Wed Oct 03 15:38:46 2007 -0400
@@ -69,7 +69,7 @@ class IPAConnPool:
         if conn is None:
             return
         # We can't re-use SASL connections. If proxydn is None it means
-        # we have a Kerberos credentails cache set. See ipaldap.set_krbccache
+        # we have a Kerberos credentials cache set. See ipaldap.set_krbccache
         if conn.proxydn is None:
             conn.unbind_s()
         else:
@@ -168,7 +168,10 @@ class IPAServer:
         else:
             raise ipaerror.gen_exception(ipaerror.CONNECTION_NO_CCACHE)
 
-        conn = _LDAPPool.getConn(self.host,port,bindca,bindcert,bindkey,proxy_dn,krbccache,debug)
+        try:
+            conn = _LDAPPool.getConn(self.host,port,bindca,bindcert,bindkey,proxy_dn,krbccache,debug)
+        except ldap.INVALID_CREDENTIALS, e:
+            raise ipaerror.gen_exception(ipaerror.CONNECTION_GSSAPI_CREDENTIALS, nested_exception=e)
 
         if conn is None:
             raise ipaerror.gen_exception(ipaerror.CONNECTION_NO_CONN)

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]