summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-server/ipa-install/ipa-replica-install37
-rw-r--r--ipa-server/ipa-install/ipa-replica-prepare89
-rw-r--r--ipa-server/ipa-install/ipa-server-install5
-rw-r--r--ipa-server/ipaserver/certs.py53
-rw-r--r--ipa-server/ipaserver/dsinstance.py3
-rw-r--r--ipa-server/ipaserver/httpinstance.py16
-rw-r--r--ipa-server/ipaserver/replication.py2
7 files changed, 162 insertions, 43 deletions
diff --git a/ipa-server/ipa-install/ipa-replica-install b/ipa-server/ipa-install/ipa-replica-install
index 792e31bb..57fae7fe 100644
--- a/ipa-server/ipa-install/ipa-replica-install
+++ b/ipa-server/ipa-install/ipa-replica-install
@@ -20,13 +20,13 @@
import sys
-import tempfile, os, pwd, traceback, logging
+import tempfile, os, pwd, traceback, logging, shutil
from ConfigParser import SafeConfigParser
from ipa import ipautil
from ipaserver import dsinstance, replication, installutils, krbinstance, service
-from ipaserver import httpinstance, webguiinstance, ntpinstance, certs
+from ipaserver import httpinstance, ntpinstance, certs
class ReplicaConfig:
def __init__(self):
@@ -93,13 +93,12 @@ def install_ds(config):
# that. Otherwise the ds setup will create the CA
# cert
pkcs12_info = None
- if ipautil.file_exists(config.dir + "/cacert.p12"):
- pkcs12_info = (config.dir + "/cacert.p12",
+ if ipautil.file_exists(config.dir + "/dscert.p12"):
+ pkcs12_info = (config.dir + "/dscert.p12",
config.dir + "/pwdfile.txt")
ds = dsinstance.DsInstance()
- ds.create_instance(config.ds_user, config.realm_name, config.host_name, config.dirman_password,
- pkcs12_info)
+ ds.create_instance(config.ds_user, config.realm_name, config.host_name, config.dirman_password, pkcs12_info)
def install_krb(config):
krb = krbinstance.KrbInstance()
@@ -108,8 +107,25 @@ def install_krb(config):
config.dirman_password, ldappwd_filename)
def install_http(config):
+ # if we have a pkcs12 file, create the cert db from
+ # that. Otherwise the ds setup will create the CA
+ # cert
+ pkcs12_info = None
+ if ipautil.file_exists(config.dir + "/httpcert.p12"):
+ pkcs12_info = (config.dir + "/httpcert.p12",
+ config.dir + "/pwdfile.txt")
+
http = httpinstance.HTTPInstance()
- http.create_instance(config.realm_name, config.host_name)
+ http.create_instance(config.realm_name, config.host_name, False, pkcs12_info)
+
+ # Now copy the autoconfiguration files
+ try:
+ shutil.copy(config.dir + "/preferences.html", "/usr/share/ipa/html/preferences.html")
+ shutil.copy(config.dir + "/configure.jar", "/usr/share/ipa/html/configure.jar")
+ shutil.copy(config.dir + "/ca.crt", "/usr/share/ipa/html/ca.crt")
+ except Exception, e:
+ print "error copying files: " + str(e)
+ sys.exit(1)
def main():
options, filename = parse_options()
@@ -137,18 +153,20 @@ def main():
install_http(config)
# Create a Web Gui instance
- webgui = webguiinstance.WebGuiInstance()
+ webgui = httpinstance.WebGuiInstance()
webgui.create_instance()
# Configure ntpd
ntp = ntpinstance.NTPInstance()
ntp.create_instance()
-
service.restart("dirsrv")
service.restart("krb5kdc")
try:
+ if not os.geteuid()==0:
+ sys.exit("\nYou must be root to run this script.\n")
+
main()
except Exception, e:
print "creation of replica failed: %s" % str(e)
@@ -157,4 +175,3 @@ except Exception, e:
message = message + "\n" + str
logging.debug(message)
sys.exit(1)
-
diff --git a/ipa-server/ipa-install/ipa-replica-prepare b/ipa-server/ipa-install/ipa-replica-prepare
index ba845558..54f507dc 100644
--- a/ipa-server/ipa-install/ipa-replica-prepare
+++ b/ipa-server/ipa-install/ipa-replica-prepare
@@ -21,12 +21,30 @@
import sys
import logging, tempfile, shutil, os, pwd
+import traceback
from ConfigParser import SafeConfigParser
import krbV
+from optparse import OptionParser
+import ipa.config
from ipa import ipautil
from ipaserver import dsinstance, installutils, certs
+def usage():
+ print "ipa-replica-prepate FQDN (e.g. replica.example.com)"
+ sys.exit(1)
+
+def parse_options():
+ parser = OptionParser()
+
+ args = ipa.config.init_config(sys.argv)
+ options, args = parser.parse_args(args)
+
+ if len(args) != 2:
+ parser.error("must provide the fully-qualified name of the replica")
+
+ return options, args
+
def get_host_name():
hostname = installutils.get_fqdn()
try:
@@ -42,22 +60,31 @@ def get_realm_name():
return c.default_realm
def check_ipa_configuration(realm_name):
- config_dir = dsinstance.config_dirname(realm_name)
+ config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
if not ipautil.dir_exists(config_dir):
logging.error("could not find directory instance: %s" % config_dir)
sys.exit(1)
-def export_certdb(ds_dir, dir):
- ds_cdb = certs.CertDB(ds_dir)
-
- pkcs12_fname = dir + "/cacert.p12"
+def export_certdb(realm_name, ds_dir, dir, fname, subject):
+ """realm is the kerberos realm for the IPA server.
+ ds_dir is the location of the master DS we are creating a replica for.
+ dir is the location of the files for the replica we are creating.
+ fname is the filename of the PKCS#12 file for this cert (minus the .p12).
+ subject is the subject of the certificate we are creating
+ """
+ ds_ca = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)))
+ ca = certs.CertDB(dir)
+ ca.create_from_cacert(ds_ca.cacert_fname)
+ ca.create_server_cert("Server-Cert", subject, ds_ca)
+
+ pkcs12_fname = dir + "/" + fname + ".p12"
passwd_fname = dir + "/pwdfile.txt"
fd = open(passwd_fname, "w")
fd.write("\n")
fd.close()
try:
- ds_cdb.export_pkcs12(pkcs12_fname, passwd_fname)
+ ca.export_pkcs12(pkcs12_fname, passwd_fname, "Server-Cert")
except ipautil.CalledProcessError, e:
print "error exporting CA certificate: " + str(e)
try:
@@ -66,6 +93,9 @@ def export_certdb(ds_dir, dir):
except:
pass
+ os.unlink(dir + "/cert8.db")
+ os.unlink(dir + "/key3.db")
+ os.unlink(dir + "/secmod.db")
def get_ds_user(ds_dir):
uid = os.stat(ds_dir).st_uid
@@ -83,31 +113,60 @@ def save_config(dir, realm_name, host_name, ds_user):
config.write(fd)
def copy_files(realm_name, dir):
- shutil.copy("/var/kerberos/krb5kdc/ldappwd", dir + "/ldappwd")
+ config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
+ try:
+ shutil.copy("/var/kerberos/krb5kdc/ldappwd", dir + "/ldappwd")
+ shutil.copy("/usr/share/ipa/html/preferences.html", dir + "/preferences.html")
+ shutil.copy("/usr/share/ipa/html/configure.jar", dir + "/configure.jar")
+ shutil.copy(config_dir + "/cacert.asc", dir + "/ca.crt")
+ except Exception, e:
+ print "error copying files: " + str(e)
+ sys.exit(1)
def main():
+ options, args = parse_options()
+
+ replica_fqdn = args[1]
+
realm_name = get_realm_name()
+ check_ipa_configuration(realm_name)
+
host_name = get_host_name()
ds_dir = dsinstance.config_dirname(realm_name)
ds_user = get_ds_user(ds_dir)
- check_ipa_configuration(realm_name)
+ print "Preparing replica for %s from %s" % (replica_fqdn, host_name)
top_dir = tempfile.mkdtemp("ipa")
dir = top_dir + "/realm_info"
os.mkdir(dir, 0700)
- export_certdb(ds_dir, dir)
+ print "Creating SSL certificate for the Directory Server"
+ export_certdb(realm_name, ds_dir, dir, "dscert", "cn=%s,ou=Fedora Directory Server" % replica_fqdn)
+ print "Creating SSL certificate for the Web Server"
+ export_certdb(realm_name, ds_dir, dir, "httpcert", "cn=%s,ou=Apache Web Server" % replica_fqdn)
+ print "Copying additional files"
copy_files(realm_name, dir)
+ print "Finalizing configuration"
save_config(dir, realm_name, host_name, ds_user)
+ print "Packaging the replica into %s" % "replica-info-" + realm_name
ipautil.run(["/bin/tar", "cfz", "replica-info-" + realm_name, "-C", top_dir, "realm_info"])
shutil.rmtree(dir)
-main()
-
-
-
-
-
+try:
+ if not os.geteuid()==0:
+ sys.exit("\nYou must be root to run this script.\n")
+ if not ipautil.file_exists("/usr/share/ipa/serial"):
+ sys.exist("The replica must be created on the primary IPA server.")
+
+ main()
+except Exception, e:
+ print "preparation of replica failed: %s" % str(e)
+ message = str(e)
+ for str in traceback.format_tb(sys.exc_info()[2]):
+ message = message + "\n" + str
+ logging.debug(message)
+ print message
+ sys.exit(1)
diff --git a/ipa-server/ipa-install/ipa-server-install b/ipa-server/ipa-install/ipa-server-install
index a7405f69..4f5354fa 100644
--- a/ipa-server/ipa-install/ipa-server-install
+++ b/ipa-server/ipa-install/ipa-server-install
@@ -496,7 +496,7 @@ def main():
print "\t\t * 88, 464: kerberos"
print "\t\t * 123: ntp"
print ""
- print "\t2. You can now obtain a kerberos ticket using the command: 'kinit admin'."
+ 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."
@@ -504,7 +504,8 @@ def main():
print "\t3. Kerberos requires time synchronization between clients"
print "\t and servers for correct operation. You should consider enabling ntpd."
-
+ print ""
+ print "Be sure to back up the CA certificate stored in " + ipaserver.dsinstance.config_dirname(ds.serverid) + "cacert.p12"
return 0
diff --git a/ipa-server/ipaserver/certs.py b/ipa-server/ipaserver/certs.py
index b39cf224..30568e6e 100644
--- a/ipa-server/ipaserver/certs.py
+++ b/ipa-server/ipaserver/certs.py
@@ -19,6 +19,7 @@
import os, stat, subprocess, re
import sha
+import errno
from ipa import ipautil
@@ -42,7 +43,7 @@ class CertDB(object):
# responsibility of the caller for now. In the
# future we might automatically determine this
# for a given db.
- self.cur_serial = 1000
+ self.cur_serial = -1
self.cacert_name = "CA certificate"
self.valid_months = "120"
@@ -57,10 +58,40 @@ class CertDB(object):
self.uid = mode[stat.ST_UID]
self.gid = mode[stat.ST_GID]
+ def set_serial_from_pkcs12(self):
+ """A CA cert was loaded from a PKCS#12 file. Set up our serial file"""
+
+ self.cur_serial = self.find_cacert_serial()
+ try:
+ f=open("/usr/share/ipa/serial","w")
+ f.write(str(self.cur_serial))
+ f.close()
+ except IOError, e:
+ raise RuntimeError("Unable to increment serial number: %s" % str(e))
+
def next_serial(self):
- r = self.cur_serial
- self.cur_serial += 1
- return str(r)
+ try:
+ f=open("/usr/share/ipa/serial","r")
+ r = f.readline()
+ self.cur_serial = int(r) + 1
+ f.close()
+ except IOError, e:
+ if e.errno == errno.ENOENT:
+ self.cur_serial = 1000
+ f=open("/usr/share/ipa/serial","w")
+ f.write(str(self.cur_serial))
+ f.close()
+ else:
+ raise RuntimeError("Unable to determine serial number: %s" % str(e))
+
+ try:
+ f=open("/usr/share/ipa/serial","w")
+ f.write(str(self.cur_serial))
+ f.close()
+ except IOError, e:
+ raise RuntimeError("Unable to increment serial number: %s" % str(e))
+
+ return str(self.cur_serial)
def set_perms(self, fname, write=False):
os.chown(fname, self.uid, self.gid)
@@ -75,7 +106,7 @@ class CertDB(object):
def run_certutil(self, args, stdin=None):
new_args = ["/usr/bin/certutil", "-d", self.secdir]
new_args = new_args + args
- ipautil.run(new_args, stdin)
+ return ipautil.run(new_args, stdin)
def run_signtool(self, args, stdin=None):
new_args = ["/usr/bin/signtool", "-d", self.secdir]
@@ -139,6 +170,16 @@ class CertDB(object):
"-t", "CT,,C",
"-a",
"-i", cacert_fname])
+
+ def find_cacert_serial(self):
+ (out,err) = self.run_certutil(["-L", "-n", self.cacert_name])
+ data = out.split('\n')
+ for line in data:
+ x = re.match(r'\s+Serial Number: (\d+) .*', line)
+ if x is not None:
+ return x.group(1)
+
+ raise RuntimeError("Unable to find serial number")
def create_server_cert(self, nickname, name, other_certdb=None):
cdb = other_certdb
@@ -330,5 +371,3 @@ class CertDB(object):
sysrestore.backup_file(self.pin_fname)
sysrestore.backup_file(self.certreq_fname)
sysrestore.backup_file(self.certder_fname)
-
-
diff --git a/ipa-server/ipaserver/dsinstance.py b/ipa-server/ipaserver/dsinstance.py
index 733e5d5b..a320a1be 100644
--- a/ipa-server/ipaserver/dsinstance.py
+++ b/ipa-server/ipaserver/dsinstance.py
@@ -257,10 +257,9 @@ class DsInstance(service.Service):
ca = certs.CertDB(dirname)
if self.pkcs12_info:
ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1])
- ca.cur_serial = 2100
else:
ca.create_self_signed()
- ca.create_server_cert("Server-Cert", "cn=%s,ou=Fedora Directory Server" % self.host_name)
+ ca.create_server_cert("Server-Cert", "cn=%s,ou=Fedora Directory Server" % self.host_name)
conn = ipaldap.IPAdmin("127.0.0.1")
conn.simple_bind_s("cn=directory manager", self.dm_password)
diff --git a/ipa-server/ipaserver/httpinstance.py b/ipa-server/ipaserver/httpinstance.py
index 12e5ae10..bee77e9f 100644
--- a/ipa-server/ipaserver/httpinstance.py
+++ b/ipa-server/ipaserver/httpinstance.py
@@ -55,10 +55,11 @@ class HTTPInstance(service.Service):
def __init__(self):
service.Service.__init__(self, "httpd")
- def create_instance(self, realm, fqdn):
+ def create_instance(self, realm, fqdn, autoconfig=True, pkcs12_info=None):
self.fqdn = fqdn
self.realm = realm
self.domain = fqdn[fqdn.find(".")+1:]
+ self.pkcs12_info = pkcs12_info
self.sub_dict = { "REALM" : realm, "FQDN": fqdn, "DOMAIN" : self.domain }
self.step("disabling mod_ssl in httpd", self.__disable_mod_ssl)
@@ -66,7 +67,8 @@ class HTTPInstance(service.Service):
self.step("configuring httpd", self.__configure_http)
self.step("creating a keytab for httpd", self.__create_http_keytab)
self.step("Setting up ssl", self.__setup_ssl)
- self.step("Setting up browser autoconfig", self.__setup_autoconfig)
+ if autoconfig:
+ self.step("Setting up browser autoconfig", self.__setup_autoconfig)
self.step("configuring SELinux for httpd", self.__selinux_config)
self.step("restarting httpd", self.__start)
self.step("configuring httpd to start on boot", self.__enable)
@@ -136,10 +138,12 @@ class HTTPInstance(service.Service):
def __setup_ssl(self):
ds_ca = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(self.realm)))
ca = certs.CertDB(NSS_DIR)
- ds_ca.cur_serial = 2000
- ca.create_from_cacert(ds_ca.cacert_fname)
- ca.create_server_cert("Server-Cert", "cn=%s,ou=Apache Web Server" % self.fqdn, ds_ca)
- ca.create_signing_cert("Signing-Cert", "cn=%s,ou=Signing Certificate,o=Identity Policy Audit" % self.fqdn, ds_ca)
+ if self.pkcs12_info:
+ ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd=False)
+ else:
+ ca.create_from_cacert(ds_ca.cacert_fname)
+ ca.create_server_cert("Server-Cert", "cn=%s,ou=Apache Web Server" % self.fqdn, ds_ca)
+ ca.create_signing_cert("Signing-Cert", "cn=%s,ou=Signing Certificate,o=Identity Policy Audit" % self.fqdn, ds_ca)
def __setup_autoconfig(self):
prefs_txt = ipautil.template_file(ipautil.SHARE_DIR + "preferences.html.template", self.sub_dict)
diff --git a/ipa-server/ipaserver/replication.py b/ipa-server/ipaserver/replication.py
index 765905e5..10addc65 100644
--- a/ipa-server/ipaserver/replication.py
+++ b/ipa-server/ipaserver/replication.py
@@ -279,7 +279,7 @@ class ReplicationManager:
return haserror
def start_replication(self, other_conn):
- print "starting replication"
+ print "Starting replication, please wait until this has completed."
cn, dn = self.agreement_dn(self.conn)
mod = [(ldap.MOD_ADD, 'nsds5BeginReplicaRefresh', 'start')]