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:
function ldap_create_page_control(
ld : PLDAP;
pagesize : ber_int_t;
cookie : pberval;
iscritical : integer;
var ctrlp : PLDAPControl): cint; cdecl; external;
function ldap_search_ext_s(
ld : PLDAP;
const base : pchar;
scope : cint;
const filter : pchar;
attrs : ppchar;
attrsonly : cbool;
serverctrls : PPLDAPControl;
clientctrls : PPLDAPControl;
timout : ptimeval;
sizelimit : cint;
var res : PLDAPMessage
): cint; cdecl; external;
Below are the same functions from ldap.h
LDAP_F( int )
ldap_create_page_control LDAP_P((
LDAP *ld,
ber_int_t pagesize,
struct berval *cookie,
int iscritical,
LDAPControl **ctrlp ));
LDAP_F( int )
ldap_search_ext_s LDAP_P((
LDAP *ld,
LDAP_CONST char *base,
int scope,
LDAP_CONST char *filter,
char **attrs,
int attrsonly,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeout,
int sizelimit,
LDAPMessage **res ));
This is the code that cause an access violation:
fResult := ldap_create_page_control(fLDAP,fPageSize,@Cookie,1,PPageControl);
if fResult<>LDAP_SUCCESS then Break;
fResult := ldap_search_ext_s(fLDAP,PChar(fBase),scope,pChar(fFilter),nil,true,@PPageControl,nil,timeout,fMaxEntries,fSearchResult);
if fResult<>LDAP_SUCCESS then Break;
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:
function TOpenLDAPSearch.Search: boolean;
Var timeout : pointer;
entry,new_entry : PLDAPMessage;
dn : pChar;
PageControl : LDAPControl;
PPageControl : PLDAPControl;
ReturnControl : PPLDAPCOntrol;
P1 : PLDAPControl;
P : LDAPControl;
Cookie : berval;
pCookie : PBerval;
berPageSize : Berval;
NumPages : integer;
MorePages : boolean;
ldapError : integer;
matcheddnp : pChar;
errmsgp : pChar;
preferralsp : ppChar;
S : string;
begin
Timeout := nil;
fNumEntries := 0;
Cookie.bv_len:=0;
Cookie.bv_val:=nil;
pCookie := @Cookie;
fEntries := TStringList.Create;
Repeat
fResult := ldap_create_page_control(fLDAP,fPageSize,@Cookie,1,PPageControl);
if fResult<>LDAP_SUCCESS then Break;
fResult := ldap_search_ext_s(fLDAP,PChar(fBase),scope,pChar(fFilter),nil,true,@PPageControl,nil,timeout,fMaxEntries,fSearchResult);
if fResult<>LDAP_SUCCESS then Break;
fResult := ldap_parse_result(fLDAP,fSearchResult,ldaperror,matcheddnp,errmsgp,preferralsp,ReturnControl,False);
if fResult<>LDAP_SUCCESS then Break;
P1 := ReturnControl^;
P := P1^;
fResult := ldap_parse_pageresponse_control(fLDAP, P1, NumPages, Cookie);
fNumEntries := ldap_count_entries(fLDAP,fSearchResult);
if (Cookie.bv_val=nil) or (fNumEntries<>fPageSize) then MorePages := False else MorePages := True;
entry := ldap_first_entry(fLDAP, fSearchResult);
while entry<>nil do
Begin
dn := ldap_get_dn(fLDAP,entry);
fEntries.Add(StrPas(dn));
new_entry := ldap_next_entry(fLDAP, entry);
ldap_memfree(entry);
entry := new_entry;
end;
Until MorePages=False;
fNumEntries := fEntries.Count;
end;
Any help or ideas will be appreciated.