--- - set_fact: samba_tls_cert={{ '/var/lib/dehydrated/certificates/certs/' + samba_letsencrypt_cert + '/fullchain.pem' }} when: samba_letsencrypt_cert is defined tags: [cert,samba] - set_fact: samba_tls_key={{ '/var/lib/dehydrated/certificates/certs/' + samba_letsencrypt_cert + '/privkey.pem' }} when: samba_letsencrypt_cert is defined tags: [cert,samba] - set_fact: samba_i_am_primary_dc={{ (inventory_hostname == samba_primary_dc and samba_role == 'dc') | ternary(True,False) }} tags: samba - name: Merge custom password complexity rules with default ones set_fact: samba_pwd_policy={{ samba_base_pwd_policy | combine(samba_pwd_policy) }} tags: samba - name: Install common packages yum: name: - samba - samba-client - sssd-winbind-idmap - openldap-clients - policycoreutils-python - tdb-tools tags: samba - name: Install DC components yum: name: - samba-dc - ldb-tools - krb5-workstation - python36-markdown - patch when: samba_role == 'dc' or samba_role == 'rodc' tags: samba # sssd-libwbclient breaks DC so only install on members - name: Install members components yum: name=sssd-libwbclient when: - samba_role != 'dc' - samba_role != 'rodc' tags: samba - name: Setup env var for ldb tools copy: src=ldb_modules_samba.sh dest=/etc/profile.d/ldb_modules_samba.sh mode=755 tags: samba - name: Set a default samba domain set_fact: samba_domain={{ ansible_domain | regex_replace('\.[a-z]+$','') }} when: samba_domain is not defined tags: samba - name: Check if domain is provisionned stat: path=/var/lib/samba/sysvol/{{ samba_realm }} register: samba_dc_sysvol tags: samba - name: Remove config files file: path={{ item }} state=absent with_items: - /etc/samba/smb.conf - /etc/krb5.conf when: - samba_role == 'dc' or samba_role == 'rodc' - not samba_dc_sysvol.stat.exists tags: samba - name: Stop samba services service: name={{ item }} state=stopped with_items: - samba - smb - nmb when: - samba_role == 'dc' or samba_role == 'rodc' - not samba_dc_sysvol.stat.exists tags: samba - name: Add rsyncd port set_fact: samba_dc_tcp_ports={{ samba_dc_tcp_ports + ['873'] }} when: samba_i_am_primary_dc == True tags: samba - name: Handle DNS ports iptables_raw: name: samba_dns_ports state: "{{ (samba_dns_src_ip | length > 0) | ternary('present','absent') }}" rules: "-A INPUT -m state --state NEW -p tcp -m multiport --dports {{ samba_dns_ports | join(',') }} -s {{ samba_dns_src_ip | join(',') }} -j ACCEPT\n -A INPUT -m state --state NEW -p udp -m multiport --dports {{ samba_dns_ports | join(',') }} -s {{ samba_dns_src_ip | join(',') }} -j ACCEPT" when: - iptables_manage | default(True) - samba_role == 'dc' or samba_role == 'rodc' tags: samba,firewall - name: Handle DC services ports iptables_raw: name: samba_dc_ports state: "{{ (samba_dc_src_ip | length > 0) | ternary('present','absent') }}" rules: "-A INPUT -m state --state NEW -p tcp -m multiport --dports {{ samba_dc_tcp_ports | join(',') }} -s {{ samba_dc_src_ip | join(',') }} -j ACCEPT\n -A INPUT -m state --state NEW -p udp -m multiport --dports {{ samba_dc_udp_ports | join(',') }} -s {{ samba_dc_src_ip | join(',') }} -j ACCEPT" when: - iptables_manage | default(True) - samba_role == 'dc' or samba_role == 'rodc' tags: samba,firewall - name: Handle other ports iptables_raw: name: samba_file_ports state: "{{ (samba_file_src_ip | length > 0) | ternary('present','absent') }}" rules: "-A INPUT -m state --state NEW -p tcp -m multiport --dports {{ samba_file_tcp_ports | join(',') }} -s {{ samba_file_src_ip | join(',') }} -j ACCEPT\n -A INPUT -m state --state NEW -p udp -m multiport --dports {{ samba_file_udp_ports | join(',') }} -s {{ samba_file_src_ip | join(',') }} -j ACCEPT" when: iptables_manage | default(True) tags: samba,firewall # We need to have our correct hostname before joining the domain !! - name: Set system hostname hostname: name={{ system_hostname | default(inventory_hostname | regex_replace('^([^\.]+)\..*','\\1')) }} tags: samba - name: Try to join the domain (as DC) command: samba-tool domain join {{ samba_realm }} DC --dns-backend SAMBA_INTERNAL --realm {{ samba_realm }} -U Administrator --password={{ samba_dc_admin_pass | quote }} when: - samba_role == 'dc' - not samba_dc_sysvol.stat.exists register: samba_dc_join ignore_errors: True tags: samba # If we're not the primary domain, and we can't join the domain # and we haven't done it yet, we must fail - name: Fail if not the primary DC and joining the domain failed fail: msg="Failed to join the domaine" when: - samba_dc_join is defined - samba_dc_join.rc is defined - samba_dc_join.rc != 0 - not samba_i_am_primary_dc == True - not samba_dc_sysvol.stat.exists tags: samba - name: Provision the domain command: samba-tool domain provision --server-role=dc --dns-backend SAMBA_INTERNAL --realm {{ samba_realm }} --domain {{ samba_domain }} --use-rfc2307 --adminpass={{ samba_dc_admin_pass | quote }} when: - not samba_dc_sysvol.stat.exists - samba_i_am_primary_dc == True - samba_dc_join.rc != 0 tags: samba - name: Join the domain (as RODC) command: samba-tool domain join {{ samba_realm }} RODC --dns-backend SAMBA_INTERNAL --realm {{ samba_realm }} -U Administrator --password={{ samba_dc_admin_pass | quote }} no_log: True when: - samba_role == 'rodc' - not samba_dc_sysvol.stat.exists tags: samba - name: Link our DC keytab file: src=/var/lib/samba/private/secrets.keytab dest=/etc/krb5.keytab state=link remote_src=True when: samba_role == 'dc' or samba_role == 'rodc' tags: samba # This is for DC where their principal is added as uppercase HOST/FQDN # it mostly work, except for ssh kerberos auth which requires lower case host/fqdn principal - name: Check if the keytab contains lowercase host principal shell: klist -k /etc/krb5.keytab | grep 'host/{{ ansible_hostname }}.{{ samba_realm }}' ignore_errors: True when: samba_role == 'dc' or samba_role == 'rodc' changed_when: False register: samba_lc_principal tags: samba - name: Add lower case host principal to the keytab file command: samba-tool domain exportkeytab /etc/krb5.keytab --principal=host/{{ ansible_hostname }}.{{ samba_realm }} when: - samba_role == 'dc' or samba_role == 'rodc' - samba_lc_principal.stdout_lines | length < 1 tags: samba - name: Add a tmpfiles.d snippet for permission on ntp_signd socket dir copy: content="d /var/lib/samba/ntp_signd 750 root ntp" dest=/etc/tmpfiles.d/samba_ntp.conf when: samba_role == 'dc' or samba_role == 'rodc' notify: systemd-tmpfiles tags: sambai - name: Set correct SELinux context on the ntp_signd socket dir sefcontext: target: "/var/lib/samba/ntp_signd(/.*)?" setype: ntpd_var_run_t state: present when: - ansible_selinux.status == 'enabled' - samba_role == 'dc' or samba_role == 'rodc' register: samba_ntp_selinux tags: samba - name: Restore SELinux context command: restorecon -R /var/lib/samba/ when: - ansible_selinux.status == 'enabled' - samba_ntp_selinux.changed tags: samba - name: Deploy rsyncd snippet template: src=rsyncd.conf.j2 dest=/etc/rsyncd.conf.d/samba_dc.conf when: samba_i_am_primary_dc == True tags: samba - name: Remove rsyncd snippet file: path=/etc/rsyncd.conf.d/samba_dc.conf state=absent when: not samba_i_am_primary_dc == True tags: samba - name: Deploy sysvol rsync password file copy: content={{ (samba_sysvol_rsync_pass is defined) | ternary(samba_i_am_primary_dc | ternary('sysvol-replication:','') + samba_sysvol_rsync_pass,'# No password defined') }} dest=/etc/samba/rsync-sysvol.secret mode=600 tags: samba - name: Setup cron to sync sysvol from primary DC cron: name: samba_sync_sysvol cron_file: samba_sync_sysvol minute: '*/16' user: root job: rsync -XAavz --delete-after {{ (samba_sysvol_rsync_pass is defined) | ternary('--password-file=/etc/samba/rsync-sysvol.secret','') }} rsync://{{ (samba_sysvol_rsync_pass is defined) | ternary('sysvol-replication@','') }}{{ samba_primary_dc }}/sysvol/ /var/lib/samba/sysvol/ state: "{{ samba_i_am_primary_dc | ternary('absent','present') }}" when: samba_role == 'dc' or samba_role == 'rodc' tags: samba - name: Create dehydrated hook dir file: path=/etc/dehydrated/hooks_deploy_cert.d/ state=directory when: samba_role == 'dc' or samba_role == 'rodc' tags: samba - name: Deploy dehydrated hook copy: src=dehydrated_deploy_hook dest=/etc/dehydrated/hooks_deploy_cert.d/samba.sh mode=755 when: samba_role == 'dc' or samba_role == 'rodc' tags: samba - name: Remove dehydrated hook file: path=/etc/dehydrated/hooks_deploy_cert.d/samba.sh state=absent when: samba_role != 'dc' and samba_role != 'rodc' tags: samba - name: Create samba tls dir file: path=/var/lib/samba/private/tls state=directory mode=700 tags: samba - name: Create DH param command: openssl dhparam -out /var/lib/samba/private/tls/dhparam.pem 2048 args: creates: /var/lib/samba/private/tls/dhparam.pem tags: samba - name: Deploy smb.conf template: src=smb.conf.j2 dest=/etc/samba/smb.conf notify: reload samba tags: samba - name: Create conf.d directory file: path=/etc/samba/smb.conf.d/ state=directory tags: samba - name: Check if there's a shares.conf snippet stat: path=/etc/samba/smb.conf.d/shares.conf register: samba_shares_snippet tags: samba - name: Deploy an empty shares conf snippet copy: content="# No shares defined yet" dest=/etc/samba/smb.conf.d/shares.conf when: not samba_shares_snippet.stat.exists tags: samba - name: Check if /etc/krb5.conf exists stat: path=/etc/krb5.conf register: samba_krb5_conf tags: samba - name: Start and enable the samba daemon service: name=samba state=started enabled=True when: samba_role == 'dc' or samba_role == 'rodc' tags: samba - name: Reconfigure sssd include_role: name=sssd_ad_auth when: - not samba_krb5_conf.stat.exists tags: samba - name: Check if winbind_cache exists stat: path=/var/lib/samba/winbindd_cache.tdb register: samba_winbind_cache tags: samba - include_tasks: member_join.yml when: - samba_role == 'member' - not samba_winbind_cache.stat.exists - name: Start and enable the smb daemon service: name=smb state=started enabled=True when: samba_role != 'dc' and samba_role != 'rodc' tags: samba # Here we just read the actual policy. This way, on the next task, we can update only the items we need - name: Check current password policy shell: "samba-tool domain passwordsettings show | perl -ne 'm/^{{ samba_pwd_policy_descriptions[item] }}: (.*)/ && print $1'" register: samba_dc_current_pwd_policy changed_when: False with_items: "{{ samba_pwd_policy.keys() | list }}" when: samba_i_am_primary_dc == True tags: samba - name: Set password policy command: samba-tool domain passwordsettings set --{{ item.item }}={{ samba_pwd_policy[item.item] }} with_items: "{{ samba_dc_current_pwd_policy.results }}" when: - samba_i_am_primary_dc == True - item.stdout | string != samba_pwd_policy[item.item] | string tags: samba - name: Add default zones to the list of managed ones set_fact: samba_dns_zones={{ samba_dns_zones | default([]) + [ samba_realm | lower, '_msdcs.' + samba_realm | lower ] }} when: samba_i_am_primary_dc == True tags: samba - name: Check existing DNS zones shell: samba-tool dns zonelist {{ ansible_all_ipv4_addresses | first }} -U Administrator --password={{ samba_dc_admin_pass | quote }} | perl -ne 'm/pszZoneName\s+:\s+(.*)/ && print "$1\n"' register: samba_existing_zones no_log: True changed_when: False when: samba_i_am_primary_dc == True tags: samba - name: Create DNS zones command: samba-tool dns zonecreate {{ ansible_all_ipv4_addresses | first }} {{ item }} -U Administrator --password={{ samba_dc_admin_pass | quote }} no_log: True when: samba_i_am_primary_dc == True with_items: "{{ samba_dns_zones | difference(samba_existing_zones.stdout_lines) }}" tags: samba - name: Remove DNS zones command: samba-tool dns zonedelete {{ ansible_all_ipv4_addresses | first }} {{ item }} -U Administrator --password={{ samba_dc_admin_pass | quote }} no_log: True when: - samba_i_am_primary_dc == True - samba_remove_unmanaged_dns_zones == True with_items: "{{ samba_existing_zones.stdout_lines | difference(samba_dns_zones) }}" tags: samba - name: Create backup scripts dir file: path=/etc/backup/{{ item }}.d state=directory with_items: - pre - post tags: samba - name: Deploy pre and post backup script template: src={{ item.src }} dest={{ item.dest }} mode=755 with_items: - src: samba_pre_backup.sh.j2 dest: /etc/backup/pre.d/samba.sh - src: samba_post_backup.sh.j2 dest: /etc/backup/post.d/samba.sh tags: samba - name: Set SEbool seboolean: name={{ item }} state=True persistent=True when: samba_role == 'dc' or samba_role == 'rodc' with_items: - samba_domain_controller tags: samba - name: Create samba scripts dir file: path=/var/lib/samba/scripts state=directory tags: samba - include: filebeat.yml