从不属于域的PC检查Active Directory中的用户名/密码

时间:2018-01-02 17:00:53

标签: delphi ldap delphi-2010

编辑:我根据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上,则可以正常工作。

我的数据:

  • 域名:graz.local
  • 用户名:LDTest

我尝试输入用户名LDTestgraz\LDTestgraz.local\LDTest

我还尝试将域名指定为grazgraz.localldap://graz.local

这些都没有效果。有什么想法吗?

顺便说一下:我不确定这是否可行(从非域PC访问域服务器),但使用LDAP管理员(Softerra)可以正常工作。

1 个答案:

答案 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