diff --git a/src/Ldap.php b/src/Ldap.php index a96ecff..9ef7a53 100644 --- a/src/Ldap.php +++ b/src/Ldap.php @@ -8,6 +8,7 @@ final class Ldap { /** @var resource|\LDAP\Connection */ private $connect; + private bool $encrypted; public function __construct() { @@ -20,19 +21,22 @@ final class Ldap ldap_set_option($this->connect, LDAP_OPT_REFERRALS, 0); ldap_set_option($this->connect, LDAP_OPT_NETWORK_TIMEOUT, 5); + $this->encrypted = str_starts_with(strtolower($server), 'ldaps://'); + // O AD recusa operações sensíveis (troca de senha via unicodePwd) em canal - // não criptografado ("Server is unwilling to perform"). Se o servidor não - // for ldaps://, negocia STARTTLS antes de qualquer bind. - if (!str_starts_with(strtolower($server), 'ldaps://')) { - if (!@ldap_start_tls($this->connect)) { - throw new LdapException( - 'Falha ao negociar STARTTLS com o LDAP: ' . ldap_error($this->connect) . - '. Troque ldap.server para ldaps:// no config/local.php se o servidor não suportar STARTTLS.' - ); - } + // não criptografado. Tenta STARTTLS só como bônus: se o servidor não suportar + // (nem todo AD aceita na 389), segue sem criptografia -- buscas/bind continuam + // funcionando normalmente, só a troca de senha vai exigir isso explicitamente. + if (!$this->encrypted && @ldap_start_tls($this->connect)) { + $this->encrypted = true; } } + public function isEncrypted(): bool + { + return $this->encrypted; + } + /** * Tenta autenticar o usuário com a própria senha dele (bind direto). * Retorna true/false, nunca lança por credencial errada. @@ -118,6 +122,14 @@ final class Ldap public function modify(string $dn, array $attributes): void { + if (array_key_exists('unicodePwd', $attributes) && !$this->encrypted) { + throw new LdapException( + 'Não foi possível negociar um canal seguro (STARTTLS) com o LDAP, e o Active Directory ' . + 'exige isso para trocar senha. Peça ao time de AD para liberar STARTTLS na porta 389, ' . + 'ou troque ldap.server para ldaps://... (porta 636) no config/local.php.' + ); + } + $ok = @ldap_mod_replace($this->connect, $dn, $attributes); if (!$ok) { throw new LdapException('Erro ao modificar LDAP: ' . ldap_error($this->connect)); -- libgit2 0.21.2