Modificare una password utente di Windows Active Directory e LDS tramite LDAP

Questo articolo descrive come modificare una password utente di Windows Active Directory e LDS tramite LDAP.

Si applica a: Windows Active Directory
Numero KB originale: 269190

Riepilogo

In base a determinate restrizioni, è possibile impostare una password di Windows Active Directory e Lightweight Directory Services (LDS) tramite LDAP (Lightweight Directory Access Protocol). Questo articolo descrive come impostare o modificare l'attributo della password.

Questi passaggi si applicano anche agli utenti di Active Directory Application Mode (ADAM) e LDS e agli oggetti userProxy allo stesso modo degli utenti di AD. Per informazioni dettagliate, vedere altri suggerimenti alla fine dell'articolo.

Ulteriori informazioni

La password viene archiviata nel database AD e LDS in un oggetto utente nell'attributo unicodePwd . Questo attributo può essere scritto in condizioni limitate, ma non può essere letto. L'attributo può essere modificato solo; non può essere aggiunto alla creazione di oggetti o sottoposto a query da una ricerca.

Per modificare questo attributo, il client deve avere una connessione TLS (Transport Layer Security) /SSL (Transport Layer Security) a 128 bit al server. Anche una sessione crittografata che usa chiavi di sessione create da provider di servizi condivisi tramite Windows New Technology LAN Manager (NTLM) o Kerberos è accettabile purché venga soddisfatta la lunghezza minima della chiave.

Per rendere possibile questa connessione tramite TLS/SSL:

  • Il server deve disporre di un certificato server per una connessione RSA a 128 bit.
  • Il client deve considerare attendibile l'autorità di certificazione (CA) che ha generato il certificato del server.
  • Sia il client che il server devono essere in grado di eseguire la crittografia a 128 bit.

La sintassi dell'attributo unicodePwd è octet-string; tuttavia, il servizio directory prevede che la stringa octet conterrà una stringa UNICODE (come indica il nome dell'attributo). Ciò significa che tutti i valori per questo attributo passato in LDAP devono essere stringhe UNICODE con codifica BER (Regole di codifica di base) come stringa ottetto. Inoltre, la stringa UNICODE deve iniziare e terminare tra virgolette che non fanno parte della password desiderata.

Esistono due modi possibili per modificare l'attributo unicodePwd . Il primo è simile a una normale operazione di modifica della password da parte dell'utente. In questo caso, la richiesta di modifica deve contenere sia l'eliminazione che un'operazione di aggiunta. L'operazione di eliminazione deve contenere la password corrente con virgolette. L'operazione di aggiunta deve contenere la nuova password desiderata con virgolette.

Il secondo modo per modificare questo attributo è analogo a un amministratore che reimposta una password per un utente. A tale scopo, il client deve eseguire il binding come utente con autorizzazioni sufficienti per modificare la password di un altro utente. Questa richiesta di modifica deve contenere una singola operazione di sostituzione con la nuova password desiderata racchiusa tra virgolette. Se il client dispone di autorizzazioni sufficienti, questa password diventa la nuova password, indipendentemente dalla password precedente.

Le due funzioni seguenti forniscono esempi di queste operazioni:

