diff --git a/roles/ipaclient/defaults/main.yml b/roles/ipaclient/defaults/main.yml index 890f35fde53889f7534488182e8391e4bfc1c52f..892fac4258bbb01e59c2f84f2575d2a1a373c817 100644 --- a/roles/ipaclient/defaults/main.yml +++ b/roles/ipaclient/defaults/main.yml @@ -12,12 +12,18 @@ ipaclient_no_dns_lookup: no ipaclient_ssh_trust_dns: no ipaclient_no_ssh: no ipaclient_no_sshd: no +ipaclient_no_sudo: no #ipaclient_no_dns_sshfp: no #ipaclient_force: no ipaclient_force_ntpd: no ipaclient_no_nisdomain: no ipaclient_configure_firefox: no ipahost_all_ip_addresses: no +ipassd_fixed_primary: no +ipassd_permit: no +ipassd_enable_dns_updates: no +ipassd_no_krb5_offline_passwords: no +ipassd_preserve_sssd: no ### packages ### ipaclient_install_packages: yes diff --git a/roles/ipaclient/library/ipaclient_setup_sssd.py b/roles/ipaclient/library/ipaclient_setup_sssd.py index e486f3543b42b9d0a7a226076873549dfdbd199c..f4833562e3a9fc12b59738ce526d3cf8dee29315 100644 --- a/roles/ipaclient/library/ipaclient_setup_sssd.py +++ b/roles/ipaclient/library/ipaclient_setup_sssd.py @@ -30,10 +30,10 @@ ANSIBLE_METADATA = { DOCUMENTATION = ''' --- -module: ipaclient_setup_sssd -short description: Configure sssd for IPA client +module: ipaclient_setup_ssd +short description: Setup sssd for IPA client description: - Configure sssd for IPA client + Setup sssd for IPA client options: servers: description: The FQDN of the IPA servers to connect to. @@ -48,27 +48,33 @@ options: hostname: description: The hostname of the machine to join (FQDN). required: true - services: - description: The services that should be enabled in the ssd configuration. - required: true - type: list - krb5_offline_passwords: - description: Whether user passwords are stored when the server is offline. + on_master: + description: Whether the configuration is done on the master or not. required: false type: bool default: no - on_master: - description: Whether the configuration is done on the master or not. + no_ssh: + description: Do not configure OpenSSH client required: false type: bool default: no - primary: - description: Whether to use fixed server as primary IPA server. + no_sshd: + description: Do not configure OpenSSH server required: false type: bool default: no - preserve_sssd: - description: Preserve old SSSD configuration if possible. + no_sudo: + description: Do not configure SSSD as data source for sudo + required: false + type: bool + default: no + all_ip_addresses: + description: All routable IP addresses configured on any interface will be added to DNS. + required: false + type: bool + default: no + fixed_primary: + description: Whether to use fixed server as primary IPA server. required: false type: bool default: no @@ -77,13 +83,18 @@ options: required: false type: bool default: no - dns_updates: + enable_dns_updates: description: Configures the machine to attempt dns updates when the ip address changes. required: false type: bool default: no - all_ip_addresses: - description: All routable IP addresses configured on any interface will be added to DNS. + preserve_sssd: + description: Preserve old SSSD configuration if possible. + required: false + type: bool + default: no + no_krb5_offline_passwords: + description: Whether user passwords are stored when the server is offline. required: false type: bool default: no @@ -98,32 +109,15 @@ EXAMPLES = ''' domain: example.com realm: EXAMPLE.COM hostname: client1.example.com - services: ["ssh", "sudo"] - cache_credentials: yes - krb5_offline_passwords: yes + no_krb5_offline_passwords: yes ''' RETURN = ''' ''' -import os -import sys -import tempfile -import SSSDConfig - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_client import * -def sssd_enable_service(module, sssdconfig, service): - try: - sssdconfig.new_service(service) - except SSSDConfig.ServiceAlreadyExists: - pass - except SSSDConfig.ServiceNotRecognizedError: - module.fail_json( - msg="Unable to activate the %s service in SSSD config." % service) - sssdconfig.activate_service(service) - def main(): module = AnsibleModule( argument_spec = dict( @@ -131,149 +125,54 @@ def main(): domain=dict(required=True), realm=dict(required=True), hostname=dict(required=True), - services=dict(required=True, type='list'), - krb5_offline_passwords=dict(required=False, type='bool'), on_master=dict(required=False, type='bool'), - primary=dict(required=False, type='bool'), - preserve_sssd=dict(required=False, type='bool'), - permit=dict(required=False, type='bool'), - dns_updates=dict(required=False, type='bool'), + no_ssh=dict(required=False, type='bool'), + no_sshd=dict(required=False, type='bool'), + no_sudo=dict(required=False, type='bool'), all_ip_addresses=dict(required=False, type='bool'), + + fixed_primary=dict(required=False, type='bool'), + permit=dict(required=False, type='bool'), + enable_dns_updates=dict(required=False, type='bool'), + preserve_sssd=dict(required=False, type='bool'), + no_krb5_offline_passwords=dict(required=False, type='bool'), ), supports_check_mode = True, ) + #ansible_log = AnsibleModuleLog(module, logger) + #options.set_logger(ansible_log) module._ansible_debug = True - cli_servers = module.params.get('servers') + cli_server = module.params.get('servers') cli_domain = module.params.get('domain') cli_realm = module.params.get('realm') - client_hostname = module.params.get('hostname') - services = module.params.get('services') - krb5_offline_passwords = module.params.get('krb5_offline_passwords') - on_master = module.params.get('on_master') - primary = module.params.get('primary') - preserve_sssd = module.params.get('preserve_sssd') - permit = module.params.get('permit') - dns_updates = module.params.get('dns_updates') - all_ip_addresses = module.params.get('all_ip_addresses') + hostname = module.params.get('hostname') + options.on_master = module.params.get('on_master') + + options.no_ssh = module.params.get('no_ssh') + options.conf_ssh = not options.no_ssh + options.no_sshd = module.params.get('no_sshd') + options.conf_sshd = not options.no_sshd + options.no_sudo = module.params.get('no_sudo') + options.conf_sudo = not options.no_sudo + options.all_ip_addresses = module.params.get('all_ip_addresses') + + options.primary = module.params.get('fixed_primary') + options.permit = module.params.get('permit') + options.dns_updates = module.params.get('enable_dns_updates') + options.preserve_sssd = module.params.get('preserve_sssd') + + options.no_krb5_offline_passwords = module.params.get( + 'krb5_offline_passwords') + options.krb5_offline_passwords = not options.no_krb5_offline_passwords fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) - client_domain = client_hostname[client_hostname.find(".")+1:] - - try: - sssdconfig = SSSDConfig.SSSDConfig() - sssdconfig.import_config() - except Exception as e: - if os.path.exists(paths.SSSD_CONF) and preserve_sssd: - # SSSD config is in place but we are unable to read it - # In addition, we are instructed to preserve it - # This all means we can't use it and have to bail out - module.fail_json( - msg="SSSD config exists but cannot be parsed: %s" % str(e)) - - # SSSD configuration does not exist or we are not asked to preserve it, - # create new one - # We do make new SSSDConfig instance because IPAChangeConf-derived - # classes have no means to reset their state and ParseError exception - # could come due to parsing error from older version which cannot be - # upgraded anymore, leaving sssdconfig instance practically unusable - # Note that we already backed up sssd.conf before going into this - # routine - if isinstance(e, IOError): - pass - else: - # It was not IOError so it must have been parsing error - module.fail_json(msg="Unable to parse existing SSSD config.") - - module.log("New SSSD config will be created") - sssdconfig = SSSDConfig.SSSDConfig() - sssdconfig.new_config() - - try: - domain = sssdconfig.new_domain(cli_domain) - except SSSDConfig.DomainAlreadyExistsError: - module.log("Domain %s is already configured in existing SSSD " - "config, creating a new one." % cli_domain) - sssdconfig = SSSDConfig.SSSDConfig() - sssdconfig.new_config() - domain = sssdconfig.new_domain(cli_domain) - - if on_master: - sssd_enable_service(module, sssdconfig, 'ifp') - - if (("ssh" in services and os.path.isfile(paths.SSH_CONFIG)) or - ("sshd" in services and os.path.isfile(paths.SSHD_CONFIG))): - sssd_enable_service(module, sssdconfig, 'ssh') - - if "sudo" in services: - sssd_enable_service(module, sssdconfig, 'sudo') - configure_nsswitch_database(fstore, 'sudoers', ['sss'], - default_value=['files']) - - domain.add_provider('ipa', 'id') - - # add discovery domain if client domain different from server domain - # do not set this config in server mode (#3947) - if not on_master and cli_domain != client_domain: - domain.set_option('dns_discovery_domain', cli_domain) - - if not on_master: - if primary: - domain.set_option('ipa_server', ', '.join(cli_servers)) - else: - domain.set_option('ipa_server', - '_srv_, %s' % ', '.join(cli_servers)) - else: - domain.set_option('ipa_server_mode', 'True') - # the master should only use itself for Kerberos - domain.set_option('ipa_server', cli_servers[0]) - - # increase memcache timeout to 10 minutes when in server mode - try: - nss_service = sssdconfig.get_service('nss') - except SSSDConfig.NoServiceError: - nss_service = sssdconfig.new_service('nss') - - nss_service.set_option('memcache_timeout', 600) - sssdconfig.save_service(nss_service) - - domain.set_option('ipa_domain', cli_domain) - domain.set_option('ipa_hostname', client_hostname) - if cli_domain.lower() != cli_realm.lower(): - domain.set_option('krb5_realm', cli_realm) - - # Might need this if /bin/hostname doesn't return a FQDN - # domain.set_option('ipa_hostname', 'client.example.com') - - domain.add_provider('ipa', 'auth') - domain.add_provider('ipa', 'chpass') - if not permit: - domain.add_provider('ipa', 'access') - else: - domain.add_provider('permit', 'access') - - domain.set_option('cache_credentials', True) - - # SSSD will need TLS for checking if ipaMigrationEnabled attribute is set - # Note that SSSD will force StartTLS because the channel is later used for - # authentication as well if password migration is enabled. Thus set - # the option unconditionally. - domain.set_option('ldap_tls_cacert', paths.IPA_CA_CRT) - - if dns_updates: - domain.set_option('dyndns_update', True) - if all_ip_addresses: - domain.set_option('dyndns_iface', '*') - else: - iface = get_server_connection_interface(cli_servers[0]) - domain.set_option('dyndns_iface', iface) - if krb5_offline_passwords: - domain.set_option('krb5_store_password_if_offline', True) - - domain.set_active(True) + client_domain = hostname[hostname.find(".")+1:] - sssdconfig.save_domain(domain) - sssdconfig.write(paths.SSSD_CONF) + if configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server, + options, client_domain, hostname): + module.fail_json("configure_sssd_conf failed") + logger.info("Configured /etc/sssd/sssd.conf") module.exit_json(changed=True) diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml index ba16a9a72b952568999077341d17b81ba09a1c29..a9a06702ee8e41204d2e853e46f61e1a4b4bf41d 100644 --- a/roles/ipaclient/tasks/install.yml +++ b/roles/ipaclient/tasks/install.yml @@ -216,13 +216,17 @@ domain: "{{ result_ipaclient_test.domain }}" realm: "{{ result_ipaclient_test.realm }}" hostname: "{{ result_ipaclient_test.hostname }}" - services: ["ssh", "sudo"] - krb5_offline_passwords: yes on_master: "{{ ipaclient_on_master }}" - #primary: no - #permit: no - #dns_updates: no - #all_ip_addresses: no + no_ssh: "{{ ipaclient_no_ssh }}" + no_sshd: "{{ ipaclient_no_sshd }}" + no_sudo: "{{ ipaclient_no_sudo }}" + all_ip_addresses: "{{ ipahost_all_ip_addresses }}" + + fixed_primary: "{{ ipassd_fixed_primary }}" + permit: "{{ ipassd_permit }}" + enable_dns_updates: "{{ ipassd_enable_dns_updates }}" + preserve_sssd: "{{ ipassd_preserve_sssd }}" + no_krb5_offline_passwords: "{{ ipassd_no_krb5_offline_passwords }}" - name: Install - Configure krb5 for IPA realm "{{ result_ipaclient_test.realm }} <= 4.4" include_role: