From 9d20688196ed699210b95ec078a879e263f8472f Mon Sep 17 00:00:00 2001 From: Laszlo Nagy Date: Wed, 9 Feb 2022 18:54:13 +0100 Subject: [PATCH] Add new role: logon policy for unix host Lists Active Directory users that have been explicitly granted log on permissions for the Unix hosts. --- README.md | 2 + examples/README.md | 4 + examples/run_logon_policy_for_unix_host.yml | 18 ++ .../modules/get_logon_policy_for_unix_host.py | 284 ++++++++++++++++++ roles/logon_policy_for_unix_host/README.md | 91 ++++++ .../defaults/main.yml | 32 ++ .../logon_policy_for_unix_host/meta/main.yml | 67 +++++ .../tasks/gather_facts.yml | 24 ++ .../tasks/generate_reports.yml | 11 + .../tasks/get_logon_policy_for_unix_host.yml | 13 + .../logon_policy_for_unix_host/tasks/main.yml | 33 ++ .../tasks/utils/set_fact_failed.yml | 14 + .../tasks/utils/set_fact_success.yml | 10 + .../tasks/utils/set_fact_unreachable.yml | 14 + ..._2020-OneIdentity_FullColor_Horizontal.png | Bin 0 -> 14172 bytes ..._2020-OneIdentity_FullColor_Horizontal.txt | 249 +++++++++++++++ .../logon_policy_for_unix_host_report.csv.j2 | 43 +++ .../logon_policy_for_unix_host_report.html.j2 | 45 +++ ...policy_for_unix_host_report_common.html.j2 | 251 ++++++++++++++++ .../logon_policy_for_unix_host/vars/main.yml | 1 + 20 files changed, 1206 insertions(+) create mode 100644 examples/run_logon_policy_for_unix_host.yml create mode 100644 plugins/modules/get_logon_policy_for_unix_host.py create mode 100644 roles/logon_policy_for_unix_host/README.md create mode 100644 roles/logon_policy_for_unix_host/defaults/main.yml create mode 100644 roles/logon_policy_for_unix_host/meta/main.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/gather_facts.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/generate_reports.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/get_logon_policy_for_unix_host.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/main.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/utils/set_fact_failed.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/utils/set_fact_success.yml create mode 100644 roles/logon_policy_for_unix_host/tasks/utils/set_fact_unreachable.yml create mode 100644 roles/logon_policy_for_unix_host/templates/Logo_2020-OneIdentity_FullColor_Horizontal.png create mode 100644 roles/logon_policy_for_unix_host/templates/Logo_2020-OneIdentity_FullColor_Horizontal.txt create mode 100644 roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report.csv.j2 create mode 100644 roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report.html.j2 create mode 100644 roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report_common.html.j2 create mode 100644 roles/logon_policy_for_unix_host/vars/main.yml diff --git a/README.md b/README.md index 62d944a..63c9173 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ The One Identity Safeguard Authentication Services Ansible Collection, referred * [`ad_group_conflicts role`](roles/ad_group_conflicts/README.md): Lists all Active Directory groups with Unix Group ID (GID) numbers assigned to other Unix-enabled groups. +* [`logon_policy_for_unix_host role`](roles/logon_policy_for_unix_host/README.md): Identifies the Active Directory users that have been explicitly granted log on permissions for the Unix hosts. + ## Installation ### Prerequisites diff --git a/examples/README.md b/examples/README.md index 9fb640c..77a5699 100644 --- a/examples/README.md +++ b/examples/README.md @@ -66,3 +66,7 @@ The [`unix_enabled_ad_groups`](run_unix_enabled_ad_groups.yml) role example show The [`ad_group_conflicts`](run_ad_group_conflicts.yml) role example shows use of the `ad_group_conflicts` role in an Ansbile playbook. The variables most likely to be overriden have been included in this playbook for your convenience even though many are still set to their default values. +## `logon_policy_for_unix_host` Role Example + +The [`logon_policy_for_unix_host`](run_logon_policy_for_unix_host.yml) role example shows use of the `logon_policy_for_unix_host` role in an Ansbile playbook. The variables most likely to be overriden have been included in this playbook for your convenience even though many are still set to their default values. + diff --git a/examples/run_logon_policy_for_unix_host.yml b/examples/run_logon_policy_for_unix_host.yml new file mode 100644 index 0000000..f575094 --- /dev/null +++ b/examples/run_logon_policy_for_unix_host.yml @@ -0,0 +1,18 @@ +--- + +- hosts: all + gather_facts: false + + # The variables you would most likely want/need to override have been included + vars: + + # Facts + logon_policy_for_unix_host_facts_generate: true + + # Reports + logon_policy_for_unix_host_reports_generate: true + logon_policy_for_unix_host_reports_backup: false + + roles: + - name: oneidentity.authentication_services.logon_policy_for_unix_host + diff --git a/plugins/modules/get_logon_policy_for_unix_host.py b/plugins/modules/get_logon_policy_for_unix_host.py new file mode 100644 index 0000000..7041524 --- /dev/null +++ b/plugins/modules/get_logon_policy_for_unix_host.py @@ -0,0 +1,284 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# ------------------------------------------------------------------------------ +# Copyright (c) 2022, One Identity LLC +# File: get_logon_policy_for_unix_host.py +# Desc: Ansible module that returns users that are allowed access to the Unix +# host using the vastool list users-allowed command. +# Auth: Laszlo Nagy +# Note: +# ------------------------------------------------------------------------------ + + +# ------------------------------------------------------------------------------ +# Required Ansible documentation +# ------------------------------------------------------------------------------ + +ANSIBLE_METADATA = { + 'metadata_version': '0.2', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = """ +--- +module: get_logon_policy_for_unix_host + +short_description: Returns users that are allowed access to the Unix host + +version_added: '2.9' + +description: > + Returns users that are allowed access to the Unix host using the + vastool list users-allowed command. + +options: + facts: + description: + - Generate Ansible facts? + type: bool + required: false + default: true + facts_key: + description: + - Ansible facts key + type: str + required: false + default: 'get_logon_policy_for_unix_host_facts_key' + +author: + - Laszlo Nagy (laszlo.nagy@oneidentity.com) +""" + +EXAMPLES = """ +- name: Get logon policy for unix host + get_logon_policy_for_unix_host: + facts: true + facts_key: get_logon_policy_for_unix_host_facts_key + register: get_logon_policy_for_unix_host_result +""" + +RETURN = """ +ansible_facts: + description: All non-standard return values are placed in Ansible facts + type: dict + returned: when facts parameter is true + keys: + changed: + description: Did the state of the host change? + type: bool + returned: always + failed: + description: Did the module fail? + type: bool + returned: always + msg: + description: Additional information if failed + type: str + returned: always + params: + description: Parameters passed in + type: dict + returned: always + version: + description: Version of vastool + type: str + returned: always + users_allowed: + description: All fields of each user account + type: list of lists + returned: always +""" + + +# ------------------------------------------------------------------------------ +# Imports +# ------------------------------------------------------------------------------ + + +from ansible.module_utils.basic import AnsibleModule +import sys +import subprocess +import traceback +import ansible_collections.oneidentity.authentication_services.plugins.module_utils.vastool as vt +import ansible_collections.oneidentity.authentication_services.plugins.module_utils.check_file_exec as cfe + + +# ------------------------------------------------------------------------------ +# Constants +# ------------------------------------------------------------------------------ + +# Arg choices and defaults +FACTS_DEFAULT = True +FACTS_VERBOSE_DEFAULT = True +FACTS_KEY_DEFAULT = 'get_logon_policy_for_unix_host_facts_key' + + +# ------------------------------------------------------------------------------ +# Functions +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +def run_module(): + """ + Main Ansible module function + """ + + # Module argument info + module_args = { + 'facts': { + 'type': 'bool', + 'required': False, + 'default': FACTS_DEFAULT + }, + 'facts_key': { + 'type': 'str', + 'required': False, + 'default': FACTS_KEY_DEFAULT + } + } + + # Seed result value + result = { + 'changed': False, + 'failed': False, + 'msg': '' + } + + # Lean on boilerplate code in AnsibleModule class + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=False + ) + + # Run logic + # NOTE: This module does not support check mode right now so no special check handling + err, result = run_normal(module.params, result) + + # Exit + module.exit_json(**result) + + +# ------------------------------------------------------------------------------ +def run_normal(params, result): + """ + Normal mode logic. + + params contains input parameters. + + result contains run results skeleton, will modify/add to and then return + this value along with an err value that contains None if no error or a string + describing the error. + """ + + # Return data + err = None + version = '' + users_allowed = [] + + # Parameters + facts = params['facts'] + facts_key = params['facts_key'] if params['facts_key'] else FACTS_KEY_DEFAULT + + try: + + # Check vastool + err, version = cfe.check_file_exec(vt.VASTOOL_PATH, '-v') + + # Run vastool + if err is None: + err, users_allowed = run_vastool_list_users_allowed() + + except Exception: + tb = traceback.format_exc() + err = str(tb) + + # Build result + result['changed'] = False # vastool list users-allowed never makes any changes to the host + result['failed'] = err is not None + result['msg'] = err if err is not None else '' + + # Create ansible_facts data + if facts: + result_facts = result.copy() + result_facts['params'] = params + result_facts['version'] = version + result_facts['users_allowed'] = users_allowed + result['ansible_facts'] = {facts_key: result_facts} + + # Return + return err, result + + +# ------------------------------------------------------------------------------ +def run_vastool_list_users_allowed(): + """ + Run vastool list users-allowed + """ + + # Return values + err = None + users_allowed = [] + non_zero_ret_code = False + + # Build vastool command + cmd = [] + cmd += [vt.VASTOOL_PATH] + cmd += ['list'] + cmd += ['users-allowed'] + + # Call vastool + try: + p = subprocess.Popen(' '.join(cmd), stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + rval_bytes, rval_err = p.communicate() + rval_bytes += rval_err + # This exception happens when the process exits with a non-zero return code + except subprocess.CalledProcessError as e: + # Just grab output bytes likes a normal exit, we'll parse it for errors anyway + rval_bytes = e.output + if p.returncode > 0: + non_zero_ret_code = True + # Popen returns list of bytes so we have to decode to get a string + rval_str = rval_bytes.decode(sys.stdout.encoding) + + # Parse vastool return + err, users_allowed = parse_vastool_stdout(non_zero_ret_code, rval_str) + + # Return + return err, users_allowed + + +# ------------------------------------------------------------------------------ +def parse_vastool_stdout(non_zero_ret_code, stdout_str): + + # Return values + err = None + users_allowed = [] + + if non_zero_ret_code: + err = stdout_str + else: + users_allowed = stdout_str.split('\n') + users_allowed = [user.strip() for user in users_allowed] + users_allowed = [user for user in users_allowed if len(user) > 0] + users_allowed = [user.split(':') for user in users_allowed] + users_allowed = [user for user in users_allowed if len(user) == 7] + + # Return + return err, users_allowed + + +# ------------------------------------------------------------------------------ +def main(): + """ + Main + """ + + run_module() + + +# When run from command line +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + main() diff --git a/roles/logon_policy_for_unix_host/README.md b/roles/logon_policy_for_unix_host/README.md new file mode 100644 index 0000000..c832ca8 --- /dev/null +++ b/roles/logon_policy_for_unix_host/README.md @@ -0,0 +1,91 @@ +# `logon_policy_for_unix_host` Role + +The `logon_policy_for_unix_host` role creates CSV and HTML reports that list Active Directory users that have been explicitly granted log on permissions for the Unix hosts. + +## Variables + +All of the variables shown below have a default value but can be overridden to suit your environment. Variable overriding can be done in playbooks, inventories, from the command line using the `-e` switch with the `ansible-playbook` command, or from Ansible Tower and AWX. See [Ansbile documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html) for further information. + +### Facts generation + +Facts generation variable defaults for all roles are set by variables in the [`common`](../common/README.md) role and can be overriden for all roles by setting the appropriate [`common`](../common/README.md) role variable. See [common role facts generation variables](../common/README.md#facts-generation) in the [`common`](../common/README.md) role. + +* `logon_policy_for_unix_host_facts_generate` enables facts generation. Implicitely enabled if `logon_policy_for_unix_host_reports_generate` is set. + + Default value is: + ```yaml + logon_policy_for_unix_host_facts_generate: "{{ facts_generate }}" + ``` + +### Report generation + +Report generation variable defaults for all roles are set by variables in the [`common`](../common/README.md) role and can be overriden for all roles by setting the appropriate [`common`](../common/README.md) role variable. See [common role report generation variables](../common/README.md#report-generation) in the [`common`](../common/README.md) role. + +* `logon_policy_for_unix_host_reports_generate` enables report generation. Reports are generated at the end of a `logon_policy_for_unix_host` run for all hosts. + + Default value is: + ```yaml + logon_policy_for_unix_host_reports_generate: "{{ reports_generate }}" + ``` + +* `logon_policy_for_unix_host_reports_backup` enables backup of prior reports by renaming them with the date and time they were generated so that the latest reports do not override the previous reports. + + Default value is: + ```yaml + logon_policy_for_unix_host_reports_backup: "{{ reports_backup }}" + + ``` + +* `logon_policy_for_unix_host_reports_host` sets the host on which the reports should be generated. + + Default value is: + ```yaml + logon_policy_for_unix_host_reports_host: "{{ reports_host }}" + ``` + +* `logon_policy_for_unix_host_reports` is a list of dictionaries that define the reports to be generated. The default value creates a CSV and HTML report using the templates included with the `logon_policy_for_unix_host` role. + + Default value is: + ```yaml + logon_policy_for_unix_host_reports: + - src: logon_policy_for_unix_host_report.csv.j2 + dest: logon_policy_for_unix_host_report.csv + - src: logon_policy_for_unix_host_report.html.j2 + dest: logon_policy_for_unix_host_report.html + ``` + + The `src` key for each list entry is the report template file on the Ansible control node. With a relative path Ansible will look in the `logon_policy_for_unix_host` role `template` directory. Use a absolute path to speciy templates located elsewhere on the Ansible control node. + + The `dest` key for each list entry is the report file on the machine specified in `logon_policy_for_unix_host_reports_host`. If `logon_policy_for_unix_host_reports_host` is set to the Ansible control node a relative path can be used and it will be relative to the directory from which the playbook is run. For other hosts, an absolute path must be used. In either case the containing directory must exist. + +## Plugins + +The `logon_policy_for_unix_host` role contains a plugin to support operation of the role: + +* `get_logon_policy_for_unix_host` module returns users that are allowed access to the Unix host using the [Safeguard Authentication Services](https://www.oneidentity.com/products/authentication-services/) vastool binary list users-allowed command. + +## Usage + +Below is a sample playbook using the `logon_policy_for_unix_host` role. + +```yaml +--- + +- hosts: all + gather_facts: false + + # The variables you would most likely want/need to override have been included + vars: + + # Facts + logon_policy_for_unix_host_facts_generate: true + + # Reports + logon_policy_for_unix_host_reports_generate: true + logon_policy_for_unix_host_reports_backup: false + + roles: + - name: oneidentity.authentication_services.logon_policy_for_unix_host +``` + +For a copy of this and other sample playbooks see [examples](../../examples/README.md) diff --git a/roles/logon_policy_for_unix_host/defaults/main.yml b/roles/logon_policy_for_unix_host/defaults/main.yml new file mode 100644 index 0000000..29d5845 --- /dev/null +++ b/roles/logon_policy_for_unix_host/defaults/main.yml @@ -0,0 +1,32 @@ +--- + +# Facts settings +# ------------------------------------------------------------------------------ + +logon_policy_for_unix_host_facts_generate: "{{ facts_generate }}" + + +# Reports settings +# ------------------------------------------------------------------------------ + +logon_policy_for_unix_host_reports_generate: "{{ reports_generate }}" +logon_policy_for_unix_host_reports_backup: "{{ reports_backup }}" + +# On which host should the reports be generated. +# TODO: This has only been tested on the Ansible control node (127.0.0.1) +logon_policy_for_unix_host_reports_host: "{{ reports_host }}" + +# List of reports to generate +# src: Is the report template file on the Ansible control node. +# With no or relative path Ansible will look in the logon_policy_for_unix_host role template directory. +# Full path to find the template files elsewhere on the Ansible control node. +# dest: Is the destination file on the host (logon_policy_for_unix_host_reports_host.) +# With no or relative path when the destination is the Ansible control node. +# (logon_policy_for_unix_host_reports_host = 127.0.0.1) relative to the playbook directory. +# Full path for other locations or on other hosts. +# In either case the directory must already exist. +logon_policy_for_unix_host_reports: + - src: logon_policy_for_unix_host_report.csv.j2 + dest: logon_policy_for_unix_host_report.csv + - src: logon_policy_for_unix_host_report.html.j2 + dest: logon_policy_for_unix_host_report.html diff --git a/roles/logon_policy_for_unix_host/meta/main.yml b/roles/logon_policy_for_unix_host/meta/main.yml new file mode 100644 index 0000000..d1fe9e1 --- /dev/null +++ b/roles/logon_policy_for_unix_host/meta/main.yml @@ -0,0 +1,67 @@ +--- + +galaxy_info: + + author: Laszlo Nagy + + company: One Identity + + description: > + Identifies the Active Directory users that have been explicitly granted log + on permissions for the Unix hosts. + + issue_tracker_url: https://github.com/OneIdentity/ansible-authentication-services/issues + + license: Apache-2.0 + + min_ansible_version: 2.9 + + # + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + platforms: + - name: Amazon + versions: + - all + - name: MacOSX + versions: + - 10.12 + - 10.13 + - 10.14 + - 10.15 + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Fedora + versions: + - all + - name: FreeBSD + versions: + - all + - name: AIX + versions: + - 7.1 + - 7.2 + - name: opensuse + versions: + - all + - name: Solaris + versions: + - all + - name: SLES + versions: + - 11 + - 12 + - 15 + - name: Ubuntu + versions: + - all + + # galaxy_tags: [] + +dependencies: + - role: common diff --git a/roles/logon_policy_for_unix_host/tasks/gather_facts.yml b/roles/logon_policy_for_unix_host/tasks/gather_facts.yml new file mode 100644 index 0000000..70522e3 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/gather_facts.yml @@ -0,0 +1,24 @@ +--- + +# Gather facts +- name: gather host information + setup: + register: result + ignore_errors: true + ignore_unreachable: true + +- name: fail when unreachable + fail: + msg: "{{ result.msg }}" + when: result.unreachable is defined and result.unreachable == true + +# MODULE FAILURE\nSee stdout/stderr for the exact error +- name: fail when module failure + fail: + msg: "{{ result.module_stderr + result.module_stdout }}" + register: result + when: result.msg is defined and "'See stdout/stderr for the exact error' in result.msg" + +- fail: + msg: "{{ result.msg }}" + when: result.msg is defined diff --git a/roles/logon_policy_for_unix_host/tasks/generate_reports.yml b/roles/logon_policy_for_unix_host/tasks/generate_reports.yml new file mode 100644 index 0000000..8b9fa65 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/generate_reports.yml @@ -0,0 +1,11 @@ +--- + +- name: generate reports + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + backup: "{{ logon_policy_for_unix_host_reports_backup }}" + with_items: "{{ logon_policy_for_unix_host_reports }}" + delegate_to: "{{ logon_policy_for_unix_host_reports_host }}" + run_once: true + changed_when: false diff --git a/roles/logon_policy_for_unix_host/tasks/get_logon_policy_for_unix_host.yml b/roles/logon_policy_for_unix_host/tasks/get_logon_policy_for_unix_host.yml new file mode 100644 index 0000000..24b1881 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/get_logon_policy_for_unix_host.yml @@ -0,0 +1,13 @@ +--- + +- name: Get logon policy for unix host + get_logon_policy_for_unix_host: + facts: "{{ logon_policy_for_unix_host_facts_generate or logon_policy_for_unix_host_reports_generate }}" + facts_key: sas_logon_policy_for_unix_host_key + register: result + failed_when: false + +# Fail if there was a message returned +- fail: + msg: "{{ result.msg }}" + when: result.msg diff --git a/roles/logon_policy_for_unix_host/tasks/main.yml b/roles/logon_policy_for_unix_host/tasks/main.yml new file mode 100644 index 0000000..8143d72 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/main.yml @@ -0,0 +1,33 @@ +--- + +# ------------------------------------------------------------------------------ +# Main +# ------------------------------------------------------------------------------ + +- block: + + # Gather facts + - include_tasks: gather_facts.yml + + # Gather users from /etc/passwd + - include_tasks: get_logon_policy_for_unix_host.yml + + # We get here on success + - include_tasks: utils/set_fact_success.yml + + ignore_unreachable: true + + rescue: + + # Set unreachable status and fail + - include_tasks: utils/set_fact_unreachable.yml + when: result.unreachable is defined and result.unreachable == true + + # Set fail status and fail + - include_tasks: utils/set_fact_failed.yml + + always: + + # Generate reports + - include_tasks: generate_reports.yml + when: logon_policy_for_unix_host_reports_generate diff --git a/roles/logon_policy_for_unix_host/tasks/utils/set_fact_failed.yml b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_failed.yml new file mode 100644 index 0000000..d2c3fc9 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_failed.yml @@ -0,0 +1,14 @@ +--- + +# Set failed +- set_fact: + cacheable: true + sas_logon_policy_for_unix_host: + unreachable: false + failed: true + changed: false + when: logon_policy_for_unix_host_reports_generate or logon_policy_for_unix_host_facts_generate + +# Propogate fail +- fail: + msg: "{{ result.msg | default('Unexpected error') }}" diff --git a/roles/logon_policy_for_unix_host/tasks/utils/set_fact_success.yml b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_success.yml new file mode 100644 index 0000000..8dfccb3 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_success.yml @@ -0,0 +1,10 @@ +--- + +# Set success +- set_fact: + cacheable: true + sas_logon_policy_for_unix_host: + unreachable: false + failed: false + changed: false + when: logon_policy_for_unix_host_reports_generate or logon_policy_for_unix_host_facts_generate diff --git a/roles/logon_policy_for_unix_host/tasks/utils/set_fact_unreachable.yml b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_unreachable.yml new file mode 100644 index 0000000..97cf332 --- /dev/null +++ b/roles/logon_policy_for_unix_host/tasks/utils/set_fact_unreachable.yml @@ -0,0 +1,14 @@ +--- + +# Set unreachable +- set_fact: + cacheable: true + sas_logon_policy_for_unix_host: + unreachable: true + failed: true + changed: false + when: logon_policy_for_unix_host_reports_generate or logon_policy_for_unix_host_facts_generate + +# Propogate fail +- fail: + msg: "{{ result.msg | default('Unexpected error') }}" diff --git a/roles/logon_policy_for_unix_host/templates/Logo_2020-OneIdentity_FullColor_Horizontal.png b/roles/logon_policy_for_unix_host/templates/Logo_2020-OneIdentity_FullColor_Horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..d95f3f326a54bb582576b5a5f21fbaf3d25b4f6a GIT binary patch literal 14172 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 + + {# Create overall page container #} +
+ + {# Title #} + {{ report.title(report_name) }} + + {# Data table #} + {{ report.table() }} + + {# Footer #} + {{ report.footer(collection_version, now(fmt='%Y-%m-%d %H:%M:%S')) }} + + {# JS libraries #} + {{ report.libraries() }} + + {# Table data #} + {{ report.table_data() }} + + {# Table detail formatter #} + {{ report.table_detail_formatter() }} + + {# Table detail copy tooltip #} + {{ report.table_detail_tooltip() }} + + {# Table cell style #} + {{ report.table_cell_style() }} + +
+ + + +{# HTML end #} +{{ report.end() }} diff --git a/roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report_common.html.j2 b/roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report_common.html.j2 new file mode 100644 index 0000000..7eeecb2 --- /dev/null +++ b/roles/logon_policy_for_unix_host/templates/logon_policy_for_unix_host_report_common.html.j2 @@ -0,0 +1,251 @@ +{# Header #} +{% macro head(report_name) %} + + + + + {# Required meta tags for Bootstrap #} + + + + {# CSS libraries include at end of head per best practices #} + + + + + {# Ionicons preferred method of inclusion #} + + + + Safeguard Authentication Services: {{ report_name }} + +{% endmacro %} + +{# Title #} +{% macro title(report_name) %} + +Active Directory users granted login permission +{% endmacro %} + + +{# Table #} +{% macro table() %} + + + + + + + + + + + + + + + + + +
IdNumber of UsersHostnameGroupIP AddressOS DistroOS VersionHW ArchTimeChangedUnreachableFailed
+ +{% for host in ansible_play_hosts_all | sort %} + + + + + + + + + + + +
UsernameUser IDGroup IDCommentHome DirectoryLogin Shell
+{% endfor %} +{% endmacro %} + +{# Footer #} +{% macro footer(report_version, report_time) %} + +

Generated: {{ report_time }}

+

Version: {{ report_version }}

+
+{% endmacro %} + +{# JS libraries #} +{% macro libraries() %} + + + + + +{% endmacro %} + +{# Table data #} +{% macro table_data() %} + +{% endmacro %} + +{# Table detail formatter #} +{% macro table_detail_formatter() %} + +{% endmacro %} + +{# Table detail copy tooltip #} +{% macro table_detail_tooltip() %} + +{% endmacro %} + +{# Table cell style #} +{% macro table_cell_style() %} + +{% endmacro %} + +{# HTML end #} +{% macro end() %} + +{% endmacro %} diff --git a/roles/logon_policy_for_unix_host/vars/main.yml b/roles/logon_policy_for_unix_host/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/logon_policy_for_unix_host/vars/main.yml @@ -0,0 +1 @@ +---