编辑:我根据Andrei Galatyn的评论修改了代码,并暗示我无法在无效时依赖令牌为零,但它仍不适用于PC& #39; s不属于域名。
我想验证用户是否输入了在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域的PC上执行,但在仅使用LDAP PC作为DNS但不属于域的PC上,则可以正常工作。
我的数据:
我尝试输入用户名LDTest
,graz\LDTest
和graz.local\LDTest
。
我还尝试将域名指定为graz
,graz.local
,ldap://graz.local
这些都没有效果。有什么想法吗?
顺便说一下:我不确定这是否可行(从非域PC访问域服务器),但使用LDAP管理员(Softerra)可以正常工作。
答案 0 :(得分:3)
正如Andrei Galatyn所说,使用LOGON32_LOGON_NETWORK代替
调用" LogonUser"时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 library并假设您正在使用Delphi 2009或更高版本(Unicode字符串)。要自动检索DC名称,您可以调用DsGetDcName。