Recent

Author Topic: Help needed with calling openldap c api  (Read 428 times)

JohnnieK

  • New Member
  • *
  • Posts: 19
Help needed with calling openldap c api
« on: October 07, 2022, 10:58:40 am »
Hi

I am trying to write a ldap application using the openlap c api. I have most of it working, but I am having an issue with paging search results. I am pretty sure I am messing up some pointer, but I have been trying to get this working for the past week and I can't seem to get it working.

I am using Lazarus 2.2.2 on openSuSE Tumbleweed 64bit.

I am using the files from /usr/share/fpcsrc/packages/ldap/

The declaration of the functions that are giving me grief are:
Code: Pascal  [Select][+][-]
  1. function ldap_create_page_control(
  2.         ld : PLDAP;
  3.         pagesize : ber_int_t;
  4.         cookie : pberval;
  5.         iscritical : integer;
  6.         var ctrlp : PLDAPControl): cint; cdecl; external;
  7.  
  8. function ldap_search_ext_s(
  9.     ld              : PLDAP;
  10.     const base      : pchar;
  11.     scope           : cint;
  12.     const filter    : pchar;
  13.     attrs           : ppchar;
  14.     attrsonly       : cbool;
  15.     serverctrls     : PPLDAPControl;
  16.     clientctrls     : PPLDAPControl;
  17.     timout          : ptimeval;
  18.     sizelimit       : cint;
  19.     var res         : PLDAPMessage
  20.   ): cint; cdecl; external;    
  21.  

Below are the same functions from ldap.h

Code: C  [Select][+][-]
  1. LDAP_F( int )
  2. ldap_create_page_control LDAP_P((
  3.         LDAP *ld,
  4.         ber_int_t pagesize,
  5.         struct berval *cookie,
  6.         int iscritical,
  7.         LDAPControl **ctrlp ));
  8.  
  9. LDAP_F( int )
  10. ldap_search_ext_s LDAP_P((
  11.         LDAP                    *ld,
  12.         LDAP_CONST char *base,
  13.         int                             scope,
  14.         LDAP_CONST char *filter,
  15.         char                    **attrs,
  16.         int                             attrsonly,
  17.         LDAPControl             **serverctrls,
  18.         LDAPControl             **clientctrls,
  19.         struct timeval  *timeout,
  20.         int                             sizelimit,
  21.         LDAPMessage             **res ));
  22.  
  23.  
  24.  

This is the code that cause an access violation:

Code: Pascal  [Select][+][-]
  1.     fResult := ldap_create_page_control(fLDAP,fPageSize,@Cookie,1,PPageControl);
  2.     if fResult<>LDAP_SUCCESS then Break;
  3.     fResult := ldap_search_ext_s(fLDAP,PChar(fBase),scope,pChar(fFilter),nil,true,@PPageControl,nil,timeout,fMaxEntries,fSearchResult);
  4.     if fResult<>LDAP_SUCCESS then Break;
  5.  

If I replace the @PpageControl with nil, then it works, but I have not paging capability so I only get the first 1000 entries back.

Here is the complete procedure:
Code: Pascal  [Select][+][-]
  1. function TOpenLDAPSearch.Search: boolean;
  2.  Var timeout         : pointer;
  3.      entry,new_entry : PLDAPMessage;
  4.      dn              : pChar;
  5.      PageControl     : LDAPControl;
  6.      PPageControl    : PLDAPControl;
  7.      ReturnControl   : PPLDAPCOntrol;
  8.      P1              : PLDAPControl;
  9.      P               : LDAPControl;
  10.      Cookie          : berval;
  11.      pCookie         : PBerval;
  12.      berPageSize     : Berval;
  13.      NumPages        : integer;
  14.      MorePages       : boolean;
  15.      ldapError       : integer;
  16.      matcheddnp      : pChar;
  17.      errmsgp         : pChar;
  18.      preferralsp     : ppChar;
  19.      S               : string;
  20.   begin
  21.    Timeout := nil;
  22.    fNumEntries := 0;
  23.    Cookie.bv_len:=0;
  24.    Cookie.bv_val:=nil;
  25.    pCookie := @Cookie;
  26.    fEntries := TStringList.Create;
  27.    Repeat
  28.     fResult := ldap_create_page_control(fLDAP,fPageSize,@Cookie,1,PPageControl);
  29.     if fResult<>LDAP_SUCCESS then Break;
  30.     fResult := ldap_search_ext_s(fLDAP,PChar(fBase),scope,pChar(fFilter),nil,true,@PPageControl,nil,timeout,fMaxEntries,fSearchResult);
  31.     if fResult<>LDAP_SUCCESS then Break;
  32.     fResult := ldap_parse_result(fLDAP,fSearchResult,ldaperror,matcheddnp,errmsgp,preferralsp,ReturnControl,False);
  33.     if fResult<>LDAP_SUCCESS then Break;
  34.     P1 := ReturnControl^;
  35.     P := P1^;
  36.     fResult := ldap_parse_pageresponse_control(fLDAP, P1, NumPages, Cookie);
  37.     fNumEntries := ldap_count_entries(fLDAP,fSearchResult);
  38.     if (Cookie.bv_val=nil) or (fNumEntries<>fPageSize) then MorePages := False else MorePages := True;
  39.     entry := ldap_first_entry(fLDAP, fSearchResult);
  40.     while entry<>nil do
  41.      Begin
  42.       dn := ldap_get_dn(fLDAP,entry);
  43.       fEntries.Add(StrPas(dn));
  44.       new_entry := ldap_next_entry(fLDAP, entry);
  45.       ldap_memfree(entry);
  46.       entry := new_entry;
  47.      end;
  48.    Until MorePages=False;
  49.    fNumEntries := fEntries.Count;
  50.   end;
  51.  

Any help or ideas will be appreciated.

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Help needed with calling openldap c api
« Reply #1 on: October 07, 2022, 11:09:35 am »
at a guess (without seeing your record types e.g. LDAPControl):
You're mixing up c-types and fpc-native types
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

JohnnieK

  • New Member
  • *
  • Posts: 19
Re: Help needed with calling openldap c api
« Reply #2 on: October 07, 2022, 11:33:18 am »
Hi

Here is the declaration of LDAPControl:

Code: Pascal  [Select][+][-]
  1. PPPLDAPControl                    = ^PPLDAPControl;
  2.   PPLDAPControl                     = ^PLDAPControl;
  3.   PLDAPControl                      = ^LDAPControl;
  4.   LDAPControl                       = record
  5.     ldctl_oid               : pcchar;
  6.     ldctl_value             : berval;
  7.     ldctl_iscritical        : cchar;
  8.   end;                              

and here is the same section from ldap.h

Code: C  [Select][+][-]
  1. typedef struct ldapcontrol {
  2.         char *                  ldctl_oid;                      /* numericoid of control */
  3.         struct berval   ldctl_value;            /* encoded value of control */
  4.         char                    ldctl_iscritical;       /* criticality */
  5. } LDAPControl;    
  6.  

 

TinyPortal © 2005-2018