The fallback to a straight Fisher-Yates shuffle needs to occur whenever the
sum of the *remaining* weights is zero, or else the remaining records will
not be reordered. Testing only once at the beginning covers the case when
all weights are zero, and obviously no shuffling is needed when only one
weight is zero; but other weight combinations are possible, such as (1, 0, 0).
Prior to this change, given two records of weight 1 the algorithm would
return them in the order (0,1) with 100% probability instead of the
desired 50%. This was due to an off-by-one error in the range test.
srv_rand() returns a float in the range [0.0, 1.0[, so r is an integer in the
range [0, total[. The correct probability for record 0 to be chosen is
a[0].weight/total, not (a[0].weight+1)/total.
Add LDAP_OPT_X_SASL_CBINDING option to define the binding type to use,
defaults to "none".
Add "tls-endpoint" binding type implementing "tls-server-end-point" from
RCF 5929, which is compatible with Windows.
Fix "tls-unique" to include the prefix in the bindings as per RFC 5056.
Always retry ldap_int_tls_connect() if it didn't complete,
regardless of blocking or non-blocking socket. Code from
ITS#7428 was wrong to only retry for async.
Since GnuTLS moved to implicit initialization on library load, calling
this function deinitializes GnuTLS and then re-initializes it.
When GnuTLS uses /dev/urandom as an entropy source (getrandom() not
available, or older versions of GnuTLS), and the application closed all
file descriptors at startup, this could result in GnuTLS opening
/dev/urandom over one of the application's file descriptors when
re-initialized.
Additionally, the custom mutex functions are never reset, so if libldap
is unloaded (for example via dlclose()) after calling this, its code may
be unmapped and the application could crash when GnuTLS calls the mutex
functions.
On typical systems, GnuTLS system mutexes are probably the same as what
libldap uses anyway.