In LDAPProvider/src/Client.php, the search() function forces the LDAP connection to re-bind to the admin user credentials even if the connection is already bound to the login user's credentials. It does this by calling establishBinding() explicitly rather than just init().
In our environment, which is Active Directory, all users can search. This means it is not necessary to specify a separate admin account for searching. This reduces complexity in those environments. This task is to change the logic in Client.php to determine which user to bind to before searching.
Before any call to ldap_* that requires a user bound to the connection, if the connection is already bound to the admin user, or bound to the login user and there are no admin user credentials, then do nothing. Otherwise get the admin user credentials, if any, and use them to bind. If there are no admin user credentials, then the connection is bound to the anonymous (null) user.
This change in logic allows the login user to be used if no admin user was specified.
I implemented the following logic, which I may figure out how to attach as a possible resolution to this task. All the changes are in Client.php and specifically in establishBinding(). Here is the changed code in Client.php and tested in MW 1.32.0:
```
const BOUND_NONE = 0;
const BOUND_ADMIN = 1;
const BOUND_USER = 2;
public function __construct( Config $config ) {
$this->config = $config;
if ( $this->connection === null ) {
$this->connection = new PlatformFunctionWrapper();
}
$this->logger = LoggerFactory::getInstance( __CLASS__ );
$this->boundTo = self::BOUND_NONE;
$this->adminUserProvided = false;
}
protected function establishBinding() {
if ( $this->boundTo == self::BOUND_ADMIN || $this->boundTo == self::BOUND_USER && !$this->adminUserProvided ) {
return;
}
$this->init();
$username = null;
if ( $this->config->has( ClientConfig::USER ) ) {
$username = $this->config->get( ClientConfig::USER );
}
$password = null;
if ( $this->config->has( ClientConfig::PASSWORD ) ) {
$password = $this->config->get( ClientConfig::PASSWORD );
}
$this->adminUserProvided = ($username != null);
$ret = $this->connection->bind( $username, $password );
if ( $ret === false ) {
$error = $this->connection->error();
$errno = $this->connection->errno();
throw new MWException(
"Could not bind to LDAP: ($errno) $error"
);
}
$this->boundTo = BOUND_ADMIN;
}
```