---
# ---
# Samba Server
# ---

- name: (samba-config-server.yml) Ensure samba packages server are installed.
  package:
    pkg: "{{ apt_install_server_samba }}"
    state: present
  when:
    - inventory_hostname in groups['samba_server']
  tags:
    - samba-server

- name: (samba-config-server.yml) Ensure quarantine directory exists
  file:
    path: /data/samba/QUARANTINE
    owner: root
    group: root
    mode: "0750"
    state: directory
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure samba share directories exists
  file:
    path: "{{ item.path }}"
    owner: "root"
    group: "{{ item.group_write_list | default('root', true) }}"
    mode: "{{ item.dir_create_mask | default('2770', true) }}"
    state: directory
    recurse: no
  with_items: "{{ samba_shares }}"
  loop_control:
    label: "{{ item.name }}"
  when:
    - inventory_hostname in groups['samba_server']
  tags:
    - samba-shares

# ---
# Virusfilter (ClamAV) - only when at least one share has vfs_object_virusfilter: true
# ---

- name: (samba-config-server.yml) Ensure virusfilter (ClamAV) packages are installed
  package:
    pkg: "{{ apt_install_server_samba_virusfilter }}"
    state: present
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Check if ClamAV virus databases are present
  find:
    paths: /var/lib/clamav
    patterns:
      - "*.cvd"
      - "*.cld"
  register: clamav_db_files
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Stop clamav-freshclam service before initial database download
  service:
    name: clamav-freshclam
    state: stopped
  failed_when: false
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
    - clamav_db_files.files | length == 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure clamav-daemon service is started before database update
  service:
    name: clamav-daemon
    state: started
    enabled: yes
  failed_when: false
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Download initial ClamAV virus databases via freshclam
  command: freshclam
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
    - clamav_db_files.files | length == 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure clamav-daemon service is enabled and started
  service:
    name: clamav-daemon
    state: started
    enabled: yes
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure clamav-freshclam service is enabled and started
  service:
    name: clamav-freshclam
    state: started
    enabled: yes
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure clamav user is member of all Samba groups
  user:
    name: clamav
    groups: "{{ item.name }}"
    append: yes
  loop: "{{ samba_groups }}"
  loop_control:
    label: "{{ item.name }}"
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
      selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
    - samba_groups | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure clamav user is member of all Samba user groups (homes virusfilter)
  user:
    name: clamav
    groups: "{{ item.name }}"
    append: yes
  loop: "{{ samba_user }}"
  loop_control:
    label: "{{ item.name }}"
  when:
    - inventory_hostname in groups['samba_server']
    - samba_homes_virusfilter | default(false) | bool
    - samba_user | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Get home directories of samba users via getent (homes virusfilter)
  ansible.builtin.getent:
    database: passwd
    key: "{{ item.name }}"
  loop: "{{ samba_user }}"
  loop_control:
    label: "{{ item.name }}"
  register: samba_user_getent
  when:
    - inventory_hostname in groups['samba_server']
    - samba_homes_virusfilter | default(false) | bool
    - samba_user | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure home directories are group-traversable for clamd (homes virusfilter)
  file:
    path: "{{ item.ansible_facts.getent_passwd[item.item.name][4] }}"
    mode: "0750"
    state: directory
  loop: "{{ samba_user_getent.results | default([]) }}"
  loop_control:
    label: "{{ item.item.name }}"
  when:
    - inventory_hostname in groups['samba_server']
    - samba_homes_virusfilter | default(false) | bool
    - item.ansible_facts is defined
  tags:
    - samba-server
    - samba-virusfilter


- name: (samba-config-server.yml) Configure AppArmor local profile for clamd (data paths)
  template:
    src: etc/apparmor.d/local/usr.sbin.clamd.j2
    dest: /etc/apparmor.d/local/usr.sbin.clamd
    owner: root
    group: root
    mode: "0644"
  notify: 
    - Reload AppArmor profile clamd
    - Restart clamav-daemon
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
      selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

- name: (samba-config-server.yml) Ensure AllowAllMatchScan is enabled in clamd.conf
  lineinfile:
    path: /etc/clamav/clamd.conf
    regexp: "^#?\\s*AllowAllMatchScan\\s"
    line: "AllowAllMatchScan true"
    state: present
  notify: Restart clamav-daemon
  when:
    - inventory_hostname in groups['samba_server']
    - samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
      selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
  tags:
    - samba-server
    - samba-virusfilter

# ---
# /etc/samba/smb.conf
# ---

- name: (samba-config-server.yml) Check if file '/etc/samba/smb.conf.ORIG exists'
  stat:
    path: /etc/samba/smb.conf.ORIG
  register: smb_conf_exists
  when:
    - inventory_hostname in groups['samba_server']
  tags:
    - samba-server

