From dca25832c4a2b996450362440633eb915ee3511e Mon Sep 17 00:00:00 2001 From: Ethan Paul Date: Fri, 27 Sep 2019 02:59:11 -0400 Subject: [PATCH] Overhaul local user management Fix user deletion on removal/reassignment Improve efficiency and cross platform support --- groups/all.yml | 4 + playbooks/deploy-sshkeys.yml | 1 + playbooks/update-users-local.yml | 127 ++++++++++++++++--------------- tasks/users-preprocessing.yml | 52 +++++++++---- 4 files changed, 110 insertions(+), 74 deletions(-) diff --git a/groups/all.yml b/groups/all.yml index 2165063..f0e04ad 100644 --- a/groups/all.yml +++ b/groups/all.yml @@ -2,3 +2,7 @@ ansible_user: ansible disable_gnome_user_list: True + +protected_users: + - root + - ansible diff --git a/playbooks/deploy-sshkeys.yml b/playbooks/deploy-sshkeys.yml index 6ae1bb6..d42d460 100644 --- a/playbooks/deploy-sshkeys.yml +++ b/playbooks/deploy-sshkeys.yml @@ -13,6 +13,7 @@ state: directory path: /home/{{ item.name }}/.ssh loop: "{{ local_users | difference([None]) }}" + - name: Put keys on remote when: item.keys != [] authorized_key: diff --git a/playbooks/update-users-local.yml b/playbooks/update-users-local.yml index d757f06..e69388e 100644 --- a/playbooks/update-users-local.yml +++ b/playbooks/update-users-local.yml @@ -1,7 +1,7 @@ --- - import_playbook: dependencies.yml -- hosts: all +- hosts: all:!network name: Update local user accounts and access controls tasks: - import_tasks: tasks/users-preprocessing.yml @@ -21,78 +21,58 @@ name: "{{ item.name }}" comment: "{{ item.fullname | default('') }}" shell: /bin/bash - groups: "{{ item.targets | intersect(targets) }} + {{ [ 'omni' ] if item.name != 'root' else [] }}" - system: "{{ item.svc | default('no') }}" + groups: "{{ item.targets | intersect(targets) + ['omni'] }}" + system: "{{ item.svc | default(False) }}" state: present - generate_ssh_key: "{{ 'yes' if generate_keys|bool == true else 'no' }}" + generate_ssh_key: "{{ True if generate_keys | bool == true else False }}" ssh_key_comment: "{{ item.name }}@{{ inventory_hostname }}" ssh_key_bits: 4096 ssh_key_type: ed25519 password: "{{ item.password }}" - loop: "{{ local_users | difference([None]) }}" + loop: "{{ local_users }}" - - name: Delete users that have been removed - tags: users_delete - block: - - name: Determine existing users - shell: 'grep omni /etc/group | cut -d: -f4 | tr "," "\n"' - changed_when: false - register: existing_users + - name: Delete removed user accounts + become: true + user: + name: "{{ item }}" + state: absent + loop: "{{ local_removed_users | difference(protected_users) }}" - - name: Coallate user names - set_fact: - user_names: "{{ user_names | default([]) + [item.name] }}" - loop: "{{ users }}" + - name: Grant sudo permissions to admin user accounts + become: true + user: + name: "{{ item.name }}" + groups: "{{ 'wheel' if ansible_os_family | lower == 'redhat' else 'sudo' }}" + state: present + loop: "{{ local_admin_users }}" - - name: Determine removed users - set_fact: - removed_users: "{{ existing_users.stdout_lines | difference(local_users) | difference([None]) }}" + - name: Disable sudo password for ansible + become: true + lineinfile: + create: true + path: /etc/sudoers.d/30-ansible + line: "ansible ALL=(ALL) NOPASSWD:ALL" + mode: 0644 - - name: Delete removed user accounts - become: true - user: - name: "{{ item }}" - state: absent - loop: "{{ removed_users }}" - - - name: Grant sudo permissions - tags: users_sudo - block: - - name: Add users to sudo group on Fedora/CentOS/RHEL - when: ansible_distribution == "Fedora" or ansible_distribution == "Red Hat Enterprise Linux" or ansible_distribution == "CentOS" - become: true - user: - name: "{{ item }}" - groups: wheel - state: present - loop: "{{ local_admin_users | difference([None]) }}" - - - name: Disable sudo password for ansible - become: true - lineinfile: - create: yes - path: /etc/sudoers.d/30-ansible - line: "ansible ALL=(ALL) NOPASSWD:ALL" - mode: 0644 - - - name: Disable sudo password for admin users - become: true - lineinfile: - create: yes - path: /etc/sudoers.d/40-admin - line: "{{ item }} ALL=(ALL) NOPASSWD:ALL" - mode: 0644 - state: "{{ 'absent' if disable_sudo_password|bool == false else 'present' }}" - loop: "{{ local_admin_users | difference([None] )}}" + - name: Disable sudo password for admin users + become: true + lineinfile: + create: true + path: /etc/sudoers.d/40-admin + line: "{{ item.name }} ALL=(ALL) NOPASSWD:ALL" + mode: 0644 + state: "{{ 'absent' if disable_sudo_password | bool == false else 'present' }}" + loop: "{{ local_admin_users }}" - name: Configure GNOME tags: users_gnome - when: ansible_distribution == "Fedora" and disable_gnome_user_list|bool == true + when: ansible_distribution == "Fedora" and disable_gnome_user_list | bool == true become: true block: - name: Configure GDM profile blockinfile: - path: /etc/ssh/sshd_config + create: true + path: /etc/dconf/profile/gdm block: | user-db:user system-db:gdm @@ -118,8 +98,35 @@ group: "{{ item.name }}" owner: "{{ item.name }}" path: /home/{{ item.name }} - recurse: yes + recurse: true state: directory - loop: "{{ local_users | difference([None]) }}" + loop: "{{ local_users }}" -- import_playbook: deploy-sshkeys.yml +# - hosts: router.net.enp.one +# name: Configure users on router +# connection: network_cli +# vars: +# ansible_network_os: edgeos +# tasks: +# - import_tasks: tasks/users-preprocessing.yml +# +# - name: Create users +# edgeos_config: +# lines: +# - set system login user {{ item.name }} authentication encrypted-password "{{ item.password }}" +# - set system login user {{ item.name }} full-name "{{ item.fullname if item.fullname is defined else "" }}" +# - set system login user {{ item.name }} level {{ 'operator' if item.name != 'ansible' else 'admin' }} +# loop: "{{ local_users | difference([None]) }}" +# +# - name: Grant administrative access to admin users +# edgeos_config: +# lines: +# - set system login user {{ item.name }} level admin +# loop: "{{ local_admin_users | difference([None]) }}" +# +# - name: Assemble key files for loadkey usage +# edgeos_command: +# commands: sudo tee /tmp/{{ item.name }}.keys<<<"{{ item.sshkeys | join('\n') }}" +# loop: "{{ local_admin_users | difference([None]) }}" +# +# - import_playbook: deploy-sshkeys.yml diff --git a/tasks/users-preprocessing.yml b/tasks/users-preprocessing.yml index ee1bd23..b8ba2d5 100644 --- a/tasks/users-preprocessing.yml +++ b/tasks/users-preprocessing.yml @@ -1,15 +1,39 @@ --- -- name: Pre-processing - tags: always - block: - - name: Load users - include_vars: - file: users.yml - - name: Reconcile user targets with host targets to get host users - set_fact: - local_users: "{{ local_users | default([]) + [item if item.targets | intersect(targets) else None] }}" - with_items: "{{ users }}" - - name: Get administrative users - set_fact: - local_admin_users: "{{ local_admin_users | default([]) + [item.name if item.admin else None] }}" - with_items: "{{ local_users | difference([None]) }}" +- name: Load users variables + include_vars: + file: users.yml + +- name: Reconcile user targets with host targets to get host users + set_fact: + local_users: >- + {{ + local_users | default([]) + ([item] if item.targets | intersect(targets) else []) + }} + loop: "{{ users }}" + +- name: Determine local user names + set_fact: + local_user_names: "{{ local_user_names | default([]) + [item.name] }}" + loop: "{{ local_users }}" + +- name: Determine administrative users + set_fact: + local_admin_users: >- + {{ + local_admin_users | default([]) + ([item] if item.admin | default(False) else []) + }} + loop: "{{ local_users }}" + +- name: Determine existing users + shell: 'grep omni /etc/group | cut -d: -f4 | tr "," "\n"' + changed_when: false + register: local_existing_users + +- name: Determine removed users + set_fact: + local_removed_users: >- + {{ + local_removed_users | default([]) + + ([item] if item not in local_user_names else []) + }} + loop: "{{ local_existing_users.stdout_lines }}"