Greetings.
This command fails in an unexpected way:
% ldapsearch -x -H 'ldap:///dc=example,dc=net' '(cn=foo)' Could not parse LDAP URI(s)=ldap:///dc=example,dc=net (3)
It appears that ldapsearch wants me to escape the '=' and ',' in that URI:
% ldapsearch -x -H 'ldap:///dc%3dexample%2cdc%3dnet' '(cn=foo)' DNS SRV: Could not turn domain=example.net into a hostlist
But why? The manpage for ldapsearch says
-HÂ ldapuri Specify URI(s) referring to the ldap server(s); a list of URI, separated by whitespace or commas is expected; only the protocol/host/port fields are allowed. As an exception, if no host/port is specified, but a DN is, the DN is used to look up the corresponding host(s) using the DNS SRV records, according to RFC 2782. The DN must be a non-empty sequence of AVAs whose attribute type is "dc" (domain component), and must be escaped according to RFC 2396.
I read that as clearly saying (via the 'exception' branch of that paragraph) that the first -H argument is correct.
RFC digression:
According to RFC 2396, the /dc... is `"/" path_segments`, segments are composed of *pchar, and
pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
...which includes both '=' and ','. Thus those characters don't need to be escaped, by RFC 2396. Or, put another way, 'ldap:///dc=example,dc=net' _is_ escaped according to RFC2396, in the sense that nothing in it needs to be escaped.
Looking instead at RFC 4516, the 'dn' in the 'ldapurl' is a 'distinguishedName' from RFC 4514 which (Sect.3) permits '=' and ',' to be included. Sect.2.1 of 4516 requires that the URI must include <reserved>, <unreserved> or <pct-encoded> of RFC 3986, but if we look at that, then Sect.2.2 indicates that <reserved> includes both '=' and ','.
Thus the behaviour of ldapsearch, when parsing the -H option, doesn't appear to match the documentation.
Explanation:
Looking at common.c:tool_args and common.c line 1199, I see that it calls ldap_url_parselist to break the -H argument into a list of URIs, and this will separate dc=example,dc=net at the comma. And sure enough, in practice it's only the ',' that has to be escaped by %2c.
I believe this behaviour doesn't match the manpage, which (clearly in my reading of it) requires either a list of protocol/host/port URIs OR (the exception) a single URI containing no host/port but only a DN. That suggests that common.c:tool_args has to detect that exception/second case. Apart from the documentation issue, having to escape commas is both repeatedly surprising and a pain in the neck on the occasions when I want to use the dc=... syntax with ldapsearch.
Re detecting that exception, searching for "///" in the ldapuri string would seem to be sufficient, and calling ldap_url_parselist_int in that case (instead of ldap_url_parselist) with a sep argument of " " looks like it would do the job with a minimal change to the code.
Best wishes,
Norman
Hi,
Just guessing by the error message, but your DNS Server does have a valid service record for that Base DN? As the error message suggests otherwise, but I may as well be completely off here.
Otherwise, but I am sure you know that, with only two "/" you can alway use the hostname, in case the DNS serive record is missing:
ldapsearch -H ldap://server.example.net -b dc=example,dc=net" 'cn=foo'
Am 10.02.23 um 17:51 schrieb Norman Gray:
Greetings.
This command fails in an unexpected way:
% ldapsearch -x -H 'ldap:///dc=example,dc=net' '(cn=foo)' Could not parse LDAP URI(s)=ldap:///dc=example,dc=net (3)It appears that ldapsearch wants me to escape the '=' and ',' in that URI:
% ldapsearch -x -H 'ldap:///dc%3dexample%2cdc%3dnet' '(cn=foo)' DNS SRV: Could not turn domain=example.net into a hostlistBut why? The manpage for ldapsearch says
-HÂ ldapuri Specify URI(s) referring to the ldap server(s); a list of URI, separated by whitespace or commas is expected; only the protocol/host/port fields are allowed. As an exception, if no host/port is specified, but a DN is, the DN is used to look up the corresponding host(s) using the DNS SRV records, according to RFC 2782. The DN must be a non-empty sequence of AVAs whose attribute type is "dc" (domain component), and must be escaped according to RFC 2396.I read that as clearly saying (via the 'exception' branch of that paragraph) that the first -H argument is correct.
RFC digression:
According to RFC 2396, the /dc... is `"/" path_segments`, segments are composed of *pchar, and
pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","...which includes both '=' and ','. Thus those characters don't need to be escaped, by RFC 2396. Or, put another way, 'ldap:///dc=example,dc=net' _is_ escaped according to RFC2396, in the sense that nothing in it needs to be escaped.
Looking instead at RFC 4516, the 'dn' in the 'ldapurl' is a 'distinguishedName' from RFC 4514 which (Sect.3) permits '=' and ',' to be included. Sect.2.1 of 4516 requires that the URI must include <reserved>, <unreserved> or <pct-encoded> of RFC 3986, but if we look at that, then Sect.2.2 indicates that <reserved> includes both '=' and ','.
Thus the behaviour of ldapsearch, when parsing the -H option, doesn't appear to match the documentation.
Explanation:
Looking at common.c:tool_args and common.c line 1199, I see that it calls ldap_url_parselist to break the -H argument into a list of URIs, and this will separate dc=example,dc=net at the comma. And sure enough, in practice it's only the ',' that has to be escaped by %2c.
I believe this behaviour doesn't match the manpage, which (clearly in my reading of it) requires either a list of protocol/host/port URIs OR (the exception) a single URI containing no host/port but only a DN. That suggests that common.c:tool_args has to detect that exception/second case. Apart from the documentation issue, having to escape commas is both repeatedly surprising and a pain in the neck on the occasions when I want to use the dc=... syntax with ldapsearch.
Re detecting that exception, searching for "///" in the ldapuri string would seem to be sufficient, and calling ldap_url_parselist_int in that case (instead of ldap_url_parselist) with a sep argument of " " looks like it would do the job with a minimal change to the code.
Best wishes,
Norman
Ede, hello.
On 20 Feb 2023, at 12:49, Ede Wolf wrote:
Just guessing by the error message, but your DNS Server does have a valid service record for that Base DN? As the error message suggests otherwise, but I may as well be completely off here.
A good thought -- thanks -- but yes, the SRV records are set up correctly, and I can make the query if the ',' in the dc= list are escaped (even though RFC 2396 doesn't require that).
Otherwise, but I am sure you know that, with only two "/" you can alway use the hostname, in case the DNS serive record is missing:
ldapsearch -H ldap://server.example.net -b dc=example,dc=net" 'cn=foo'
Indeed, and that's what I do most of the time. In fact, this is a case where a sequence of host+port LDAP URIs is useful.
Best wishes,
Norman
Norman,
did you try to provide a hostname in the URI?
ldapsearch -x -H 'ldap://<HOST>/dc=example,dc=net' '(cn=foo)'
instead of
ldapsearch -x -H 'ldap:///dc=example,dc=net' '(cn=foo)'
?
Regards,
Uwe
Am 20.02.23 um 14:19 schrieb Norman Gray:
Ede, hello.
On 20 Feb 2023, at 12:49, Ede Wolf wrote:
Just guessing by the error message, but your DNS Server does have a valid service record for that Base DN? As the error message suggests otherwise, but I may as well be completely off here.
A good thought -- thanks -- but yes, the SRV records are set up correctly, and I can make the query if the ',' in the dc= list are escaped (even though RFC 2396 doesn't require that).
Otherwise, but I am sure you know that, with only two "/" you can alway use the hostname, in case the DNS serive record is missing:
ldapsearch -H ldap://server.example.net -b dc=example,dc=net" 'cn=foo'
Indeed, and that's what I do most of the time. In fact, this is a case where a sequence of host+port LDAP URIs is useful.
Best wishes,
Norman
Uwe, helllo.
On 20 Feb 2023, at 13:28, Uwe Sauter wrote:
ldapsearch -x -H 'ldap://<HOST>/dc=example,dc=net' '(cn=foo)'
instead of
ldapsearch -x -H 'ldap:///dc=example,dc=net' '(cn=foo)'
No: the documentation for the -H option says that the SRV-lookup form, with the dc= components, is only tried when the host:port element of the URI is empty.
Looking at the code, the problem does appear to be that common.c:tool_args attempts to break the -H argument into multiple LDAP URIs by separating at commas, as well as spaces. That's the right thing to do to match the first sentence of the ldapsearch(1) documentation of -H, but the second sentence there (the one starting 'As an exception...') doesn't mention a list of SRV names (sensibly, since an SRV record is implicitly a list anyway), so shouldn't, I think, attempt to split the argument.
As the code stands, you have to escape the ',' in order to trick the code into not splitting this argument.
I noted in the OP that there's a mild code change which would make this work as expected.
I'm raise this as a bugreport with suggested fix, since it doesn't sound from this discussion that there's something obvious I'm missing.
Best wishes,
Norman
openldap-technical@openldap.org