+
Skip to content

acl crashes with TypeError when use_nfsv4_acls is true and permissions is omitted #679

@gdrosos

Description

@gdrosos
SUMMARY

When ansible.posix.acl is run with use_nfsv4_acls: true and permissions is omitted, the module crashes with:

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

The error comes from build_entry() attempting permissions + 'tcy' without first checking if permissions is None.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

acl

ANSIBLE VERSION
ansible [core 2.18.7]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.13/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.13.5 (main, Jun 11 2025, 22:06:31) [GCC] (/usr/bin/python3.13)
  jinja version = 3.1.6
  libyaml = True
COLLECTION VERSION
Collection    Version
------------- -------
ansible.posix 1.6.2  
CONFIGURATION

OS / ENVIRONMENT
STEPS TO REPRODUCE
    - name: Prepare test dir
      file:
        path: /tmp/test_dir
        state: directory

    - name: Trigger acl module crash (no permissions set)
      ansible.posix.acl:
        path: /tmp/test_dir
        entity: www-data
        etype: user
        state: absent
        use_nfsv4_acls: true
        default: true
EXPECTED RESULTS

Module should fail gracefully via fail_json() with a helpful message (e.g., "permissions must be set when using NFSv4 ACLs") or handle the missing value.

ACTUAL RESULTS
ansible-playbook [core 2.18.8]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.12/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.12.2 (main, Jul 26 2025, 13:01:09) [GCC 10.2.1 20210110] (/usr/local/bin/python3.12)
  jinja version = 3.1.6
  libyaml = True
No config file found; using defaults
setting up inventory plugins
Loading collection ansible.builtin from 
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Loading collection ansible.posix from /usr/local/lib/python3.12/site-packages/ansible_collections/ansible/posix
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python3.12/site-packages/ansible/plugins/callback/default.py
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: u.yml ***********************************************************************************************************************
Positional arguments: u.yml
verbosity: 4
connection: ssh
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in u.yml

PLAY [localhost] **********************************************************************************************************************

TASK [Prepare test dir] ***************************************************************************************************************
task path: /opt/u.yml:4
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655 `" && echo ansible-tmp-1755279565.3375456-2116-59485947555655="` echo /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655 `" ) && sleep 0'
Using module file /usr/local/lib/python3.12/site-packages/ansible/modules/file.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-211298fmm1a0/tmpfxgzu1h8 TO /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655/AnsiballZ_file.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+rwx /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655/ /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655/AnsiballZ_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/local/bin/python3.12 /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655/AnsiballZ_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1755279565.3375456-2116-59485947555655/ > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
    "changed": false,
    "diff": {
        "after": {
            "path": "/tmp/test_dir"
        },
        "before": {
            "path": "/tmp/test_dir"
        }
    },
    "gid": 0,
    "group": "root",
    "invocation": {
        "module_args": {
            "_diff_peek": null,
            "_original_basename": null,
            "access_time": null,
            "access_time_format": "%Y%m%d%H%M.%S",
            "attributes": null,
            "follow": true,
            "force": false,
            "group": null,
            "mode": null,
            "modification_time": null,
            "modification_time_format": "%Y%m%d%H%M.%S",
            "owner": null,
            "path": "/tmp/test_dir",
            "recurse": false,
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "src": null,
            "state": "directory",
            "unsafe_writes": false
        }
    },
    "mode": "0755",
    "owner": "root",
    "path": "/tmp/test_dir",
    "size": 4096,
    "state": "directory",
    "uid": 0
}

TASK [Trigger acl module crash (no permissions set)] **********************************************************************************
task path: /opt/u.yml:9
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998 `" && echo ansible-tmp-1755279565.5967522-2141-106969790720998="` echo /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998 `" ) && sleep 0'
Using module file /usr/local/lib/python3.12/site-packages/ansible_collections/ansible/posix/plugins/modules/acl.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-211298fmm1a0/tmpstjdjm3_ TO /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+rwx /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/ /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/local/bin/python3.12 /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.ansible.posix.plugins.modules.acl', init_globals=dict(_module_fqn='ansible_collections.ansible.posix.plugins.modules.acl', _modlib_path=modlib_path),
  File "<frozen runpy>", line 226, in run_module
  File "<frozen runpy>", line 98, in _run_module_code
  File "<frozen runpy>", line 88, in _run_code
  File "/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py", line 410, in <module>
  File "/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py", line 382, in main
  File "/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py", line 186, in build_entry
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1755279565.5967522-2141-106969790720998/AnsiballZ_acl.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.ansible.posix.plugins.modules.acl', init_globals=dict(_module_fqn='ansible_collections.ansible.posix.plugins.modules.acl', _modlib_path=modlib_path),\n  File \"<frozen runpy>\", line 226, in run_module\n  File \"<frozen runpy>\", line 98, in _run_module_code\n  File \"<frozen runpy>\", line 88, in _run_code\n  File \"/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py\", line 410, in <module>\n  File \"/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py\", line 382, in main\n  File \"/tmp/ansible_ansible.posix.acl_payload_8cxq4_j4/ansible_ansible.posix.acl_payload.zip/ansible_collections/ansible/posix/plugins/modules/acl.py\", line 186, in build_entry\nTypeError: unsupported operand type(s) for +: 'NoneType' and 'str'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error",
    "rc": 1
}

PLAY RECAP ****************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载