Active Directory no Server 2012 - Configuração adequada para alterar senhas via programação

5

Esta questão estava anteriormente no StackOverflow, como eu pensei que era um problema de programação. Parece que é mais um problema configurar o Active Directory corretamente, então mudei-o para cá.

Ok, já estou nisso há algum tempo, mas não encontrei minha solução. Eu rotineiramente me conecto ao OpenLDAP com o servidor em que estou, e tudo funciona bem com SSL e LDAPs. No entanto, agora preciso mudar para o Active Directory e estou tendo problemas.

Para configurar o sistema, fiz o seguinte: 1) Exportou meu certificado do Server 2012: link

2) Convertei meu certificado de DER para PEM: link

3) Certifique-se de que TLS_REQCERT foi definido como "nunca"

4) Confirmei que meu arquivo ldap.conf estava apontando para o local correto do meu certificado.

Boom! Consegui me conectar via ldap_connect () e consegui me ligar ao meu usuário. No entanto, quando fui modificar uma senha, recebi a sempre útil mensagem de erro de "Servidor não disponível para execução".

Algumas pessoas sugerem que isso é um problema com o SSL. Então, fiz alguns testes com o comando:

*ldapsearch -H "ldaps://my.domain.tld" -b "" -s base -Omaxssf=0 -d7*

Os resultados que recebo são:

ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP my.domain.tld:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying ip.add.re.ss:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0

TLS: loaded CA certificate file /etc/openldap/certs/cert-name.pem
... certificate data ...
TLS: certificate [CN=my.domain.tld] **is valid**
... more certificate data ...
* host: my.domain.tld  port: 636  (default)
  refcnt: 2  status: Connected
  last used: Fri Feb 21 11:50:13 2014

Portanto, parece que estou conectado e que meu certificado é válido.

Tentando uma pesquisa na linha de comando:

ldapsearch -H "ldaps://my.domain.tld:636" -D "[email protected]" -W -x -b "CN=Person I. M. Lookingfor,CN=Users,DC=my,DC=domain,DC=tld"

Retorna todas as informações que espero recuperar.

Neste ponto, não acho que seja um problema com o código, por mais que eu acredite que haja alguma configuração que ainda esteja faltando no AD. Eu não sou uma pessoa do Windows, então eu não sei o que mais eu poderia estar perdendo. Quaisquer pensamentos adicionais seriam apreciados.

CÓDIGO PARA GERAR LDIF

function encodePwd($new_password) {
        $newpass = '';
        $new_password = "\"".$new_password."\"";
        $len = strlen($new_password);
        for ($i = 0; $i < $len; $i++) {
                $newpass .= "{$new_password{$i}}dn: CN=Tester B. Testerton,CN=Users,DC=my,DC=domain,DC=tld
changetype: modify
replace: unicodePwd
unicodePwd:: IgBiAHUAQAAoADUAJABpAF4APQA5AGwAawBDACIA
0"; } $newpass = base64_encode($newpass); return $newpass; }

LDIF resultante:

$mods["unicodePwd"] = $new_pass64;
if(ldap_modify($ldap_conx,$ldap_user_dn,$mods) === false)
{
    $e = ldap_error($ldap_conx);
    $e_no = ldap_errno($ldap_conx);
    echo "Error attempting to modify password in LDAP for user: $uname\n";
} else {
    echo "Success! Changed password for user: $uname\n";
}

Então o código tenta:

Logging in as current user using SSPI
Importing directory from file ".\tester.ldif"
Loading entries..
1 entry modified successfully.

The command has completed successfully

Alterei o grupo "Usuários do domínio" para "Gerenciado por" minha conta de usuário administrativa. Em seguida, executei o comando ldifde no PowerShell como Administrador e ele funcionou onde não funcionava antes de se tornar o "gerenciador":

*ldapsearch -H "ldaps://my.domain.tld" -b "" -s base -Omaxssf=0 -d7*

No entanto, ainda não consigo modificar a senha via PHP; algo ainda está faltando. Eu uso rotineiramente este servidor Linux para atualizar os servidores OpenLDAP e Novell eDirectory, então eu sei que minhas configurações LDAP para PHP estão corretas.

O meu problema parece, é mais com a configuração do Active Directory Server para uso com atualizações programáticas. Eu tentei a atualização de senha com o Python, mas os resultados são os mesmos.

Atualizar Eu olhei para o link fornecido por Ryan ( link ) e confirmei que minha tentativa de converter o A senha está, de fato, convertendo para a codificação correta (isto é, "carro" converte para IgBjAGEAcgAiAA == como no artigo). Parece que agora é preciso descobrir como adicionar direitos estendidos ao meu gerenciador de LDAP.

    
por mike 24.02.2014 / 01:28

1 resposta

5

Como você já sabe, atualizar o atributo unicodePwd de uma conta de usuário remotamente requer uma conexão SSL / TLS de 128 bits ou melhor com o controlador de domínio, por padrão. Ou SASL se 2008R2 ou 2012. Parece que você já está coberto desde que você tenha um certificado e esteja utilizando LDAPS.

Além disso, apenas para informações públicas, o atributo unicodePwd é write -only. Nunca é retornado no resultado de uma pesquisa LDAP.

Também vejo que você está colocando a senha de texto sem formatação entre aspas e, em seguida, a codificação base64, que estão corretas. Você está tão perto!

Mas o que eu não vejo no seu código é onde você está garantindo que a codificação é UTF-16. tem para ser UTF-16. UTF-16 little endian, então codificado em base64, para ser exato.

"... the DC requires that the password value be specified in a UTF-16 encoded Unicode string containing the password surrounded by quotation marks, which has been BER-encoded as an octet string per the Object(Replica-Link) syntax."

Além disso, só para não perdermos o óbvio, garanta as permissões corretas:

For the password change operation to succeed, the server enforces the requirement that the user or inetOrgPerson object whose password is being changed must possess the "User-Change-Password" control access right on itself,

(ou seja, a conta não tem o sinalizador "o usuário não pode alterar a senha",)

and that Vdel must be the current password on the object. For the password reset to succeed, the server enforces the requirement that the client possess the "User-Force-Change-Password" control access right on the user or inetOrgPerson object whose password is to be reset.

E, novamente, para não ignorarmos o óbvio, verifique se o novo valor que você está tentando definir atende à política de senha do domínio.

Eu não falo PHP ou Perl tão bem, mas aqui está um Powershell que obtém a senha no formato codificado corretamente que você precisa:

PS C:\> [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("'"SweetNewPwd123!'""))
IgBTAHcAZQBlAHQATgBlAHcAUAB3AGQAMQAyADMAIQAiAA==

Vamos refletir sobre a documentação do sempre misterioso atributo unicodePwd :

link

Além disso, como leitura suplementar, confira este post:

link

    
por 24.02.2014 / 02:34