mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-28 18:01:23 -06:00
bd9dea888d
435019
219 lines
7.1 KiB
Python
219 lines
7.1 KiB
Python
#! /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
|
|
#
|
|
|
|
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, ipaldap
|
|
from ipaserver import version
|
|
import ldap
|
|
|
|
def usage():
|
|
print "ipa-replica-prepate FQDN (e.g. replica.example.com)"
|
|
sys.exit(1)
|
|
|
|
def parse_options():
|
|
parser = OptionParser(version=version.VERSION)
|
|
|
|
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:
|
|
installutils.verify_fqdn(hostname)
|
|
except RuntimeError, e:
|
|
logging.error(str(e))
|
|
sys.exit(1)
|
|
|
|
return hostname
|
|
|
|
def get_realm_name():
|
|
try:
|
|
c = krbV.default_context()
|
|
return c.default_realm
|
|
except Exception, e:
|
|
return None
|
|
|
|
def get_domain_name():
|
|
try:
|
|
conn = ipaldap.IPAdmin("127.0.0.1")
|
|
conn.simple_bind_s("", "")
|
|
|
|
context = conn.getEntry("", ldap.SCOPE_BASE, '(objectclass=*)', [ 'namingContexts' ])
|
|
conn.unbind()
|
|
except Exception, e:
|
|
return None
|
|
|
|
domain_name = context.getValue('namingContexts')
|
|
domain_name = domain_name.replace('dc=','')
|
|
domain_name = domain_name.replace(',','.')
|
|
|
|
return domain_name
|
|
|
|
def check_ipa_configuration(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(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
|
|
"""
|
|
try:
|
|
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)
|
|
except Exception, e:
|
|
raise e
|
|
|
|
pkcs12_fname = dir + "/" + fname + ".p12"
|
|
passwd_fname = dir + "/pwdfile.txt"
|
|
fd = open(passwd_fname, "w")
|
|
fd.write("\n")
|
|
fd.close()
|
|
|
|
try:
|
|
ca.export_pkcs12(pkcs12_fname, passwd_fname, "Server-Cert")
|
|
except ipautil.CalledProcessError, e:
|
|
print "error exporting CA certificate: " + str(e)
|
|
try:
|
|
os.unlink(pkcs12_fname)
|
|
os.unlink(passwd_fname)
|
|
except:
|
|
pass
|
|
|
|
os.unlink(dir + "/cert8.db")
|
|
os.unlink(dir + "/key3.db")
|
|
os.unlink(dir + "/secmod.db")
|
|
os.unlink(dir + "/noise.txt")
|
|
if ipautil.file_exists(passwd_fname + ".orig"):
|
|
os.unlink(passwd_fname + ".orig")
|
|
|
|
def get_ds_user(ds_dir):
|
|
uid = os.stat(ds_dir).st_uid
|
|
user = pwd.getpwuid(uid)[0]
|
|
|
|
return user
|
|
|
|
def save_config(dir, realm_name, host_name, ds_user, domain_name):
|
|
config = SafeConfigParser()
|
|
config.add_section("realm")
|
|
config.set("realm", "realm_name", realm_name)
|
|
config.set("realm", "master_host_name", host_name)
|
|
config.set("realm", "ds_user", ds_user)
|
|
config.set("realm", "domain_name", domain_name)
|
|
fd = open(dir + "/realm_info", "w")
|
|
config.write(fd)
|
|
|
|
def copy_files(realm_name, dir):
|
|
config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
|
|
try:
|
|
shutil.copy("/var/kerberos/krb5kdc/ldappwd", dir + "/ldappwd")
|
|
shutil.copy("/var/kerberos/krb5kdc/kpasswd.keytab", dir + "/kpasswd.keytab")
|
|
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]
|
|
|
|
print "Determining current realm name"
|
|
realm_name = get_realm_name()
|
|
if realm_name is None:
|
|
print "Unable to determine default realm"
|
|
sys.exit(1)
|
|
|
|
check_ipa_configuration(realm_name)
|
|
|
|
print "Getting domain name from LDAP"
|
|
domain_name = get_domain_name()
|
|
if domain_name is None:
|
|
print "Unable to determine LDAP default domain"
|
|
sys.exit(1)
|
|
|
|
host_name = get_host_name()
|
|
if host_name == replica_fqdn:
|
|
print "You can't create a replica on itself"
|
|
sys.exit(1)
|
|
ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
|
|
ds_user = get_ds_user(ds_dir)
|
|
|
|
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)
|
|
|
|
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, domain_name)
|
|
|
|
print "Packaging the replica into /var/lib/ipa/%s" % "replica-info-" + replica_fqdn
|
|
ipautil.run(["/bin/tar", "cfz", "/var/lib/ipa/replica-info-" + replica_fqdn, "-C", top_dir, "realm_info"])
|
|
os.chmod("/var/lib/ipa/replica-info-" + replica_fqdn, 0600)
|
|
|
|
shutil.rmtree(dir)
|
|
|
|
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.exit("The replica must be created on the primary IPA server.")
|
|
|
|
main()
|
|
except SystemExit, e:
|
|
sys.exit(e)
|
|
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)
|