diff options
Diffstat (limited to 'ipa-server/ipa-install/ipa-server-install')
-rw-r--r-- | ipa-server/ipa-install/ipa-server-install | 622 |
1 files changed, 0 insertions, 622 deletions
diff --git a/ipa-server/ipa-install/ipa-server-install b/ipa-server/ipa-install/ipa-server-install deleted file mode 100644 index c9d5c5bf..00000000 --- a/ipa-server/ipa-install/ipa-server-install +++ /dev/null @@ -1,622 +0,0 @@ -#! /usr/bin/python -E -# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> -# -# Copyright (C) 2007 Red Hat -# see file 'COPYING' for use and warranty information -# -# 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; version 2 only -# -# 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 -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - - -# requires the following packages: -# fedora-ds-base -# openldap-clients -# nss-tools - -import sys -import os -import socket -import errno -import logging -import pwd -import subprocess -import signal -import shutil -import glob -import traceback -from optparse import OptionParser - -import ipaserver.dsinstance -import ipaserver.krbinstance -import ipaserver.bindinstance -import ipaserver.httpinstance -import ipaserver.ntpinstance - -from ipaserver import service -from ipa import version -from ipaserver.installutils import * - -from ipa import sysrestore -from ipa.ipautil import * - -pw_name = None - -def parse_options(): - parser = OptionParser(version=version.VERSION) - parser.add_option("-u", "--user", dest="ds_user", - help="ds user") - parser.add_option("-r", "--realm", dest="realm_name", - help="realm name") - parser.add_option("-n", "--domain", dest="domain_name", - help="domain name") - parser.add_option("-p", "--ds-password", dest="dm_password", - help="admin password") - parser.add_option("-P", "--master-password", dest="master_password", - help="kerberos master password (normally autogenerated)") - parser.add_option("-a", "--admin-password", dest="admin_password", - help="admin user kerberos password") - parser.add_option("-d", "--debug", dest="debug", action="store_true", - default=False, help="print debugging information") - parser.add_option("--hostname", dest="host_name", help="fully qualified name of server") - parser.add_option("--ip-address", dest="ip_address", help="Master Server IP Address") - parser.add_option("--setup-bind", dest="setup_bind", action="store_true", - default=False, help="configure bind with our zone file") - parser.add_option("-U", "--unattended", dest="unattended", action="store_true", - default=False, help="unattended installation never prompts the user") - parser.add_option("", "--uninstall", dest="uninstall", action="store_true", - default=False, help="uninstall an existing installation") - parser.add_option("-N", "--no-ntp", dest="conf_ntp", action="store_false", - help="do not configure ntp", default=True) - parser.add_option("--dirsrv_pkcs12", dest="dirsrv_pkcs12", - help="PKCS#12 file containing the Directory Server SSL certificate") - parser.add_option("--http_pkcs12", dest="http_pkcs12", - help="PKCS#12 file containing the Apache Server SSL certificate") - parser.add_option("--dirsrv_pin", dest="dirsrv_pin", - help="The password of the Directory Server PKCS#12 file") - parser.add_option("--http_pin", dest="http_pin", - help="The password of the Apache Server PKCS#12 file") - parser.add_option("--no-host-dns", dest="no_host_dns", action="store_true", - default=False, - help="Do not use DNS for hostname lookup during installation") - - options, args = parser.parse_args() - - if options.uninstall: - if (options.ds_user or options.realm_name or - options.dm_password or options.admin_password or - options.master_password): - parser.error("error: In uninstall mode, -u, r, -p and -P options are not allowed") - elif options.unattended: - if (not options.ds_user or not options.realm_name or - not options.dm_password or not options.admin_password): - parser.error("error: In unattended mode you need to provide at least -u, -r, -p and -a options") - - # If any of the PKCS#12 options are selected, all are required. Create a - # list of the options and count it to enforce that all are required without - # having a huge set of it blocks. - pkcs12 = [options.dirsrv_pkcs12, options.http_pkcs12, options.dirsrv_pin, options.http_pin] - cnt = pkcs12.count(None) - if cnt > 0 and cnt < 4: - parser.error("error: All PKCS#12 options are required if any are used.") - - return options - -def signal_handler(signum, frame): - global ds - print "\nCleaning up..." - if ds: - print "Removing configuration for %s instance" % ds.serverid - ds.stop() - if ds.serverid: - ipaserver.dsinstance.erase_ds_instance_data (ds.serverid) - sys.exit(1) - -def read_host_name(host_default,no_host_dns=False): - host_name = "" - - print "Enter the fully qualified domain name of the computer" - print "on which you're setting up server software. Using the form" - print "<hostname>.<domainname>" - print "Example: master.example.com." - print "" - print "" - if host_default == "": - host_default = "master.example.com" - while True: - host_name = user_input("Server host name", host_default, allow_empty = False) - print "" - try: - verify_fqdn(host_name,no_host_dns) - except Exception, e: - raise e - else: - break - return host_name - -def resolve_host(host_name): - ip = "" - try: - ip = socket.gethostbyname(host_name) - - if ip == "127.0.0.1" or ip == "::1": - print "The hostname resolves to the localhost address (127.0.0.1/::1)" - print "Please change your /etc/hosts file so that the hostname" - print "resolves to the ip address of your network interface." - print "The KDC service does not listen on localhost" - print "" - print "Please fix your /etc/hosts file and restart the setup program" - return None - - except: - print "Unable to lookup the IP address of the provided host" - return ip - -def verify_ip_address(ip): - is_ok = True - try: - socket.inet_pton(socket.AF_INET, ip) - except: - try: - socket.inet_pton(socket.AF_INET6, ip) - except: - print "Unable to verify IP address" - is_ok = False - return is_ok - -def read_ip_address(host_name): - while True: - ip = user_input("Please provide the IP address to be used for this host name", allow_empty = False) - - if ip == "127.0.0.1" or ip == "::1": - print "The IPA Server can't use localhost as a valid IP" - continue - - if not verify_ip_address(ip): - continue - - print "Adding ["+ip+" "+host_name+"] to your /etc/hosts file" - fstore.backup_file("/etc/hosts") - hosts_fd = open('/etc/hosts', 'r+') - hosts_fd.seek(0, 2) - hosts_fd.write(ip+'\t'+host_name+' '+host_name.split('.')[0]+'\n') - hosts_fd.close() - - return ip - -def read_ds_user(): - print "The server must run as a specific user in a specific group." - print "It is strongly recommended that this user should have no privileges" - print "on the computer (i.e. a non-root user). The setup procedure" - print "will give this user/group some permissions in specific paths/files" - print "to perform server-specific operations." - print "" - - ds_user = "" - try: - pwd.getpwnam('dirsrv') - - print "A user account named 'dirsrv' already exists. This is the user id" - print "that the Directory Server will run as." - print "" - if user_input("Do you want to use the existing 'dirsrv' account?", True): - ds_user = "dirsrv" - else: - print "" - ds_user = user_input_plain("Which account name do you want to use for the DS instance?", allow_empty = False, allow_spaces = False) - print "" - except KeyError: - ds_user = "dirsrv" - - return ds_user - -def read_domain_name(domain_name, unattended): - print "The domain name has been calculated based on the host name." - print "" - if not unattended: - domain_name = user_input("Please confirm the domain name", domain_name) - print "" - return domain_name - -def read_realm_name(domain_name, unattended): - print "The kerberos protocol requires a Realm name to be defined." - print "This is typically the domain name converted to uppercase." - print "" - - if unattended: - return domain_name.upper() - realm_name = user_input("Please provide a realm name", domain_name.upper()) - upper_dom = realm_name.upper() - if upper_dom != realm_name: - print "An upper-case realm name is required." - if not user_input("Do you want to use " + upper_dom + " as realm name?", True): - print "" - print "An upper-case realm name is required. Unable to continue." - sys.exit(1) - else: - realm_name = upper_dom - print "" - return realm_name - - -def read_dm_password(): - print "Certain directory server operations require an administrative user." - print "This user is referred to as the Directory Manager and has full access" - print "to the Directory for system management tasks and will be added to the" - print "instance of directory server created for IPA." - print "The password must be at least 8 characters long." - print "" - #TODO: provide the option of generating a random password - dm_password = read_password("Directory Manager") - return dm_password - -def read_admin_password(): - print "The IPA server requires an administrative user, named 'admin'." - print "This user is a regular system account used for IPA server administration." - print "" - #TODO: provide the option of generating a random password - admin_password = read_password("IPA admin") - return admin_password - -def check_dirsrv(unattended): - serverids = ipaserver.dsinstance.check_existing_installation() - if serverids: - print "" - print "An existing Directory Server has been detected." - if unattended or not user_input("Do you wish to remove it and create a new one?", False): - print "" - print "Only a single Directory Server instance is allowed on an IPA" - print "server, the one used by IPA itself." - sys.exit(1) - - try: - service.stop("dirsrv") - except: - pass - - for serverid in serverids: - ipaserver.dsinstance.erase_ds_instance_data(serverid) - - (ds_unsecure, ds_secure) = ipaserver.dsinstance.check_ports() - if not ds_unsecure or not ds_secure: - print "IPA requires ports 389 and 636 for the Directory Server." - print "These are currently in use:" - if not ds_unsecure: - print "\t389" - if not ds_secure: - print "\t636" - sys.exit(1) - -def uninstall(): - try: - run(["/usr/sbin/ipa-client-install", "--on-master", "--unattended", "--uninstall"]) - except Exception, e: - print "Uninstall of client side components failed!" - print "ipa-client-install returned: " + str(e) - pass - - ipaserver.ntpinstance.NTPInstance(fstore).uninstall() - ipaserver.bindinstance.BindInstance(fstore).uninstall() - ipaserver.httpinstance.WebGuiInstance().uninstall() - ipaserver.httpinstance.HTTPInstance(fstore).uninstall() - ipaserver.krbinstance.KrbInstance(fstore).uninstall() - ipaserver.dsinstance.DsInstance().uninstall() - fstore.restore_all_files() - return 0 - -def main(): - global ds - global pw_name - ds = None - - options = parse_options() - - if os.getegid() != 0: - print "Must be root to setup server" - return 1 - - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - - if options.uninstall: - standard_logging_setup("/var/log/ipaserver-uninstall.log", options.debug) - 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" - - global fstore - fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore') - - if options.uninstall: - if not options.unattended: - print "\nThis is a NON REVERSIBLE operation and will delete all data and configuration!\n" - if not user_input("Are you sure you want to continue with the uninstall procedure?", False): - print "" - print "Aborting uninstall operation." - sys.exit(1) - - return uninstall() - - print "==============================================================================" - print "This program will setup the FreeIPA Server." - print "" - print "This includes:" - if options.conf_ntp: - print " * Configure the Network Time Daemon (ntpd)" - print " * Create and configure an instance of Directory Server" - print " * Create and configure a Kerberos Key Distribution Center (KDC)" - print " * Configure Apache (httpd)" - print " * Configure TurboGears" - if options.setup_bind: - print " * Configure DNS (bind)" - if not options.conf_ntp: - print "" - print "Excluded by options:" - print " * Configure the Network Time Daemon (ntpd)" - print "" - print "To accept the default shown in brackets, press the Enter key." - print "" - - check_dirsrv(options.unattended) - - ds_user = "" - realm_name = "" - host_name = "" - domain_name = "" - ip_address = "" - master_password = "" - dm_password = "" - admin_password = "" - - # check bind packages are installed - if options.setup_bind: - if not ipaserver.bindinstance.check_inst(): - print "--setup-bind was specified but bind is not installed on the system" - print "Please install bind and restart the setup program" - return 1 - - # check the hostname is correctly configured, it must be as the kldap - # utilities just use the hostname as returned by gethostbyname to set - # up some of the standard entries - - host_default = "" - if options.host_name: - host_default = options.host_name - else: - host_default = get_fqdn() - - if options.unattended: - try: - verify_fqdn(host_default,options.no_host_dns) - except RuntimeError, e: - logging.error(str(e) + "\n") - return 1 - - host_name = host_default - else: - host_name = read_host_name(host_default,options.no_host_dns) - - host_name = host_name.lower() - - if not options.domain_name: - domain_name = read_domain_name(host_name[host_name.find(".")+1:], options.unattended) - else: - domain_name = options.domain_name - - domain_name = domain_name.lower() - - # Check we have a public IP that is associated with the hostname - ip = resolve_host(host_name) - if ip is None: - if options.ip_address: - ip = options.ip_address - if ip is None and options.unattended: - print "Unable to resolve IP address for host name" - return 1 - - if not verify_ip_address(ip): - ip = "" - if options.unattended: - return 1 - - if options.ip_address and options.ip_address != ip: - if options.setup_bind: - ip = options.ip_address - else: - print "Error: the hostname resolves to an IP address that is different" - print "from the one provided on the command line. Please fix your DNS" - print "or /etc/hosts file and restart the installation." - return 1 - - if options.unattended: - if not ip: - print "Unable to resolve IP address" - return 1 - - if not ip: - ip = read_ip_address(host_name) - ip_address = ip - - print "The IPA Master Server will be configured with" - print "Hostname: " + host_name - print "IP address: " + ip_address - print "Domain name: " + domain_name - print "" - - if not options.ds_user: - ds_user = read_ds_user() - if ds_user == "": - return 1 - else: - ds_user = options.ds_user - - if not options.realm_name: - realm_name = read_realm_name(domain_name, options.unattended) - else: - realm_name = options.realm_name.upper() - - if not options.dm_password: - dm_password = read_dm_password() - else: - dm_password = options.dm_password - - if not options.master_password: - master_password = ipa_generate_password() - else: - master_password = options.master_password - - if not options.admin_password: - admin_password = read_admin_password() - else: - admin_password = options.admin_password - - if not options.unattended: - print "" - print "The following operations may take some minutes to complete." - print "Please wait until the prompt is returned." - - # Configure ntpd - if options.conf_ntp: - ntp = ipaserver.ntpinstance.NTPInstance(fstore) - ntp.create_instance() - - if options.dirsrv_pin: - [pw_fd, pw_name] = tempfile.mkstemp() - os.write(pw_fd, options.dirsrv_pin) - os.close(pw_fd) - - # Create a directory server instance - ds = ipaserver.dsinstance.DsInstance() - if options.dirsrv_pkcs12: - pkcs12_info = (options.dirsrv_pkcs12, pw_name) - ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info) - os.remove(pw_name) - else: - ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password) - - # Create a kerberos instance - krb = ipaserver.krbinstance.KrbInstance(fstore) - krb.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, master_password) - - # Create a HTTP instance - - if options.http_pin: - [pw_fd, pw_name] = tempfile.mkstemp() - os.write(pw_fd, options.http_pin) - os.close(pw_fd) - - http = ipaserver.httpinstance.HTTPInstance(fstore) - if options.http_pkcs12: - pkcs12_info = (options.http_pkcs12, pw_name) - http.create_instance(realm_name, host_name, domain_name, autoconfig=False, pkcs12_info=pkcs12_info) - os.remove(pw_name) - else: - http.create_instance(realm_name, host_name, domain_name, autoconfig=True) - - # Create the config file - fstore.backup_file("/etc/ipa/ipa.conf") - fd = open("/etc/ipa/ipa.conf", "w") - fd.write("[defaults]\n") - fd.write("server=" + host_name + "\n") - fd.write("realm=" + realm_name + "\n") - fd.write("domain=" + domain_name + "\n") - fd.close() - - # Create a Web Gui instance - webgui = ipaserver.httpinstance.WebGuiInstance() - webgui.create_instance() - - bind = ipaserver.bindinstance.BindInstance(fstore) - bind.setup(host_name, ip_address, realm_name, domain_name) - if options.setup_bind: - bind.create_instance() - else: - bind.create_sample_bind_zone() - - # Apply any LDAP updates. Needs to be done after the configuration file - # is created - service.print_msg("Applying LDAP updates") - ds.apply_updates() - - # Restart ds and krb after configurations have been changed - service.print_msg("restarting the directory server") - ds.restart() - - service.print_msg("restarting the KDC") - krb.restart() - - # Set the admin user kerberos password - ds.change_admin_password(admin_password) - - # Call client install script - try: - run(["/usr/sbin/ipa-client-install", "--on-master", "--unattended", "--domain", domain_name, "--server", host_name, "--realm", realm_name]) - except Exception, e: - print "Configuration of client side components failed!" - print "ipa-client-install returned: " + str(e) - return 1 - - print "==============================================================================" - print "Setup complete" - print "" - print "Next steps:" - print "\t1. You must make sure these network ports are open:" - print "\t\tTCP Ports:" - print "\t\t * 80, 443: HTTP/HTTPS" - print "\t\t * 389, 636: LDAP/LDAPS" - print "\t\t * 88, 464: kerberos" - if options.setup_bind: - print "\t\t * 53: bind" - print "\t\tUDP Ports:" - print "\t\t * 88, 464: kerberos" - if options.setup_bind: - print "\t\t * 53: bind" - if options.conf_ntp: - print "\t\t * 123: ntp" - print "" - print "\t2. You can now obtain a kerberos ticket using the command: 'kinit admin'" - print "\t This ticket will allow you to use the IPA tools (e.g., ipa-adduser)" - print "\t and the web user interface." - - if not service.is_running("ntpd"): - print "\t3. Kerberos requires time synchronization between clients" - print "\t and servers for correct operation. You should consider enabling ntpd." - - print "" - if not options.dirsrv_pkcs12: - print "Be sure to back up the CA certificate stored in " + ipaserver.dsinstance.config_dirname(ds.serverid) + "cacert.p12" - print "The password for this file is in " + ipaserver.dsinstance.config_dirname(ds.serverid) + "pwdfile.txt" - else: - print "In order for Firefox autoconfiguration to work you will need to" - print "use a SSL signing certificate. See the IPA documentation for more details." - print "You also need to install a PEM copy of the HTTP issuing CA into" - print "/usr/share/ipa/html/ca.crt" - - return 0 - -try: - try: - sys.exit(main()) - except SystemExit, e: - sys.exit(e) - except Exception, e: - message = "Unexpected error - see ipaserver-install.log for details:\n %s" % str(e) - print message - message = str(e) - for str in traceback.format_tb(sys.exc_info()[2]): - message = message + "\n" + str - logging.debug(message) - sys.exit(1) -finally: - if pw_name and ipautil.file_exists(pw_name): - os.remove(pw_name) |