2013-08-30 7 views
0

Для поиска конкретного пользователя в службах Active Directory мы использовали ldap_search_sW API. Это, однако, сбой моего exe в случае Windows Server 2012. Код ошибки не возвращается, EXE просто перестает работать.Ошибка ldap_search_sW на Windows Server 2012 R2 X64?

У меня есть 32-разрядное приложение. Поэтому я предполагаю, что он загрузится из каталога «SysWow64». Вот пример строки о том, как это делается призвание: -

Декларация PLD:

type // record declaration begins 
    {$EXTERNALSYM PLDAP} 
    PLDAP = ^LDAP; 
    {$EXTERNALSYM LDAP} 
    LDAP = record 

     ld_sb: record 
     sb_sd: ULONG; 
     Reserved1: array [0..(10 * sizeof(ULONG))] of Byte; 
     sb_naddr: ULONG; // notzero implies CLDAP available 
     Reserved2: array [0..(6 * sizeof(ULONG)) - 1] of Byte; 
     // 
     // Following parameters MAY match up to reference implementation of LDAP 
     // 

    ld_host: PChar; 
    ld_version: ULONG; 
    ld_lberoptions: Byte; 

    // 
    // Safe to assume that these parameters are in same location as 
    // reference implementation of LDAP API. 
    // 

    ld_deref: ULONG; 

    ld_timelimit: ULONG; 
    ld_sizelimit: ULONG; 

    ld_errno: ULONG; 
    ld_matched: PChar; 
    ld_error: PChar; 
    ld_msgid: ULONG; 

    Reserved3: array [0..(6*sizeof(ULONG))] of Byte; 

    // 
    // Following parameters may match up to reference implementation of LDAP API. 
    // 

    ld_cldaptries: ULONG; 
    ld_cldaptimeout: ULONG; 
    ld_refhoplimit: ULONG; 
    ld_options: ULONG; 

end; // record declaration end 

pld : PLDAP; 
pld := Session.pld; // session PLD is assigned as is to it 
The sessions' PLD is initialized as 
ldappld := ldap_initW(PWideChar(ldapServerW), ldapPort) // this is eventually assigned to Session's PLD which is assigned to the PLD used Below 

LdapCheck(ldap_search_sW(pld, PWideChar('DC=esbs,DC=local'), LDAP_SCOPE_SUBTREE, '(objectCategory=user)', nil, 0, plmSearch)); 

Какие шаги я должен предпринять?

Вот окна дамп аварии EXE:

Problem signature: 
Problem Event Name: APPCRASH 
Application Name: project1.exe 
Application Version: 0.1.1.0 
Application Timestamp: 2a425e19 
Fault Module Name: KERNELBASE.dll 
Fault Module Version: 6.2.8400.0 
Fault Module Timestamp: 4fb7184e 
Exception Code: 000006ba 
Exception Offset: 00017945 
OS Version: 6.2.8400.2.0.0.400.8 
Locale ID: 1033 
Additional Information 1: 91d0 
Additional Information 2: 91d025961d4c758a8b5ea7ee1390f3b7 
Additional Information 3: c3ce 
Additional Information 4: c3cebe78f080ab69603c33ad36d75750 

Декларация функции:

{$EXTERNALSYM ldap_search_sW} 
    function ldap_search_sW(ld: PLDAP; base: PWideChar; scope: ULONG; filter, attrs: PWideChar; attrsonly: ULONG; var res: PLDAPMessage): ULONG; cdecl; 
+0

@DavidHeffernan: Я пробовал разные вещи. – CyprUS

+0

Должен признаться, я в шоке от этого кода исключения. У вас есть что-то вроде madExcept в приложении для сбора диагностических данных? –

+0

@DavidHeffernan: У меня Eureka Log 6. Должен ли я присоединить его к проекту, а затем попробовать? – CyprUS

ответ

0

Мы решили эту проблему и я отправляю решение здесь. Не было проблемы в функции ldap_search_sW, которую мы использовали. Перед подключением к ADS мы использовали для аутентификации имени пользователя и пароля. Затем мы использовали ldap_initW, ldap_set_optionW и ldap_simple_bind_sW для подключения к серверу.

Затем список пользователей читается ldap_search_sW, чтобы прочитать список пользователей. На сервере 2012, если часть аутентификации была пропущена, exe не сработал. аутентификация была сделана, как: -

function AuthenticateADSUserW(ADSUserName, ADSPassword, ADSip: String;Var Fun_Obj:String): Boolean; 
var 
    AuthResult : Integer; 
    hInstance: THandle; 
    ADSServerName, 
    ADSUsrNam, 
    ADSPwd, 
    ADSPortNo, 
    Error: Array [0..255] of char; 
    ldapDomain, 
    ldapUserName, 
    ldapPassword : WideString; 
    hr   : integer; 
    obj   : IADs; 
begin 
    try 
    Result := False; 
     Fun_Obj := ''; 
// Insert code to securely retrieve the user name and password. 
try 
    ldapDomain := UTF8Decode(ADSip); 
    ldapUserName := UTF8Decode(ADSUserName); 
    ldapPassword := UTF8Decode(ADSPassword); 

    CoInitialize(Nil); //Added By Sameer 

    hr := ADsOpenObject('LDAP://'+ldapDomain, 
         ldapUserName, 
         ldapPassword, 
         ADS_SECURE_AUTHENTICATION, 
         IADs, 
         obj); 
    Fun_Obj := obj.ADsPath ; 
    if Succeeded(hr) then 
     Result := True; 

except 
    on e : exception do 
    begin 
    escan.Updatelog('Error '+e.ClassName + ': ' + e.Message,1,0); 
     Result := False; 
    end; 
    //lblMessage.Caption := e.ClassName + ': ' + #13#10 + e.Message; 
end; 
finally 
    CoUninitialize; 
end; 
end; 

Мы пропустили это и вместо проверки подлинности пути получения базового DN предоставленного имени пользователя. Если BASE DN возвращается, пользователь считается аутентифицированным. Если возвращается пустым, пользователь не аутентифицируется.

Надеюсь, это поможет кому-то.

Смежные вопросы