diff options
-rw-r--r-- | install/share/Makefile.am | 1 | ||||
-rw-r--r-- | install/share/default-caacl.ldif | 11 | ||||
-rw-r--r-- | install/updates/50-dogtag10-migration.update | 1 | ||||
-rw-r--r-- | ipalib/plugins/caacl.py | 8 | ||||
-rw-r--r-- | ipaserver/install/ca.py | 5 | ||||
-rw-r--r-- | ipaserver/install/cainstance.py | 100 | ||||
-rw-r--r-- | ipaserver/install/dsinstance.py | 4 | ||||
-rw-r--r-- | ipaserver/install/server/replicainstall.py | 3 | ||||
-rw-r--r-- | ipaserver/install/server/upgrade.py | 13 |
9 files changed, 90 insertions, 56 deletions
diff --git a/install/share/Makefile.am b/install/share/Makefile.am index 92508a9ba..42f3972e1 100644 --- a/install/share/Makefile.am +++ b/install/share/Makefile.am @@ -31,7 +31,6 @@ app_DATA = \ caJarSigningCert.cfg.template \ custodia.conf.template \ default-aci.ldif \ - default-caacl.ldif \ default-hbac.ldif \ default-smb-group.ldif \ default-trust-view.ldif \ diff --git a/install/share/default-caacl.ldif b/install/share/default-caacl.ldif deleted file mode 100644 index f3cd5b4d4..000000000 --- a/install/share/default-caacl.ldif +++ /dev/null @@ -1,11 +0,0 @@ -# default CA ACL that grants use of caIPAserviceCert on top-level CA to all hosts and services -dn: ipauniqueid=autogenerate,cn=caacls,cn=ca,$SUFFIX -changetype: add -objectclass: ipaassociation -objectclass: ipacaacl -ipauniqueid: autogenerate -cn: hosts_services_caIPAserviceCert -ipaenabledflag: TRUE -ipamembercertprofile: cn=caIPAserviceCert,cn=certprofiles,cn=ca,$SUFFIX -hostcategory: all -servicecategory: all diff --git a/install/updates/50-dogtag10-migration.update b/install/updates/50-dogtag10-migration.update index 2ab9d15bd..0070c308a 100644 --- a/install/updates/50-dogtag10-migration.update +++ b/install/updates/50-dogtag10-migration.update @@ -16,3 +16,4 @@ addifexist:resourceACLS:certServer.ca.groups:execute:allow (execute) group="Admi addifexist:resourceACLS:certServer.ca.users:execute:allow (execute) group="Administrators":Admins may execute user operations replace:resourceACLS:certServer.securitydomain.domainxml:read,modify:allow (read) user="anybody";allow (modify) group="Subsystem Group":Anybody is allowed to read domain.xml but only Subsystem group is allowed to modify the domain.xml::certServer.securitydomain.domainxml:read,modify:allow (read) user="anybody";allow (modify) group="Subsystem Group" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Anybody is allowed to read domain.xml but only Subsystem group and Enterprise Administrators are allowed to modify the domain.xml replace:resourceACLS:certServer.ca.connectorInfo:read,modify:allow (modify,read) group="Enterprise KRA Administrators":Only Enterprise Administrators are allowed to update the connector information::certServer.ca.connectorInfo:read,modify:allow (read) group="Enterprise KRA Administrators";allow (modify) group="Enterprise KRA Administrators" || group="Subsystem Group":Only Enterprise Administrators and Subsystem Group are allowed to update the connector information +addifexist:resourceACLS:certServer.profile.configuration:read,modify:allow (read,modify) group="Certificate Manager Agents":Certificate Manager agents may modify (create/update/delete) and read profiles diff --git a/ipalib/plugins/caacl.py b/ipalib/plugins/caacl.py index 247d6df14..64dbec16e 100644 --- a/ipalib/plugins/caacl.py +++ b/ipalib/plugins/caacl.py @@ -307,6 +307,14 @@ class caacl_del(LDAPDelete): msg_summary = _('Deleted CA ACL "%(value)s"') + def pre_callback(self, ldap, dn, *keys, **options): + if keys[0] == 'hosts_services_caIPAserviceCert': + raise errors.ProtectedEntryError( + label=_("CA ACL"), + key=keys[0], + reason=_("default CA ACL can be only disabled")) + return dn + @register() class caacl_mod(LDAPUpdate): diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index 8d0252cbb..51871f2dc 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -138,9 +138,10 @@ def install_step_0(standalone, replica_config, options): if standalone: api.Backend.ldap2.disconnect() - cainstance.install_replica_ca(replica_config, postinstall) + cainstance.install_replica_ca(replica_config, postinstall, + ra_p12=getattr(options, 'ra_p12', None)) - if standalone: + if standalone and not api.Backend.ldap2.isconnected(): api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 448e42e2b..90edb362f 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -410,7 +410,7 @@ class CAInstance(DogtagInstance): cert_file=None, cert_chain_file=None, master_replication_port=None, subject_base=None, ca_signing_algorithm=None, - ca_type=None): + ca_type=None, ra_p12=None): """Create a CA instance. For Dogtag 9, this may involve creating the pki-ca instance. @@ -484,7 +484,10 @@ class CAInstance(DogtagInstance): self.step("requesting RA certificate from CA", self.__request_ra_certificate) self.step("issuing RA agent certificate", self.__issue_ra_cert) self.step("adding RA agent as a trusted user", self.__create_ca_agent) - self.step("authorizing RA to modify profiles", self.__configure_profiles_acl) + elif ra_p12 is not None: + self.step("importing RA certificate from PKCS #12 file", + lambda: self.import_ra_cert(ra_p12, configure_renewal=False)) + self.step("authorizing RA to modify profiles", configure_profiles_acl) self.step("configure certmonger for renewals", self.configure_certmonger_renewal) self.step("configure certificate renewals", self.configure_renewal) if not self.clone: @@ -492,9 +495,12 @@ class CAInstance(DogtagInstance): self.step("configure Server-Cert certificate renewal", self.track_servercert) self.step("Configure HTTP to proxy connections", self.http_proxy) - if not self.clone: - self.step("restarting certificate server", self.restart_instance) - self.step("Importing IPA certificate profiles", import_included_profiles) + self.step("restarting certificate server", self.restart_instance) + self.step("migrating certificate profiles to LDAP", + migrate_profiles_to_ldap) + self.step("importing IPA certificate profiles", + import_included_profiles) + self.step("adding default CA ACL", ensure_default_caacl) self.start_creation(runtime=210) @@ -921,7 +927,7 @@ class CAInstance(DogtagInstance): export_kra_agent_pem() - def import_ra_cert(self, rafile): + def import_ra_cert(self, rafile, configure_renewal=True): """ Cloned RAs will use the same RA agent cert as the master so we need to import from a PKCS#12 file. @@ -937,7 +943,8 @@ class CAInstance(DogtagInstance): finally: os.remove(agent_name) - self.configure_agent_renewal() + if configure_renewal: + self.configure_agent_renewal() export_kra_agent_pem() @@ -987,10 +994,6 @@ class CAInstance(DogtagInstance): conn.disconnect() - def __configure_profiles_acl(self): - """Allow the Certificate Manager Agents group to modify profiles.""" - configure_profiles_acl() - def __run_certutil(self, args, database=None, pwd_file=None, stdin=None): if not database: database = self.ra_agent_db @@ -1654,7 +1657,7 @@ def replica_ca_install_check(config): exit('IPA schema missing on master CA directory server') -def install_replica_ca(config, postinstall=False): +def install_replica_ca(config, postinstall=False, ra_p12=None): """ Install a CA on a replica. @@ -1691,7 +1694,7 @@ def install_replica_ca(config, postinstall=False): ca.create_ra_agent_db = False ca.configure_instance(config.host_name, config.dirman_password, config.dirman_password, - pkcs12_info=(cafile,), + pkcs12_info=(cafile,), ra_p12=ra_p12, master_host=config.master_host_name, master_replication_port=config.ca_ds_port, subject_base=config.subject_base) @@ -1816,6 +1819,14 @@ def update_people_entry(dercert): return True def ensure_ldap_profiles_container(): + ensure_entry( + DN(('ou', 'certificateProfiles'), ('ou', 'ca'), ('o', 'ipaca')), + objectclass=['top', 'organizationalUnit'], + ou=['certificateProfiles'], + ) + + +def ensure_entry(dn, **attrs): server_id = installutils.realm_to_serverid(api.env.realm) dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id @@ -1823,40 +1834,39 @@ def ensure_ldap_profiles_container(): if not conn.isconnected(): conn.connect(autobind=True) - dn = DN(('ou', 'certificateProfiles'), ('ou', 'ca'), ('o', 'ipaca')) try: conn.get_entry(dn) except errors.NotFound: # entry doesn't exist; add it - entry = conn.make_entry( - dn, - objectclass=['top', 'organizationalUnit'], - ou=['certificateProfiles'], - ) + entry = conn.make_entry(dn, **attrs) conn.add_entry(entry) conn.disconnect() def configure_profiles_acl(): + """Allow the Certificate Manager Agents group to modify profiles.""" server_id = installutils.realm_to_serverid(api.env.realm) dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id updated = False dn = DN(('cn', 'aclResources'), ('o', 'ipaca')) - rule = ( + new_rules = [ 'certServer.profile.configuration:read,modify:allow (read,modify) ' 'group="Certificate Manager Agents":' - 'Certificate Manager agents may modify (create/update/delete) and read profiles' - ) - modlist = [(ldap.MOD_ADD, 'resourceACLS', [rule])] + 'Certificate Manager agents may modify (create/update/delete) and read profiles', + + 'certServer.ca.account:login,logout:allow (login,logout) ' + 'user="anybody":Anybody can login and logout', + ] conn = ldap2.ldap2(api, ldap_uri=dogtag_uri) if not conn.isconnected(): conn.connect(autobind=True) - rules = conn.get_entry(dn).get('resourceACLS', []) - if rule not in rules: - conn.conn.modify_s(str(dn), modlist) + cur_rules = conn.get_entry(dn).get('resourceACLS', []) + add_rules = [rule for rule in new_rules if rule not in cur_rules] + if add_rules: + conn.conn.modify_s(str(dn), [(ldap.MOD_ADD, 'resourceACLS', add_rules)]) updated = True conn.disconnect() @@ -1876,6 +1886,17 @@ def import_included_profiles(): if not conn.isconnected(): conn.connect(autobind=True) + ensure_entry( + DN(('cn', 'ca'), api.env.basedn), + objectclass=['top', 'nsContainer'], + cn=['ca'], + ) + ensure_entry( + DN(api.env.container_certprofile, api.env.basedn), + objectclass=['top', 'nsContainer'], + cn=['certprofiles'], + ) + api.Backend.ra_certprofile._read_password() api.Backend.ra_certprofile.override_port = 8443 @@ -1981,6 +2002,33 @@ def _create_dogtag_profile(profile_id, profile_data): "(it is probably already enabled)") +def ensure_default_caacl(): + """Add the default CA ACL if missing.""" + if not api.Backend.ldap2.isconnected(): + try: + api.Backend.ldap2.connect(autobind=True) + except errors.PublicError as e: + root_logger.error("Cannot connect to LDAP to add CA ACLs: %s", e) + return + + ensure_entry( + DN(('cn', 'ca'), api.env.basedn), + objectclass=['top', 'nsContainer'], + cn=['ca'], + ) + ensure_entry( + DN(api.env.container_caacl, api.env.basedn), + objectclass=['top', 'nsContainer'], + cn=['certprofiles'], + ) + + if not api.Command.caacl_find()['result']: + api.Command.caacl_add(u'hosts_services_caIPAserviceCert', + hostcategory=u'all', servicecategory=u'all') + api.Command.caacl_add_profile(u'hosts_services_caIPAserviceCert', + certprofile=(u'caIPAserviceCert',)) + + if __name__ == "__main__": standard_logging_setup("install.log") ds = dsinstance.DsInstance() diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 7bdcaea31..c980ebf4e 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -332,7 +332,6 @@ class DsInstance(service.Service): self.step("adding range check plugin", self.__add_range_check_plugin) if hbac_allow: self.step("creating default HBAC rule allow_all", self.add_hbac) - self.step("creating default CA ACL rule", self.add_caacl) self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings) self.step("adding entries for topology management", self.__add_topology_entries) @@ -874,9 +873,6 @@ class DsInstance(service.Service): def add_hbac(self): self._ldap_mod("default-hbac.ldif", self.sub_dict) - def add_caacl(self): - self._ldap_mod("default-caacl.ldif", self.sub_dict) - def change_admin_password(self, password): root_logger.debug("Changing admin password") dirname = config_dirname(self.serverid) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 5ce9eb709..492ea72d8 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -672,6 +672,9 @@ def install(installer): options.domain_name = config.domain_name options.host_name = config.host_name + if ipautil.file_exists(config.dir + "/cacert.p12"): + options.ra_p12 = config.dir + "/ra.p12" + ca.install(False, config, options) krb = install_krb(config, setup_pkinit=not options.no_pkinit) diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index b9621a39d..84339b0a2 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1328,18 +1328,7 @@ def add_default_caacl(ca): return if ca.is_configured(): - if not api.Backend.ldap2.isconnected(): - try: - api.Backend.ldap2.connect(autobind=True) - except ipalib.errors.PublicError as e: - root_logger.error("Cannot connect to LDAP to add CA ACLs: %s", e) - return - - if not api.Command.caacl_find()['result']: - api.Command.caacl_add(u'hosts_services_caIPAserviceCert', - hostcategory=u'all', servicecategory=u'all') - api.Command.caacl_add_profile(u'hosts_services_caIPAserviceCert', - certprofile=(u'caIPAserviceCert',)) + cainstance.ensure_default_caacl() sysupgrade.set_upgrade_state('caacl', 'add_default_caacl', True) |