- name: (samba-config-server.yml) Backup existing file /etc/samba/smb.conf
  command: cp -a /etc/samba/smb.conf /etc/samba/smb.conf.ORIG
  when:
    - inventory_hostname in groups['samba_server']
    - smb_conf_exists.stat.exists == False
  tags:
    - samba-server

- name: (samba-config-server.yml) /etc/samba/smb.conf
  template:
    dest: /etc/samba/smb.conf
    src: etc/samba/smb.conf.j2
    owner: root
    group: root
    mode: 0644
  when:
    - inventory_hostname in groups['samba_server']
  notify:
    - Restart smbd
    - Restart nmbd
  tags:
    - samba-server

- name: (samba-config-server.yml) Ensure file /etc/samba/users.map exists
  copy:
    src: "{{ role_path + '/files/etc/samba/users.map' }}"
    dest: /etc/samba/users.map
    owner: root
    group: root
    mode: 0644
  when:
    - inventory_hostname in groups['samba_server']
  notify:
    - Restart smbd
    - Restart nmbd
  tags:
    - samba-server

# ---
# Cronjob for cleaning up samba trash dirs
# ---

- name: (samba-config-server.yml) Check if file '/root/bin/samba/clean_samba_trash.sh' exists
  ansible.builtin.stat:
    path: /root/bin/samba/clean_samba_trash.sh
  register: clean_samba_trash_exists
  when:
    - inventory_hostname in groups['samba_server']
  tags:
    - samba-server
    - samba-cron

- name: (samba-config-server.yml) Adjust configuration for script 'clean_samba_trash.sh'
  template:
    dest: /root/bin/samba/conf/clean_samba_trash.conf
    src: root/bin/samba/conf/clean_samba_trash.conf.j2
  when:
    - inventory_hostname in groups['samba_server']
    - clean_samba_trash_exists.stat.exists|bool
  tags:
    - samba-server
    - samba-cron

- name: (samba-config-server.yml) Check if cleaning up trash dirs is configured
  ansible.builtin.lineinfile:
    path: /root/bin/samba/conf/clean_samba_trash.conf
    regexp: "^trash_dirs=*"
    state: absent
  check_mode: true
  changed_when: false
  register: clean_samba_trash_dirs
  when:
    - inventory_hostname in groups['samba_server']
  tags: [samba-server, samba-cron]

- name: (samba-config-server.yml) Creates a cron job for cleaning up samba trash dirs
  ansible.builtin.cron:
    name: "{{ samba_cronjob_trash_dirs.name }}"
    minute: "{{ samba_cronjob_trash_dirs.minute }}"
    hour: "{{ samba_cronjob_trash_dirs.hour | default('*') }}"
    day: "{{ samba_cronjob_trash_dirs.day | default('*') }}"
    month: "{{ samba_cronjob_trash_dirs.month | default('*') }}"
    weekday: "{{ samba_cronjob_trash_dirs.weekday | default('*') }}"
    user: "{{ samba_cronjob_trash_dirs.user | default('root') }}"
    job: "{{ samba_cronjob_trash_dirs.job }}"
  when:
    - inventory_hostname in groups['samba_server']
    - clean_samba_trash_exists.stat.exists | bool
    - (clean_samba_trash_dirs.found | int) > 0
  tags: [samba-server, samba-cron]

# ---
# Cronjob for setting permissions on samba shares
# ---

- name: (samba-config-server.yml) Check if file '/root/bin/samba/set_permissions_samba_shares.sh' exists
  ansible.builtin.stat:
    path: /root/bin/samba/set_permissions_samba_shares.sh
  register: set_permissions_on_samba_shares_exists
  when:
    - inventory_hostname in groups['samba_server']
  tags: [samba-server, samba-cron]

- name: (samba-config-server.yml) Adjust configuration for script 'set_permissions_samba_shares.sh'
  ansible.builtin.template:
    dest: /root/bin/samba/conf/set_permissions_samba_shares.conf
    src: root/bin/samba/conf/set_permissions_samba_shares.conf.j2
  when:
    - inventory_hostname in groups['samba_server']
    - set_permissions_on_samba_shares_exists.stat.exists | bool
  tags: [samba-server, samba-cron]

- name: (samba-config-server.yml) Creates a cron job for setting permissions to samba dirs
  ansible.builtin.cron:
    name: "{{ samba_cronjob_permissions.name }}"
    minute: "{{ samba_cronjob_permissions.minute }}"
    hour: "{{ samba_cronjob_permissions.hour | default('*') }}"
    day: "{{ samba_cronjob_permissions.day | default('*') }}"
    month: "{{ samba_cronjob_permissions.month | default('*') }}"
    weekday: "{{ samba_cronjob_permissions.weekday | default('*') }}"
    user: "{{ samba_cronjob_permissions.user | default('root') }}"
    job: "{{ samba_cronjob_permissions.job }}"
  when:
    - inventory_hostname in groups['samba_server']
    - (clean_samba_trash_dirs.found | int) > 0 # << int -> bool
  tags: [samba-server, samba-cron]
