community.general
community.general copied to clipboard
ldap_search can not search whole domain
Summary
When I specify only the Domain-Component dn: 'DC=example,DC=com' the module bugs out. The Error message differs on scope: 'children/subordinate'
Issue Type
Bug Report
Component Name
ldap_search
Ansible Version
ansible [core 2.12.1]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/jochen/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/dist-packages/ansible
ansible collection location = /usr/share/ansible/collections:/home/jochen/.ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
jinja version = 3.0.3
libyaml = True
Community.general Version
# /usr/local/lib/python3.9/dist-packages/ansible_collections
Collection Version
----------------- -------
community.general 4.3.0
Configuration
COLLECTIONS_PATHS(/etc/ansible/ansible.cfg) = ['/usr/share/ansible/collections', '/home/jochen/.ansible/collections']
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 60
OS / Environment
Target is Debian11 Ldap-Server: Synology DSM 6.2.4 (Synology Directory Server 4.4.5, based on Samba 4.4.16)
Steps to Reproduce
- hosts: 'ldap_gatherer'
tasks:
- name: 'gather ldap-user'
community.general.ldap_search:
bind_dn: '{{ ldap_query_user.name }}'
bind_pw: '{{ ldap_query_user.password }}'
dn: 'DC=example,DC=com'
server_uri: '{{ ldap_url }}'
scope: 'children'
filter: '{{ vpn_user_filter }}'
attrs: 'sAMAccountName'
register: 'vpn_user'
- name: 'print'
ansible.builtin.debug:
var: vpn_user
Expected Results
print all users where "filter" matches
Actual Results
The full traceback is:
File "/tmp/ansible_community.general.ldap_search_payload_n5e6yudq/ansible_community.general.ldap_search_payload.zip/ansible_collections/community/general/plugins/modules/ldap_search.py", line 110, in main
File "/tmp/ansible_community.general.ldap_search_payload_n5e6yudq/ansible_community.general.ldap_search_payload.zip/ansible_collections/community/general/plugins/modules/ldap_search.py", line 158, in main
File "/tmp/ansible_community.general.ldap_search_payload_n5e6yudq/ansible_community.general.ldap_search_payload.zip/ansible_collections/community/general/plugins/modules/ldap_search.py", line 163, in perform_search
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 854, in search_s
return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 848, in search_ext_s
return self.result(msgid,all=1,timeout=timeout)[1]
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 740, in result
resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 744, in result2
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 748, in result3
resp_type, resp_data, resp_msgid, decoded_resp_ctrls, retoid, retval = self.result4(
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 758, in result4
ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 331, in _ldap_call
reraise(exc_type, exc_value, exc_traceback)
File "/usr/lib/python3/dist-packages/ldap/compat.py", line 44, in reraise
raise exc_value
File "/usr/lib/python3/dist-packages/ldap/ldapobject.py", line 315, in _ldap_call
result = func(*args,**kwargs)
fatal: [srvito01]: FAILED! => {
"changed": false,
"details": "{'desc': 'Operations error', 'info': '00002020: Operation unavailable without authentication'}",
"invocation": {
"module_args": {
"attrs": [
"sAMAccountName"
],
"bind_dn": "CN=ldap.query,CN=Users,DC=example,DC=com",
"bind_pw": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"dn": "DC=example,DC=com",
"filter": "(memberof:1.2.840.113556.1.4.1941:=CN=vpn_access,CN=Users,DC=example,DC=com)",
"referrals_chasing": "anonymous",
"sasl_class": "external",
"schema": false,
"scope": "children",
"server_uri": "ldap://domaincontroller.example.com",
"start_tls": false,
"validate_certs": true
}
},
"msg": "Attribute action failed."
}
When Changing scope to subordinate the error changes to:
"details": "{'desc': 'Protocol error', 'info': '00002021: Protocol error. Invalid scope'}",
Code of Conduct
- [X] I agree to follow the Ansible Code of Conduct
Files identified in the description:
If these files are incorrect, please update the component name
section of the description or use the !component
bot command.
cc @eryx12o45 @jtyr click here for bot help
After some more tests, I realized that "scope: subordinate" does not work at all.
Files identified in the description:
If these files are incorrect, please update the component name
section of the description or use the !component
bot command.
@JochenKorge were you able to get the results through this module if so how?
This looks like something on the LDAP server side. The module is quite simple and straightforward. Those responses come from the server. The module is only passing back the answer it receives from the LDAP server.
I disagree with russoz. Something is definitely wrong with the ldap_search module when using the scope 'subordinate' on the entire domain. While it is true that the response is being generates by the LDAP server, the testing indicates that the request to the LDAP server is the problem, that is the cause of the errors.
$ ansible-galaxy collection list | grep community.general
community.general 8.4.0
Common variables:
ldap_bind_user: "CN=bind_user,OU=ServiceAccounts,OU=<REDACTED>,DC=pro,DC=<REDACTED>,DC=com"
ldap_bind_password: <REDACTED>
ldap_server_url: ldap://ldap.pro.<redacted>.com
ldap_base_dn: "OU=ServiceAccounts,OU=<REDACTED>,DC=pro,DC=<REDACTED>,DC=com"
ldap_filter: cn=svc_account1
Here are 2 scenerios:
- name: TEST module
community.general.ldap_search:
server_uri: "{{ ldap_server_url }}" # -H
bind_dn: "{{ ldap_bind_user }}" # -D
bind_pw: "{{ ldap_bind_password }}" # -w
dn: "{{ ldap_base_dn }}" # -b
scope: onelevel # -s
filter: "{{ ldap_filter }}"
validate_certs: false
register: module_out
ignore_errors: true
- debug:
var: module_out
- name: TEST command line
ansible.builtin.command: ldapsearch -s "one" -b "{{ ldap_base_dn }}" -H "{{ ldap_server_url }}" -D "{{ ldap_bind_user }}" -w "{{ ldap_bind_password }}" "({{ ldap_filter }})"
changed_when: false
register: command_out
- debug:
var: command_out
In this first scenerio both the module and the command line provide the expected results.
- name: TEST module
community.general.ldap_search:
server_uri: "{{ ldap_server_url }}" # -H
bind_dn: "{{ ldap_bind_user }}" # -D
bind_pw: "{{ ldap_bind_password }}" # -w
dn: "{{ ldap_base_dn }}" # -b
scope: subordinate # -s
filter: "{{ ldap_filter }}"
validate_certs: false
#attrs: memberOf
register: module_out
ignore_errors: true
- debug:
var: module_out
- name: TEST command line
ansible.builtin.command: ldapsearch -s "sub" -b "{{ ldap_base_dn }}" -H "{{ ldap_server_url }}" -D "{{ ldap_bind_user }}" -w "{{ ldap_bind_password }}" "({{ ldap_filter }})"
changed_when: false
register: command_out
- debug:
var: command_out
In this second scenerio, the command line provides the expected results, but the module_out is
"module_out": {
"changed": false,
"details": "{'msgtype': 101, 'msgid': 4, 'result': 80, 'desc': 'Other (e.g., implementation specific) error', 'ctrls': [], 'info': '00000057: LdapErr: DSID-0C090DA2, comment: Error processing control, data 0, v4563'}",
"failed": true,
"msg": "Attribute action failed."
}