ULONG ChangeUserPassword(WCHAR* pszUserDN, WCHAR* pszOldPassword,WCHAR* pszNewPassword)
{
    ULONG err = 1;
    LDAPMod modNewPassword;
    LDAPMod modOldPassword;
    LDAPMod *modEntry[3];
    BERVAL newPwdBerVal;
    BERVAL oldPwdBerVal;
    BERVAL *newPwd_attr[2];
    BERVAL *oldPwd_attr[2];
    WCHAR pszNewPasswordWithQuotes[1024];
    WCHAR pszOldPasswordWithQuotes[1024];
    
    // Build an array of LDAPMod.
    
    // For setting unicodePwd, this MUST be a double op.
    modEntry[0] = &modOldPassword;
    modEntry[1] = &modNewPassword;
    modEntry[2] = NULL;
    
    // Build mod struct for unicodePwd Add.
    modNewPassword.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
    modNewPassword.mod_type =L"unicodePwd";
    modNewPassword.mod_vals.modv_bvals = newPwd_attr;
    
    // Build mod struct for unicodePwd Delete.
    modOldPassword.mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
    modOldPassword.mod_type =L"unicodePwd";
    modOldPassword.mod_vals.modv_bvals = oldPwd_attr;
    
    // Password will be single valued, so we only have one element.
    newPwd_attr[0] = &newPwdBerVal;
    newPwd_attr[1]= NULL;
    oldPwd_attr[0] = &oldPwdBerVal;
    oldPwd_attr[1]= NULL;
    
    // Surround the passwords in quotes.
    wsprintf(pszNewPasswordWithQuotes,L"\"%s\"",pszNewPassword);
    wsprintf(pszOldPasswordWithQuotes,L"\"%s\"",pszOldPassword);
    
    // Build the BER structures with the UNICODE passwords w/quotes.
    newPwdBerVal.bv_len = wcslen(pszNewPasswordWithQuotes) * sizeof(WCHAR);
    newPwdBerVal.bv_val = (char*)pszNewPasswordWithQuotes;
    oldPwdBerVal.bv_len = wcslen(pszOldPasswordWithQuotes) * sizeof(WCHAR);
    oldPwdBerVal.bv_val = (char*)pszOldPasswordWithQuotes;
    
    // Perform single modify.
    err = ldap_modify_s(ldapConnection,
    pszUserDN,
    modEntry
    );
    
    if (err == LDAP_SUCCESS )
    wprintf(L"\nPassword successfully changed!\n");
    else
    wprintf(L"\nPassword change failed!\n");
    
    return err;
}
    
ULONG SetUserPassword(WCHAR* pszUserDN, WCHAR* pszPassword)
{
    ULONG err = 1;
    LDAPMod modPassword;
    LDAPMod *modEntry[2];
    BERVAL pwdBerVal;
    BERVAL *pwd_attr[2];
    WCHAR pszPasswordWithQuotes[1024];
    
    // Build an array of LDAPMod.
    // For setting unicodePwd, this MUST be a single op.
    modEntry[0] = &modPassword;
    modEntry[1] = NULL;
    
    // Build mod struct for unicodePwd. 
    modPassword.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
    modPassword.mod_type =L"unicodePwd";
    modPassword.mod_vals.modv_bvals = pwd_attr;
    
    // Password will be single valued, so we only have one element.
    pwd_attr[0] = &pwdBerVal;
    pwd_attr[1]= NULL;
    
    // Surround the password in quotes.
    wsprintf(pszPasswordWithQuotes,L"\"%s\"",pszPassword);
    
    // Build the BER structure with the UNICODE password.
    pwdBerVal.bv_len = wcslen(pszPasswordWithQuotes) * sizeof(WCHAR);
    pwdBerVal.bv_val = (char*)pszPasswordWithQuotes;
    
    // Perform single modify.
    err = ldap_modify_s(ldapConnection,
    pszUserDN,
    modEntry
    );
    
    if (err == LDAP_SUCCESS )
    wprintf(L"\nPassword succesfully set!\n");
    else
    wprintf(L"\nPassword set failed!\n");
    
    return err;
}

Consiglio

  • Per configurare le istanze di LDS usando gli oggetti UserProxy per la reimpostazione della password, è necessario consentire la delega vincolata dell'account del servizio LDS (impostazione predefinita: account computer LDS) ai controller di dominio nel caso in cui l'accesso utente usi Kerberos.
  • Se si usa l'associazione semplice LDAP, è necessario usare Windows Server 2022 o una versione più recente e impostare una voce del Registro di sistema per inoltrare le credenziali della sessione LDAP amministratore al controller di Dominio di Active Directory:
    Chiave del Registro di sistema: HKLM\system\currentcontrolset\services<LDS Instance>\Parameters
    Voce del Registro di sistema: Consenti tipo di accesso ClearText
    Digitare: REG_DWORD
    Dati: 0: Non consentire l'inoltro delle credenziali (impostazione predefinita)
              1: Consentire l'inoltro delle credenziali per la reimpostazione della password
  • Si noti che la modifica in entrambi i casi significa che il server LDS deve essere considerato un dispositivo di livello 0 in quanto può avviare attività sensibili alla sicurezza nel controller di dominio.

Si applica a

  • Windows Server 2012 Datacenter
  • Windows Server 2012 Standard
  • Windows Server 2012 R2 Datacenter
  • Windows Server 2012 R2 Standard
  • Windows Server 2016
  • Windows Server 2019
  • Windows Server 2022
  • Windows 8.1 Enterprise
  • Windows 8.1 Pro
  • Windows 10
  • Windows 11