ansible-collections / community.windows

Windows community collection for Ansible
https://galaxy.ansible.com/community/windows
GNU General Public License v3.0
204 stars 159 forks source link

win_credential fails to retrieve stored value of domain_password secret from Windows 10 credential store #521

Open ChrisNicoll-Pro opened 1 year ago

ChrisNicoll-Pro commented 1 year ago
SUMMARY

When setting a domain_password secret in the Windows 10 credential store, the task always reports as changed. Looking through the source code it appears to be due to the module failing to read the current value of the secret from the credential store. As a result, it falls back to always setting the secret due to the current value being unknown and, therefore, impossible to compare against.

ISSUE TYPE
COMPONENT NAME

win_credential

ANSIBLE VERSION
ansible [core 2.15.0]
  config file = /Users/***/work/ansible/ansible.cfg
  configured module search path = ['/Users/***/work/ansible/library']
  ansible python module location = /Users/***/Library/Python/3.9/lib/python/site-packages/ansible
  ansible collection location = /Users/***/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/***/Library/Python/3.9/bin/ansible
  python version = 3.9.6 (default, Oct 18 2022, 12:41:40) [Clang 14.0.0 (clang-1400.0.29.202)] (/Library/Developer/CommandLineTools/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
Collection        Version
----------------- -------
community.windows 1.13.0 
CONFIGURATION
CONFIG_FILE() = /Users/***/work/ansible/ansible.cfg
DEFAULT_HOST_LIST(/Users/***/work/ansible/ansible.cfg) = ['/Users/***/work/ansible/inventory', '/Users/***/work/ansible-inventory']
DEFAULT_MODULE_PATH(/Users/***/work/ansible/ansible.cfg) = ['/Users/***/work/ansible/library']
DEFAULT_ROLES_PATH(/Users/***/work/ansible/ansible.cfg) = ['/Users/***/work/ansible/roles', '/Users/***/.ansible/roles', '/usr/share/ansible/roles'
OS / ENVIRONMENT

Targeting Windows 10

STEPS TO REPRODUCE

Run the following multiple times and it always reports as changed.

- name: "Create network access credential for user"
  vars:
    ansible_become_method: 'runas'
    ansible_become_user: 'user'
    ansible_become_pass: 'pass'

  block:
    - name: "Set credential"
      become: yes
      community.windows.win_credential:
        name: 'server.my.domain.com'
        type: 'domain_password'
        username: 'domain\other'
        secret: '1234'
        state: 'present'
EXPECTED RESULTS

I'd expect this module to be able to read the stored secrets so the module is idempotent when used. If it really isn't possible to read the stored secrets, I think it should at least log a warning message to notify users. The current implementation makes it impossible to know whether the stored credential was different or if it failed to read it.

ACTUAL RESULTS

The module always overwrites the secret due to $existing_credential.Secret.Length -eq 0(L683) always resolving to true.

TASK [Set credential] ***************************************************************************************************************************************
changed: [node1] => {
    "changed": true,
    "diff": {
        "after": {
            "alias": null,
            "attributes": [],
            "comment": null,
            "name": "server.my.domain.com",
            "persistence": "LocalMachine",
            "type": "DomainPassword",
            "username": "domain\\other"
        },
        "before": {
            "alias": null,
            "attributes": [],
            "comment": null,
            "name": "server.my.domain.com",
            "persistence": "LocalMachine",
            "type": "DomainPassword",
            "username": "domain\\other"
        }
    },
    "invocation": {
        "module_args": {
            "alias": null,
            "attributes": null,
            "comment": null,
            "name": "server.my.domain.com",
            "persistence": "local",
            "secret": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "secret_format": "text",
            "state": "present",
            "type": "domain_password",
            "update_secret": "always",
            "username": "domain\\other"
        }
    }
}
BradKnowles commented 2 months ago

Can confirm this is still happening with Ansible 2.16.9

ANSIBLE VERSION
ansible [core 2.16.9]
  config file = /home/ubuntu/an/ansible.cfg
  configured module search path = ['/home/ubuntu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/ubuntu/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True
COLLECTION VERSION
Collection        Version
----------------- -------
community.windows 2.2.0
CONFIGURATION
CONFIG_FILE() = /home/ubuntu/an/ansible.cfg
DEFAULT_GATHERING(/home/ubuntu/an/ansible.cfg) = smart
DEFAULT_HOST_LIST(/home/ubuntu/an/ansible.cfg) = ['/home/ubuntu/an/inventories']
OS / ENVIRONMENT

Target OS:

Windows 2019 Datacenter Version 1809 (OS Build 17763.6054)

Controller:

Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:        22.04
Codename:       jammy