Hello,
It has been brought to my attention that some PHP code using LDAP connect was broken by the update to PHP 5.6.11.
This is because the use on ldap_connect(host:port) is not allowed anymore.
You have to use either ldap_connect(host, port) or ldap_connect(ldap://host:port).
The use of ldap_connect(host:port) without ldap:// is not something that is in the tests, and is not explicitely allowed by our documentation: http://php.net/manual/en/function.ldap-connect.php
(Maybe it could be made clearer than when not using ldaps://, ldap:// is still needed for an LDAP URI to be valid)
So basically my question is, is that something that should be "fixed" to be consistent with previous PHP version, or should it stay that way as this is what is documented and tested?
Here are the problems people encountered because of this change (most assume they have to use host and port separately and do not think to add the ldap:// in there):
https://www.netways.org/issues/2931
https://dev.icinga.org/issues/9298
https://github.com/owncloud/core/issues/20020
MCMic
So basically my question is, is that something that should be "fixed" to
be consistent with previous PHP version, or should it stay that way as this
is what is documented and tested?
An equivalent question: Do you want to support this syntax going forward?
It's a common enough format that users likely will try it before reading
the documentation. But supporting it implies the code, the documentation,
and now a footnote that it wasn't supported between 5.6.11 and 5.6.x.
IMO, forbid it, adding a version note to the documentation: "5.6.11 --
Support for the undocumented $host format 'hostname:port' was removed."
bishop
Am 03.11.15 um 15:23 schrieb Bishop Bettini:
So basically my question is, is that something that should be "fixed" to
be consistent with previous PHP version, or should it stay that way as this
is what is documented and tested?An equivalent question: Do you want to support this syntax going forward?
It's a common enough format that users likely will try it before reading
the documentation. But supporting it implies the code, the documentation,
and now a footnote that it wasn't supported between 5.6.11 and 5.6.x.IMO, forbid it, adding a version note to the documentation: "5.6.11 --
Support for the undocumented $host format 'hostname:port' was removed."bishop
Hi All
+1 on that solution. Just throwing "host:port" onto something doesn't
help anyone. Try that with "www.google.com:443" in your favourite
browser. Most will give you an error (if it's not port 80). So those
people that try it will eventually read the documentation on php.net and
then see that it's not supported.
The only extension I'd see to it would be to check whether someone is
trying that and raising an error in PHP describing that "this format is
not supported! Please use ldap(s)://hostname:port instead"
@come do you see to the version note in the documentation or shall I?
Cheers
Andreas
--
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org http://hei.gl/wiFKy7 |
+---------------------------------------------------------------------+
| http://hei.gl/root-ca |
+---------------------------------------------------------------------+
Hi Andreas,
Andreas Heigl wrote:
+1 on that solution. Just throwing "host:port" onto something doesn't
help anyone. Try that with "www.google.com:443" in your favourite
browser. Most will give you an error (if it's not port 80). So those
people that try it will eventually read the documentation on php.net and
then see that it's not supported.
If you give the port number for a non-HTTP TCP application then yes,
your browser will spit an error back at you, because HTTP is the
implicit URI scheme. That doesn't mean hostname:port is wrong, it's
perfectly valid for HTTP. Similarly, I could give my LDAP URI as
google.com:80 and get an error, but I don't think that's a fault with
hostname:port.
The PHP interpreter itself uses it for HTTP:
$ php -S localhost:8000
I'm unconvinced.
Thanks.
Andrea Faulds
http://ajf.me/
Am 03.11.15 um 20:07 schrieb Andrea Faulds:
Hi Andreas,
Andreas Heigl wrote:
+1 on that solution. Just throwing "host:port" onto something doesn't
help anyone. Try that with "www.google.com:443" in your favourite
browser. Most will give you an error (if it's not port 80). So those
people that try it will eventually read the documentation on php.net and
then see that it's not supported.If you give the port number for a non-HTTP TCP application then yes,
your browser will spit an error back at you, because HTTP is the
implicit URI scheme. That doesn't mean hostname:port is wrong, it's
perfectly valid for HTTP. Similarly, I could give my LDAP URI as
google.com:80 and get an error, but I don't think that's a fault with
hostname:port.The PHP interpreter itself uses it for HTTP:
$ php -S localhost:8000
I'm unconvinced.
Hi Andrea.
The documentation mentions two different ways of using ldap_connect:
either with 2 parameters being host and port (from which the port is
optional) or with a single parameter using an LDAP-URI. There is a third
possibility mentioned in one of the comments of passing in a string of
multiple LDAP-URIs separated by a space. But I couldn't find a mention
of "host:port".
As there is an explicit mention of an URI the scheme is mandatory. And
as the scheme is used to differentiate between ldap and ldaps it's a
somewhat different story than the paramteter to phps internal server as
that one ONLY serves http (AFAIK). And it is explicitly stated that the
first version of ldap_connect with two parameters only allows
connections via ldap (not ldaps). If you want to use ldaps as scheme you
are required to use the second form with the LDAP-URI. So if someone
passes a single parameter 'host:port' to ldap_connect I'm sure they want
to use ldaps as protocol?
In my eyes the main question is whether we want to support something
that was never intended and nowhere documented just because someone
tried something and by luck didn't break something. I'd consider the
possibility to pass 'host:port' as single parameter to ldap_connect as a
bug and not as a feature. Therefore I'd rather see that bug fixed sooner
than later. And have the documentation point out explicitly that using
'host:port' without a scheme is NOT supported even though it might have
once worked.
Cheers
Andreas
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org http://hei.gl/wiFKy7 |
+---------------------------------------------------------------------+
| http://hei.gl/root-ca |
+---------------------------------------------------------------------+
Hello,
About ldap_connect documentation, we got an interesting proposition there: https://github.com/owncloud/core/issues/20020#issuecomment-153387886
The idea is to documment the LDAP URI version as a default and only list the host, port syntax as a backward compatibilty thing.
Which it is IMO.
The fact that when using (host, port) SSL is not supported goes strongly in that direction.
http://php.net/manual/en/ldap.requirements.php already says OpenLDAP>=2.4 is needed so «If you are using OpenLDAP 2.x.x» can be removed.
What should be clear in the documentation :
- The LDAP URI scheme is the recommended way to call ldap_connect
- The ldap:// or ldaps:// is required
- People can use host, port if they do not need SSL
- Second parameter is not used if the first one is an LDAP scheme, so calling ldap_connect('ldap://localhost', 456) will use default port 389.
Does that seem ok?
MCMic
PS: just saw that Andreas Heigl already edited the doc, to some of it is already fixed. It could still be improved to recommend LDAP URIS more clearly.
What should be clear in the documentation :
- The LDAP URI scheme is the recommended way to call ldap_connect
- The ldap:// or ldaps:// is required
- People can use host, port if they do not need SSL
Agreed.
- Second parameter is not used if the first one is an LDAP scheme, so
calling ldap_connect('ldap://localhost', 456) will use default port 389.
I'd prefer this raise a notice, like "Second argument ignored when using
URI syntax. Port will default to 389. Did you mean 'ldap://localhost:456'
instead?"
bishop
Le mercredi 4 novembre 2015, 21:10:09 Bishop Bettini a écrit :
- Second parameter is not used if the first one is an LDAP scheme, so
calling ldap_connect('ldap://localhost', 456) will use default port 389.I'd prefer this raise a notice, like "Second argument ignored when using
URI syntax. Port will default to 389. Did you mean 'ldap://localhost:456'
instead?"
Good idea, this will avoid confusion. I will add this.
MCMic
Does this seems correct?
I got mail from someone saying that in previous version, calling ldap_connect($host, NULL) would use default port.
While now it is considered as trying to use port 0 and trigger an error.
I’m a bit troubled about it because the documentation says:
resource ldap_connect ([ string $hostname = NULL
[, int $port = 389 ]] )
So $port defaults to 389 and not to NULL, and it says nothing about accepting NULL
as second parameter.
That said, it does seem handful to be able to pass NULL
to ask for default port without remembering which one it is.
The context is something like:
$port = NULL;
if (isset($options['port'])) {
$port = $options['port'];
}
$resource = ldap_connect($host, $port);
Right now it either needs an if statement or hardcoding 389 instead of NULL
as the default. In the C code we use the constant LDAP_PORT for this but there is no such thing in PHP.
Any ideas/comments about this?
MCMic
I got mail from someone saying that in previous version, calling
ldap_connect($host, NULL) would use default port.
While now it is considered as trying to use port 0 and trigger an error.
I believe the current behavior (interpret as zero and trigger error) is
correct.
I’m a bit troubled about it because the documentation says:
resource ldap_connect ([ string $hostname =NULL
[, int $port = 389 ]] )
So $port defaults to 389 and not to NULL, and it says nothing about
acceptingNULL
as second parameter.
Let's compare to another PHP function that takes a numeric optional
parameter with a non-zero default:
array array_unique ( array $array [, int $sort_flags = SORT_STRING
] )
Note that SORT_STRING
=== 2, SORT_REGULAR
=== 0.
If you pass null for the second argument, you get the SORT_REGULAR
behavior, not the default SORT_STRING
behavior:
print_r(array_unique([ 1, '1', '1a' ], null));
That said, it does seem handful to be able to pass NULL
to ask for default
port without remembering which one it is.
The context is something like:
$port = NULL;
if (isset($options['port'])) {
$port = $options['port'];
}
$resource = ldap_connect($host, $port);
A few reasons I'd offer as arguments against this. $port is deprecated, so
why add features to deprecated arguments? Other PHP internal functions
don't behave this way (array_unique, socket_create_listen, ssh2_connect,
etc.), so why go against the grain? Why not document (in a comment) the
preferred way of doing this, which might be:
if (isset($options['port']))
$resource = ldap_connect($host, $options['port']);
else
$resource = ldap_connect($host);
Right now it either needs an if statement or hardcoding 389 instead of
NULL
as the default. In the C code we use the constant LDAP_PORT for this
but there is no such thing in PHP.
Any ideas/comments about this?
A PHP user-land constant like LDAP_DEFAULT_PORT might help users out
marginally, but to my knowledge no other port numbers are exposed as such
in PHP. Like ssh2_connect, for example, uses a raw 22.
If one wanted truly robust (paranoid) code, you'd probably want to do:
$port = getservbyname('ldap', 'tcp');
if (isset($options['port']) && is_numeric($options['port']))
$port = intval($options['port']);
$resource = ldap_connect($host, $port);
And this could go in a comment and solve the whole issue without code
changes.
Le mercredi 4 novembre 2015, 21:41:20 Bishop Bettini a écrit :
If one wanted truly robust (paranoid) code, you'd probably want to do:
$port = getservbyname('ldap', 'tcp');
if (isset($options['port']) && is_numeric($options['port']))
$port = intval($options['port']);$resource = ldap_connect($host, $port);
And this could go in a comment and solve the whole issue without code
changes.
Ok, so we could just put in the documentation the tip about getservbyname if one does not want to use 389 directly.
I got mail from someone saying that in previous version, calling
ldap_connect($host, NULL) would use default port.
While now it is considered as trying to use port 0 and trigger an error.I believe the current behavior (interpret as zero and trigger error) is
correct.
we have precedence for both behavior.
I’m a bit troubled about it because the documentation says:
resource ldap_connect ([ string $hostname =NULL
[, int $port = 389 ]] )
So $port defaults to 389 and not to NULL, and it says nothing about
acceptingNULL
as second parameter.Let's compare to another PHP function that takes a numeric optional
parameter with a non-zero default:array array_unique ( array $array [, int $sort_flags =
SORT_STRING
] )Note that
SORT_STRING
=== 2,SORT_REGULAR
=== 0.If you pass null for the second argument, you get the
SORT_REGULAR
behavior, not the defaultSORT_STRING
behavior:print_r(array_unique([ 1, '1', '1a' ], null));
on the other hand functions like ftp_connect assumes the default port when
passed NULL:
[tyrael@Ferencs-MBP]$ php -r '$c=ftp_connect("ftp.de.debian.org",
NULL);ftp_login($c, "anonymous", "");print_r(ftp_nlist($c, "-la ."));'
Array
(
[0] => debian-security
[1] => backports.org
[2] => debian-archive
[3] => .
[4] => HEADER.html
[5] => .welcome.msg
[6] => debian-backports
[7] => debian-ports
[8] => debian-cd
[9] => debian
[10] => ..
[11] => pub
)
That said, it does seem handful to be able to pass
NULL
to ask for defaultport without remembering which one it is.
The context is something like:
$port = NULL;
if (isset($options['port'])) {
$port = $options['port'];
}
$resource = ldap_connect($host, $port);A few reasons I'd offer as arguments against this. $port is deprecated, so
why add features to deprecated arguments? Other PHP internal functions
don't behave this way (array_unique, socket_create_listen, ssh2_connect,
etc.), so why go against the grain? Why not document (in a comment) the
preferred way of doing this, which might be:if (isset($options['port']))
$resource = ldap_connect($host, $options['port']);
else
$resource = ldap_connect($host);
I'm fine with changing this for future versions but my understanding is
that this BC break (along with some others) was introduced in a micro
release (5.6.11 afair), so at least for 5.6 I would prefer restoring the
old behavior and for 7.0 I'm fine with the change but please document it in
NEWS and UPGRADING so we can incorporate it in the docs.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
Le vendredi 6 novembre 2015, 11:43:58 Ferenc Kovacs a écrit :
on the other hand functions like ftp_connect assumes the default port when
passed NULL:I'm fine with changing this for future versions but my understanding is
that this BC break (along with some others) was introduced in a micro
release (5.6.11 afair), so at least for 5.6 I would prefer restoring the
old behavior and for 7.0 I'm fine with the change but please document it in
NEWS and UPGRADING so we can incorporate it in the docs.
Ok, so I pushed a fix to treat NULL
(and 0 for that matter, same as in ftp_connect) into the default ldap port.
I pushed only to 5.6 as I think for 7 we should keep the error, it does not makes much sense to accept NULL
as port and the documentation does not mention it.
MCMic
Le vendredi 6 novembre 2015, 11:43:58 Ferenc Kovacs a écrit :
on the other hand functions like ftp_connect assumes the default port
when
passed NULL:I'm fine with changing this for future versions but my understanding is
that this BC break (along with some others) was introduced in a micro
release (5.6.11 afair), so at least for 5.6 I would prefer restoring the
old behavior and for 7.0 I'm fine with the change but please document it
in
NEWS and UPGRADING so we can incorporate it in the docs.Ok, so I pushed a fix to treat
NULL
(and 0 for that matter, same as in
ftp_connect) into the default ldap port.
I pushed only to 5.6 as I think for 7 we should keep the error, it does
not makes much sense to acceptNULL
as port and the documentation does not
mention it.MCMic
--
thanks!
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu