LDAP를 통해 Windows Active Directory 및 LDS 사용자 암호 변경

이 문서에서는 LDAP를 통해 Windows Active Directory 및 LDS 사용자 암호를 변경하는 방법을 설명합니다.

적용 대상: Windows Active Directory
원본 KB 번호: 269190

요약

특정 제한 사항에 따라 LDAP(Lightweight Directory Access Protocol)를 통해 Windows Active Directory 및 LDS(Lightweight Directory Services) 암호를 설정할 수 있습니다. 이 문서에서는 암호 특성을 설정하거나 변경하는 방법을 설명합니다.

이러한 단계는 AD 사용자와 동일한 방식으로 ADAM(Active Directory 애플리케이션 모드) 및 LDS 사용자 및 userProxy 개체에도 적용됩니다. 자세한 내용은 문서의 끝에 있는 추가 힌트를 참조하세요.

추가 정보

암호는 유니코드Pwd 특성의 사용자 개체에 있는 AD 및 LDS 데이터베이스에 저장됩니다. 이 특성은 제한된 조건에서 작성할 수 있지만 읽을 수는 없습니다. 특성은 수정할 수 있습니다. 개체를 만들 때 추가하거나 검색을 통해 쿼리할 수 없습니다.

이 특성을 수정하려면 클라이언트에 서버에 대한 128비트 TLS(전송 계층 보안)/SSL(Secure Socket Layer) 연결이 있어야 합니다. 최소 키 길이가 충족되는 한 Windows NTLM(New Technology LAN Manager) 또는 Kerberos를 사용하여 SSP에서 만든 세션 키를 사용하는 암호화된 세션도 허용됩니다.

TLS/SSL을 사용하여 이 연결을 수행할 수 있습니다.

  • 서버에는 128비트 RSA 연결에 대한 서버 인증서가 있어야 합니다.
  • 클라이언트는 서버 인증서를 생성한 CA(인증 기관)를 신뢰해야 합니다.
  • 클라이언트와 서버 모두 128비트 암호화를 사용할 수 있어야 합니다.

unicodePwd 특성의 구문은 octet-string입니다. 그러나 디렉터리 서비스는 특성 이름에서 알 수 있듯이 octet-string에 유니코드 문자열이 포함될 것으로 예상합니다. 즉, LDAP에 전달된 이 특성의 값은 BER로 인코딩된 유니코드 문자열(기본 인코딩 규칙)이어야 합니다. 또한 UNICODE 문자열은 원하는 암호의 일부가 아닌 따옴표로 시작하고 끝나야 합니다.

유니코드Pwd 특성을 수정하는 방법에는 두 가지가 있습니다. 첫 번째는 일반 사용자 암호 변경 작업과 유사합니다. 이 경우 수정 요청에는 삭제 및 추가 작업이 모두 포함되어야 합니다. 삭제 작업에는 따옴표가 있는 현재 암호가 포함되어야 합니다. 추가 작업에는 따옴표가 있는 원하는 새 암호가 포함되어야 합니다.

이 특성을 수정하는 두 번째 방법은 관리자가 사용자의 암호를 재설정하는 것과 유사합니다. 이렇게 하려면 클라이언트가 다른 사용자의 암호를 수정할 수 있는 충분한 권한이 있는 사용자로 바인딩해야 합니다. 이 수정 요청에는 따옴표로 둘러싸인 새 원하는 암호로 단일 바꾸기 작업이 포함되어야 합니다. 클라이언트에 충분한 권한이 있는 경우 이 암호는 이전 암호에 관계없이 새 암호가 됩니다.

다음 두 함수는 이러한 작업의 예를 제공합니다.

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;
}

  • 암호 재설정을 위해 UserProxy 개체를 사용하여 LDS 인스턴스를 구성하려면 사용자 로그온이 Kerberos를 사용하는 경우 도메인 컨트롤러에 대한 LDS 서비스 계정(기본값: LDS 컴퓨터 계정)의 제한된 위임을 허용해야 합니다.
  • LDAP 단순 바인딩을 사용하는 경우 Windows Server 2022 또는 최신 버전을 사용하고 레지스트리 항목을 설정하여 관리자 LDAP 세션 자격 증명을 Active Directory 도메인 컨트롤러에 전달해야 합니다.
    레지스트리 키: HKLM\system\currentcontrolset\services<LDS Instance>\Parameters
    레지스트리 항목: ClearText 로그온 유형 허용
    유형: REG_DWORD
    데이터: 0: 자격 증명 전달을 허용하지 않음(기본값)
              1: 암호 재설정을 위한 자격 증명 전달 허용
  • 두 경우 모두 변경되면 도메인 컨트롤러에서 보안에 민감한 작업을 시작할 수 있으므로 LDS 서버는 계층 0 디바이스로 간주되어야 합니다.

적용 대상

  • 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