summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--install/share/default-aci.ldif2
-rwxr-xr-xinstall/tools/ipa-replica-install6
-rwxr-xr-xinstall/tools/ipa-server-install8
-rw-r--r--ipaserver/install/bindinstance.py12
-rw-r--r--ipaserver/install/cainstance.py4
-rw-r--r--ipaserver/install/certs.py12
-rw-r--r--ipaserver/install/dsinstance.py9
-rw-r--r--ipaserver/install/httpinstance.py16
-rw-r--r--ipaserver/install/krbinstance.py38
-rw-r--r--ipaserver/install/ldapupdate.py3
-rw-r--r--ipaserver/install/service.py60
11 files changed, 146 insertions, 24 deletions
diff --git a/install/share/default-aci.ldif b/install/share/default-aci.ldif
index 7f08518b8..784377e9f 100644
--- a/install/share/default-aci.ldif
+++ b/install/share/default-aci.ldif
@@ -8,7 +8,7 @@ aci: (targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || samba
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword")(version 3.0; acl "Self can write own password"; allow (write) userdn="ldap:///self";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Password change service can read/write passwords"; allow (read, write) userdn="ldap:///krbprincipalname=kadmin/changepw@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
-aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "KDC System Account can access passwords"; allow (all) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr = "userPassword || krbPrincipalKey || krbPasswordExpiration || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "KDC System Account can access passwords"; allow (all) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
aci: (targetattr = "krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount")(version 3.0; acl "KDC System Account can update some fields"; allow (write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
aci: (targetattr = "krbPrincipalName || krbUPEnabled || krbMKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount")(version 3.0; acl "Only the KDC System Account has access to kerberos material"; allow (read, search, compare) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
aci: (targetfilter = "(|(objectClass=person)(objectClass=krbPrincipalAux)(objectClass=posixAccount)(objectClass=groupOfNames)(objectClass=posixGroup))")(targetattr != "aci || userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Account Admins can manage Users and Groups"; allow (add, delete, read, write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 33d3726c2..766957862 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -200,7 +200,7 @@ def install_http(config):
config.dir + "/http_pin.txt")
http = httpinstance.HTTPInstance()
- http.create_instance(config.realm_name, config.host_name, config.domain_name, False, pkcs12_info, self_signed_ca=True)
+ http.create_instance(config.realm_name, config.host_name, config.domain_name, config.dirman_password, False, pkcs12_info, self_signed_ca=True)
# Now copy the autoconfiguration files
if ipautil.file_exists(config.dir + "/preferences.html"):
@@ -347,6 +347,10 @@ def main():
CA.fix_ra_perms()
service.restart("httpd")
+ # The DS instance is created before the keytab, add the SSL cert we
+ # generated
+ ds.add_cert_to_service()
+
# Create the management framework config file
fd = open("/etc/ipa/default.conf", "w")
fd.write("[global]\n")
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 0694d6ed5..c92989a47 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -729,6 +729,10 @@ def main():
krb = krbinstance.KrbInstance(fstore)
krb.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, master_password)
+ # The DS instance is created before the keytab, add the SSL cert we
+ # generated
+ ds.add_cert_to_service()
+
# Render webui assets:
ipautil.run(["/sbin/restorecon", ASSETS_DIR])
render_assets()
@@ -743,10 +747,10 @@ def main():
http = 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)
+ http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=False, pkcs12_info=pkcs12_info)
os.remove(pw_name)
else:
- http.create_instance(realm_name, host_name, domain_name, autoconfig=True, self_signed_ca=not options.ca)
+ http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=True, self_signed_ca=not options.ca)
ipautil.run(["/sbin/restorecon", "/var/cache/ipa/sessions"])
# Create the management framework config file
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index e2edcd392..9150c8edf 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -201,6 +201,7 @@ class BindInstance(service.Service):
# Store the keytab on disk
self.fstore.backup_file("/etc/named.keytab")
installutils.create_keytab("/etc/named.keytab", dns_principal)
+ dns_principal = self.move_service(dns_principal)
# Make sure access is strictly reserved to the named user
pent = pwd.getpwnam(self.named_user)
@@ -220,17 +221,8 @@ class BindInstance(service.Service):
logging.critical("Could not connect to the Directory Server on %s" % self.fqdn)
raise e
- dns_princ_dn = "krbprincipalname=%s,cn=%s,cn=kerberos,%s" % (dns_principal, self.realm, self.suffix)
- mod = [(ldap.MOD_ADD, 'objectClass', 'ipaService')]
-
- try:
- conn.modify_s(dns_princ_dn, mod)
- except Exception, e:
- logging.critical("Could not modify principal's %s entry" % dns_principal)
- raise e
-
dns_group = "cn=dnsserver,cn=rolegroups,cn=accounts,%s" % self.suffix
- mod = [(ldap.MOD_ADD, 'member', dns_princ_dn)]
+ mod = [(ldap.MOD_ADD, 'member', dns_principal)]
try:
conn.modify_s(dns_group, mod)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 198b0c644..46a337cb0 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -810,7 +810,7 @@ class CAInstance(service.Service):
os.close(f)
os.chmod(self.ra_agent_pwd, stat.S_IRUSR)
- stdout, stderr = self.__run_certutil(["-N"])
+ (stdout, stderr, returncode) = self.__run_certutil(["-N"])
def __get_ca_chain(self):
try:
@@ -886,7 +886,7 @@ class CAInstance(service.Service):
# Generate our CSR. The result gets put into stdout
try:
- (stdout, stderr) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", "CN=RA Subsystem Certificate,OU=pki-ipa,O=%s" % self.domain_name, "-z", noise_name, "-a"])
+ (stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", "CN=RA Subsystem Certificate,OU=pki-ipa,O=%s" % self.domain_name, "-z", noise_name, "-a"])
finally:
os.remove(noise_name)
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index c4923a751..a1dffff24 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -26,6 +26,7 @@ import urllib
import xml.dom.minidom
import pwd
import fcntl
+import base64
from ipapython import nsslib
from ipapython import sysrestore
@@ -459,9 +460,20 @@ class CertDB(object):
(out, err) = self.request_cert(subject)
cdb.issue_server_cert(self.certreq_fname, self.certder_fname)
self.add_cert(self.certder_fname, nickname)
+ fd = open(self.certder_fname, "r")
+ dercert = fd.read()
+ fd.close()
+
os.unlink(self.certreq_fname)
os.unlink(self.certder_fname)
+ # On the off-chance the certificate is base64-encoded
+ try:
+ dercert = base64.b64decode(dercert)
+ except:
+ pass
+ return dercert
+
def create_signing_cert(self, nickname, hostname, other_certdb=None, subject=None):
cdb = other_certdb
if not cdb:
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index c25b97538..33ff053c3 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -146,6 +146,7 @@ class DsInstance(service.Service):
self.host_name = None
self.pkcs12_info = None
self.ds_user = None
+ self.dercert = None
if realm_name:
self.suffix = util.realm_to_suffix(self.realm_name)
self.__setup_sub_dict()
@@ -164,6 +165,7 @@ class DsInstance(service.Service):
self.self_signed_ca = self_signed_ca
self.uidstart = uidstart
self.gidstart = gidstart
+ self.principal = "ldap/%s@%s" % (self.host_name, self.realm_name)
self.__setup_sub_dict()
self.step("creating directory server user", self.__create_ds_user)
@@ -203,7 +205,7 @@ class DsInstance(service.Service):
REALM=self.realm_name, USER=self.ds_user,
SERVER_ROOT=server_root, DOMAIN=self.domain,
TIME=int(time.time()), UIDSTART=self.uidstart,
- GIDSTART=self.gidstart)
+ GIDSTART=self.gidstart, HOST=self.host_name)
def __create_ds_user(self):
user_exists = True
@@ -335,19 +337,20 @@ class DsInstance(service.Service):
# We only handle one server cert
nickname = server_certs[0][0]
+ self.dercert = dsdb.get_cert_from_db(nickname)
else:
nickname = "Server-Cert"
cadb = certs.CertDB(httpinstance.NSS_DIR, host_name=self.host_name)
if self.self_signed_ca:
cadb.create_self_signed()
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
- dsdb.create_server_cert("Server-Cert", self.host_name, cadb)
+ self.dercert = dsdb.create_server_cert("Server-Cert", self.host_name, cadb)
dsdb.create_pin_file()
else:
# FIXME, need to set this nickname in the RA plugin
cadb.export_ca_cert('ipaCert', False)
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
- dsdb.create_server_cert("Server-Cert", self.host_name, cadb)
+ self.dercert = dsdb.create_server_cert("Server-Cert", self.host_name, cadb)
dsdb.create_pin_file()
conn = ipaldap.IPAdmin("127.0.0.1")
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 94e155bf0..ee62f81f2 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -30,6 +30,7 @@ import dsinstance
import installutils
from ipapython import sysrestore
from ipapython import ipautil
+from ipalib import util
HTTPD_DIR = "/etc/httpd"
SSL_CONF = HTTPD_DIR + "/conf.d/ssl.conf"
@@ -55,12 +56,16 @@ class HTTPInstance(service.Service):
else:
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
- def create_instance(self, realm, fqdn, domain_name, autoconfig=True, pkcs12_info=None, self_signed_ca=False):
+ def create_instance(self, realm, fqdn, domain_name, dm_password=None, autoconfig=True, pkcs12_info=None, self_signed_ca=False):
self.fqdn = fqdn
self.realm = realm
self.domain = domain_name
+ self.dm_password = dm_password
+ self.suffix = util.realm_to_suffix(self.realm)
self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
+ self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm)
+ self.dercert = None
self.sub_dict = { "REALM" : realm, "FQDN": fqdn, "DOMAIN" : self.domain }
self.step("disabling mod_ssl in httpd", self.__disable_mod_ssl)
@@ -68,11 +73,11 @@ class HTTPInstance(service.Service):
self.step("Setting mod_nss password file", self.__set_mod_nss_passwordfile)
self.step("Adding URL rewriting rules", self.__add_include)
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)
if autoconfig:
self.step("Setting up browser autoconfig", self.__setup_autoconfig)
self.step("publish CA cert", self.__publish_ca_cert)
+ self.step("creating a keytab for httpd", self.__create_http_keytab)
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)
@@ -117,6 +122,8 @@ class HTTPInstance(service.Service):
http_principal = "HTTP/" + self.fqdn + "@" + self.realm
installutils.kadmin_addprinc(http_principal)
installutils.create_keytab("/etc/httpd/conf/ipa.keytab", http_principal)
+ self.move_service(http_principal)
+ self.add_cert_to_service()
pent = pwd.getpwnam("apache")
os.chown("/etc/httpd/conf/ipa.keytab", pent.pw_uid, pent.pw_gid)
@@ -170,16 +177,17 @@ class HTTPInstance(service.Service):
db.create_password_conf()
# We only handle one server cert
nickname = server_certs[0][0]
+ self.dercert = db.get_cert_from_db(nickname)
self.__set_mod_nss_nickname(nickname)
else:
if self.self_signed_ca:
db.create_from_cacert(ca_db.cacert_fname)
db.create_password_conf()
- db.create_server_cert("Server-Cert", self.fqdn, ca_db)
+ self.dercert = db.create_server_cert("Server-Cert", self.fqdn, ca_db)
db.create_signing_cert("Signing-Cert", "Object Signing Cert", ca_db)
else:
- db.create_server_cert("Server-Cert", self.fqdn, ca_db)
+ self.dercert = db.create_server_cert("Server-Cert", self.fqdn, ca_db)
db.create_signing_cert("Signing-Cert", "Object Signing Cert", ca_db)
db.create_password_conf()
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index a33ab233c..c4a20b545 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -32,6 +32,7 @@ from ipapython import sysrestore
from ipapython import ipautil
from ipalib import util
from ipalib import errors
+from ipalib import uuid
from ipaserver import ipaldap
@@ -91,6 +92,40 @@ class KrbInstance(service.Service):
else:
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
+ def move_service_to_host(self, principal):
+ """
+ Used to move a host/ service principal created by kadmin.local from
+ cn=kerberos to reside under the host entry.
+ """
+ conn = None
+
+ service_dn = "krbprincipalname=%s,cn=%s,cn=kerberos,%s" % (principal, self.realm, self.suffix)
+ try:
+ conn = ipaldap.IPAdmin("127.0.0.1")
+ conn.simple_bind_s("cn=directory manager", self.admin_password)
+ except Exception, e:
+ logging.critical("Could not connect to the Directory Server on %s" % self.fqdn)
+ raise e
+ service_entry = conn.getEntry(service_dn, ldap.SCOPE_BASE)
+ conn.deleteEntry(service_dn)
+
+ # Create a host entry for this master
+ host_dn = "fqdn=%s,cn=computers,cn=accounts,%s" % (self.fqdn, self.suffix)
+ host_entry = ipaldap.Entry(host_dn)
+ host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux'])
+ host_entry.setValue('krbextradata', service_entry.getValue('krbextradata'))
+ host_entry.setValue('krblastpwdchange', service_entry.getValue('krblastpwdchange'))
+ host_entry.setValue('krbpasswordexpiration', service_entry.getValue('krbpasswordexpiration'))
+ host_entry.setValue('krbprincipalname', service_entry.getValue('krbprincipalname'))
+ host_entry.setValue('krbticketflags', service_entry.getValue('krbticketflags'))
+ host_entry.setValue('krbprincipalkey', service_entry.getValue('krbprincipalkey'))
+ host_entry.setValue('serverhostname', self.fqdn.split('.',1)[0])
+ host_entry.setValue('cn', self.fqdn)
+ host_entry.setValue('fqdn', self.fqdn)
+ host_entry.setValue('ipauniqueid', str(uuid.uuid1()))
+ conn.addEntry(host_entry)
+ conn.unbind()
+
def __common_setup(self, ds_user, realm_name, host_name, domain_name, admin_password):
self.ds_user = ds_user
self.fqdn = host_name
@@ -404,6 +439,7 @@ class KrbInstance(service.Service):
def __create_ds_keytab(self):
ldap_principal = "ldap/" + self.fqdn + "@" + self.realm
installutils.kadmin_addprinc(ldap_principal)
+ self.move_service(ldap_principal)
self.fstore.backup_file("/etc/dirsrv/ds.keytab")
installutils.create_keytab("/etc/dirsrv/ds.keytab", ldap_principal)
@@ -424,6 +460,8 @@ class KrbInstance(service.Service):
os.chown("/etc/krb5.keytab", 0, 0)
os.chmod("/etc/krb5.keytab", 0600)
+ self.move_service_to_host(host_principal)
+
def __export_kadmin_changepw_keytab(self):
installutils.kadmin_modprinc("kadmin/changepw", "+requires_preauth")
diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index c90f153db..ad2067c09 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -28,7 +28,7 @@ import sys
from ipaserver.install import installutils
from ipaserver import ipaldap
from ipapython import entity, ipautil
-from ipalib import util
+from ipalib import util, uuid
from ipalib import errors
import ldap
import logging
@@ -124,6 +124,7 @@ class LDAPUpdate:
def _template_str(self, s):
try:
+ self.sub_dict["UUID"] = str(uuid.uuid1())
return ipautil.template_str(s, self.sub_dict)
except KeyError, e:
raise BadSyntax("Unknown template keyword %s" % e)
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 758688982..5e2eb63dc 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -22,6 +22,10 @@ import os
import tempfile
from ipapython import sysrestore
from ipapython import ipautil
+from ipalib import uuid, errors
+import ldap
+from ipaserver import ipaldap
+import base64
def stop(service_name, instance_name=""):
@@ -98,6 +102,7 @@ class Service:
path = ipautil.SHARE_DIR + ldif
if sub_dict is not None:
+ sub_dict['UUID'] = str(uuid.uuid1())
txt = ipautil.template_file(path, sub_dict)
fd = ipautil.write_tmp_file(txt)
path = fd.name
@@ -120,6 +125,61 @@ class Service:
if fd is not None:
fd.close()
+ def move_service(self, principal):
+ """
+ Used to move a principal entry created by kadmin.local from
+ cn=kerberos to cn=services
+ """
+ dn = "krbprincipalname=%s,cn=%s,cn=kerberos,%s" % (principal, self.realm, self.suffix)
+ try:
+ conn = ipaldap.IPAdmin("127.0.0.1")
+ conn.simple_bind_s("cn=directory manager", self.dm_password)
+ except Exception, e:
+ logging.critical("Could not connect to the Directory Server on %s: %s" % (self.fqdn, str(e)))
+ raise e
+ try:
+ entry = conn.getEntry(dn, ldap.SCOPE_BASE)
+ except errors.NotFound:
+ # There is no service in the wrong location, nothing to do.
+ # This can happen when installing a replica
+ conn.unbind()
+ return
+ newdn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (principal, self.suffix)
+ conn.deleteEntry(dn)
+ entry.dn = newdn
+ classes = entry.getValues("objectclass")
+ classes = classes + ["ipaobject", "ipaservice", "pkiuser"]
+ entry.setValues("objectclass", list(set(classes)))
+ entry.setValue("ipauniqueid", str(uuid.uuid1()))
+ conn.addEntry(entry)
+ conn.unbind()
+ return newdn
+
+ def add_cert_to_service(self):
+ """
+ Add a certificate to a service
+
+ This should be passed in DER format but we'll be nice and convert
+ a base64-encoded cert if needed.
+ """
+ try:
+ self.dercert = base64.b64decode(self.dercert)
+ except Exception:
+ pass
+ dn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (self.principal, self.suffix)
+ try:
+ conn = ipaldap.IPAdmin("127.0.0.1")
+ conn.simple_bind_s("cn=directory manager", self.dm_password)
+ except Exception, e:
+ logging.critical("Could not connect to the Directory Server on %s: %s" % (self.fqdn, str(e)))
+ raise e
+ mod = [(ldap.MOD_ADD, 'userCertificate', self.dercert)]
+ try:
+ conn.modify_s(dn, mod)
+ except Exception, e:
+ logging.critical("Could not add certificate to service %s entry: %s" % (self.principal, str(e)))
+ conn.unbind()
+
def set_output(self, fd):
self.output_fd = fd