Проверьте имя пользователя / пароль в Active Directory с ПК, который НЕ является частью домена
Изменить: Я изменил код в соответствии с комментарием Андрея Галатына и намекнул, что я не буду полагаться, что токен будет нулевым, если он недействителен, но он все еще не работает для ПК, которые не являются частью домена.
Я хочу убедиться, что пользователь ввел комбинацию имени пользователя и пароля, которая действительна на сервере LDAP.
В настоящее время я использую этот код:
function CheckWinUserAccount(Username, Password, Domain : string) : boolean;
var token: THandle;
begin
result:=False;
if LogonUser( PChar(Username), PChar(Domain), PChar(Password),
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) then
begin
CloseHandle(token);
result:=True;
end;
end;
Он отлично работает, если выполняется на ПК, который является частью домена LDAP, но не на ПК, который использует только компьютер LDAP в качестве DNS, но не является частью домена.
Мои данные:
- Домен: graz.local
- Имя пользователя: LDTest
Я попытался ввести имя пользователя как LDTest
, как graz\LDTest
и в качестве graz.local\LDTest
,
Я также попытался указать домен как graz
, graz.local
, ldap://graz.local
Ничего из этого не сработало. Любая идея?
Кстати: я не был уверен, возможно ли это вообще (доступ к серверу домена с компьютера, не являющегося доменом), но с помощью администратора LDAP (от Softerra) это работает.
1 ответ
Как отметил Андрей Галатын, при вызове "LogonUser" используйте LOGON32_LOGON_NETWORK вместо LOGON32_LOGON_INTERACTIVE. Имя пользователя не должно включать имя домена, имя домена может быть либо именем домена NetBIOS ("graz"), либо именем домена DNS ("graz.local").
РЕДАКТИРОВАТЬ: Использование "LogonUser" работает, только если клиент уже установил соединение с доменом.
Вот код, который выполняет аутентификацию с использованием LDAP.
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
JwaWinLDAP,
JwaRpcDce;
var
sUsername, sDomain, sPassword, sDC : String;
LDAP : PLDAP;
SWAI : SEC_WINNT_AUTH_IDENTITY;
begin
if (ParamCount <> 4) then
begin
WriteLn ('WinLdapTest [username] [domain] [password] [domain controller]');
Halt (1);
end; { if }
sUsername := ParamStr (1);
sDomain := ParamStr (2);
sPassword := ParamStr (3);
sDC := ParamStr (4);
LDAP := ldap_openW (PChar (sDC), LDAP_PORT);
if (Assigned (LDAP)) then
try
SWAI.User := PChar (sUserName);
SWAI.UserLength := Length (sUserName);
SWAI.Domain := PChar (sDomain);
SWAI.DomainLength := Length (sDomain);
SWAI.Password := PChar (sPassword);
SWAI.PasswordLength := Length (sPassword);
SWAI.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE;
if (ldap_bind_sW (LDAP, PChar (sDC), PChar (@SWAI),
LDAP_AUTH_NTLM) = LDAP_SUCCESS) then
WriteLN ('"ldap_bind" success')
else WriteLN ('"ldap_bind" failure');
finally
ldap_unbind (LDAP);
end { try / finally }
else WriteLn ('"ldap_open" failed');
end.
Код использует библиотеку JEDI API и предполагает, что вы используете Delphi 2009 или более позднюю версию (строки Unicode). Чтобы автоматически получить имя DC, вы можете вызвать DsGetDcName.