From 3e0bc5516313726a8843ce66c10b9cf6173acca2 Mon Sep 17 00:00:00 2001 From: Brian Schonecker Date: Wed, 23 Oct 2019 07:44:57 -0400 Subject: [PATCH] Adding the ability for the role to create individual /etc/sudoers.d/ files instead of one, monolithic file. --- defaults/main.yml | 5 +++ tasks/config.yml | 14 ++++-- templates/etc/sudoers.d/ansible.j2 | 69 ++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 2998db5..81605c5 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -27,3 +27,8 @@ sudo_sudoers_file: ansible sudo_sudoers_d_path: /etc/sudoers.d # delete other files in `sudo_sudoers_d_path` purge_other_sudoers_files: no + + +runas_default: root # must be a single word string +hosts_default: ALL # must be a single word string +commands_default: ALL diff --git a/tasks/config.yml b/tasks/config.yml index ba32aee..971a361 100644 --- a/tasks/config.yml +++ b/tasks/config.yml @@ -3,11 +3,19 @@ - name: "Creating sudoers configuration in {{ sudo_sudoers_d_path }}/{{ sudo_sudoers_file }}" template: src: "etc/sudoers.d/ansible.j2" - dest: "{{ sudo_sudoers_d_path }}/{{ sudo_sudoers_file }}" - validate: "/usr/sbin/visudo -cf %s" + dest: "{{ sudo_sudoers_d_path }}/{{ my_sudoers.name }}" + validate: "visudo -cf %s" owner: root group: "{{ sudo_sudoers_group }}" mode: "0440" + loop: "{{ sudo_users }}" + loop_control: + loop_var: my_sudoers + +- name: Build a list of the file names that we don't want to delete. + set_fact: + sudo_keep: "{{ sudo_keep | default([]) | union([item.name]) }}" + loop: "{{ sudo }}" - name: "List files in {{ sudo_sudoers_d_path }}" find: @@ -26,4 +34,4 @@ label: "{{ item.path }}" when: - purge_other_sudoers_files | bool - - (item.path|basename) != sudo_sudoers_file + - (item.path|basename) not in sudo_keep diff --git a/templates/etc/sudoers.d/ansible.j2 b/templates/etc/sudoers.d/ansible.j2 index 3671f59..be28807 100644 --- a/templates/etc/sudoers.d/ansible.j2 +++ b/templates/etc/sudoers.d/ansible.j2 @@ -1,17 +1,60 @@ -# {{ ansible_managed }} - -{% for item in sudo_defaults %} -Defaults{{ ":" ~ item.name if item.name is defined else "" }} {{ item.defaults }} -{% endfor %} +# This file is {{ ansible_managed }}. DO NOT EDIT! +{% if my_sudoers.comment is defined %} +# {{ my_sudoers.comment }} +{% endif %} -{% for item in sudo_users %} -{% if item.commands is not defined %} -{{ item.name }} {{ item.hosts | default('ALL') }}={{ "(" ~ item.users | default('ALL') ~ ":" ~ item.groups | default('ALL') ~ ")" }} {{ "NOPASSWD:" if item.nopasswd | default(false) else "" }} ALL -{% elif item.commands is string %} -{{ item.name }} {{ item.hosts | default('ALL') }}={{ "(" ~ item.users | default('ALL') ~ ":" ~ item.groups | default('ALL') ~ ")" }} {{ "NOPASSWD:" if item.nopasswd | default(false) else "" }} {{ item.commands }} +# Any conversion of dashes to underscores and/or removal of percent signs +# in Alias definitions is to maintain compatibility with the sudoers Alias definitions. +# See `man sudoers` for more information. +{% if my_sudoers.users is defined -%} +{% set USERALIAS = my_sudoers.name|upper|replace('-','_')|replace('%','')+'_USERS' %} +User_Alias {{ USERALIAS }} = +{%- if my_sudoers.users is string %} + {{ my_sudoers.users }} {% else %} -{% for command in item.commands %} -{{ item.name }} {{ item.hosts | default('ALL') }}={{ "(" ~ item.users | default('ALL') ~ ":" ~ item.groups | default('ALL') ~ ")" }} {{ "NOPASSWD:" if item.nopasswd | default(false) else "" }} {{ command }} -{% endfor %} + {{ my_sudoers.users|sort|join(', ') }} +{% endif %} {% endif %} +{% set HOSTALIAS = my_sudoers.name|upper|replace('-','_')|replace('%','')+'_HOSTS' %} +Host_Alias {{ HOSTALIAS }} = +{%- if my_sudoers.hosts is string %} + {{ my_sudoers.hosts }} +{% else %} + {{ my_sudoers.hosts|sort|join(', ') }} +{% endif %} +{% set CMNDALIAS = my_sudoers.name|upper|replace('-','_')|replace('%','')+'_CMNDS' %} +Cmnd_Alias {{ CMNDALIAS }} = +{%- if my_sudoers.commands is defined %} +{% if my_sudoers.commands is string %} + {{ my_sudoers.commands }} +{% else %} + {{ my_sudoers.commands|join(', ') }} +{% endif %} +{% else %} +{{ commands_default }} +{% endif %} +{% set RUNASALIAS = my_sudoers.name|upper|replace('-','_')|replace('%','')+'_RUNAS' %} +Runas_Alias {{ RUNASALIAS }} = +{%- if my_sudoers.runas is defined %} +{% if my_sudoers.runas is string %} +{{ my_sudoers.runas }} +{% else %} + {{ my_sudoers.runas|sort|join(', ') }} +{% endif %} +{% else %} + {{ runas_default }} +{% endif %} + +{% if my_sudoers.users is defined %} +# User Commands +{{ USERALIAS }} {{ HOSTALIAS }} = ({{ RUNASALIAS }}) +{%- if my_sudoers.nopasswd is defined %} NOPASSWD:{% else %} PASSWD:{% endif %} {{ CMNDALIAS }} +{% endif %} + +{% if my_sudoers.groups is defined %} +# Group Commands +{% for group in my_sudoers.groups %} +%{{ group }} {{ HOSTALIAS }} = ({{ RUNASALIAS }}) +{%- if my_sudoers.nopasswd is defined %} NOPASSWD:{% else %} PASSWD:{% endif %} {{ CMNDALIAS }} {% endfor %} +{% endif %}