enhance ldapclient so it can actually formulate, encode and send search
request.
This commit is contained in:
5
Makefile
5
Makefile
@@ -1,4 +1,4 @@
|
||||
#DEBUG=1
|
||||
DEBUG=1
|
||||
|
||||
all: t t1 t2 bindrequest tinyldap ldapclient
|
||||
|
||||
@@ -13,7 +13,8 @@ scan_ldapbindrequest.o scan_ldapbindresponse.o scan_ldapresult.o \
|
||||
scan_ldapstring.o scan_ldapsearchfilter.o scan_ldapsearchrequest.o \
|
||||
freefilter.o freeava.o scan_ldapava.o fmt_ldapsearchresultentry.o \
|
||||
fmt_ldapstring.o freepal.o scan_ldapsearchresultentry.o \
|
||||
fmt_ldapresult.o
|
||||
fmt_ldapresult.o fmt_ldappal.o fmt_ldapadl.o fmt_ldapava.o \
|
||||
fmt_ldapsearchfilter.o fmt_ldapsearchrequest.o
|
||||
|
||||
ldif.a: ldif_parse.o ldap_match.o strduptab.o strstorage.o
|
||||
|
||||
|
||||
24
fmt_ldapadl.c
Normal file
24
fmt_ldapadl.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
struct AttributeDescriptionList* x=adl;
|
||||
long sum=0;
|
||||
int tmp;
|
||||
while (x) {
|
||||
sum+=fmt_asn1OCTETSTRING(0,0,x->a.l);
|
||||
x=x->next;
|
||||
}
|
||||
tmp=fmt_asn1SET(dest,sum);
|
||||
sum+=tmp;
|
||||
if (dest) {
|
||||
dest+=tmp;
|
||||
x=adl;
|
||||
while (x) {
|
||||
dest+=fmt_ldapstring(dest,&x->a);
|
||||
x=x->next;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
10
fmt_ldapava.c
Normal file
10
fmt_ldapava.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
int fmt_ldapava(char* dest,struct AttributeValueAssertion* a) {
|
||||
long sum,l;
|
||||
sum=fmt_ldapstring(dest,&a->desc);
|
||||
if (dest) dest+=sum;
|
||||
l=fmt_ldapstring(dest,&a->value);
|
||||
return sum+l;
|
||||
}
|
||||
24
fmt_ldappal.c
Normal file
24
fmt_ldappal.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
int fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
||||
// int l,l2,sum;
|
||||
long sum,l,l2;
|
||||
if (!pal) return 0;
|
||||
sum=fmt_ldapstring(0,&pal->type);
|
||||
/* look how much space the adl needs */
|
||||
l=fmt_ldapadl(0,pal->values);
|
||||
/* write sequence header */
|
||||
l2=fmt_asn1SEQUENCE(dest,l+sum);
|
||||
if (dest) {
|
||||
fmt_ldapstring(dest+l2,&pal->type);
|
||||
dest+=sum+l2;
|
||||
}
|
||||
sum+=l+l2;
|
||||
if (dest) {
|
||||
fmt_ldapadl(dest,pal->values);
|
||||
dest+=l;
|
||||
}
|
||||
return sum+fmt_ldappal(dest,pal->next);
|
||||
}
|
||||
|
||||
55
fmt_ldapsearchfilter.c
Normal file
55
fmt_ldapsearchfilter.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <byte.h>
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
Filter ::= CHOICE {
|
||||
and [0] SET OF Filter,
|
||||
or [1] SET OF Filter,
|
||||
not [2] Filter,
|
||||
equalityMatch [3] AttributeValueAssertion,
|
||||
substrings [4] SubstringFilter,
|
||||
greaterOrEqual [5] AttributeValueAssertion,
|
||||
lessOrEqual [6] AttributeValueAssertion,
|
||||
present [7] AttributeDescription,
|
||||
approxMatch [8] AttributeValueAssertion,
|
||||
extensibleMatch [9] MatchingRuleAssertion }
|
||||
*/
|
||||
|
||||
int fmt_ldapsubstring(char* dest,struct Substring* s) {
|
||||
long sum=0,tmp;
|
||||
while (s) {
|
||||
tmp=fmt_asn1string(dest,PRIVATE,CONSTRUCTED,s->substrtype,s->s.s,s->s.l);
|
||||
if (dest) dest+=tmp; sum+=tmp;
|
||||
s=s->next;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
||||
long sum,tmp;
|
||||
switch (f->type) {
|
||||
case AND: case OR: case NOT:
|
||||
sum=fmt_ldapsearchfilter(dest,f->x); break;
|
||||
case EQUAL: case GREATEQUAL: case LESSEQUAL: case APPROX:
|
||||
sum=fmt_ldapava(dest,&f->ava); break;
|
||||
case SUBSTRING:
|
||||
{
|
||||
char* nd=dest;
|
||||
sum=fmt_ldapstring(nd,&f->ava.desc);
|
||||
sum+=fmt_ldapsubstring(nd+sum,f->substrings);
|
||||
}
|
||||
break;
|
||||
case PRESENT:
|
||||
sum=fmt_ldapstring(dest,&f->ava.desc);
|
||||
break;
|
||||
default: return 0;
|
||||
}
|
||||
tmp=fmt_asn1length(0,sum);
|
||||
if (!dest) return sum+tmp+1;
|
||||
if (dest) byte_copyr(dest+tmp+1,sum,dest);
|
||||
fmt_asn1tag(dest,PRIVATE,CONSTRUCTED,f->type);
|
||||
fmt_asn1length(dest+1,sum);
|
||||
return sum+tmp+1;
|
||||
}
|
||||
22
fmt_ldapsearchrequest.c
Normal file
22
fmt_ldapsearchrequest.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
int fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) {
|
||||
int l,sum=0;
|
||||
sum=fmt_ldapstring(dest,&sr->baseObject);
|
||||
if (dest) dest+=sum;
|
||||
l=fmt_asn1ENUMERATED(dest,sr->scope);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_asn1ENUMERATED(dest,sr->derefAliases);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_asn1INTEGER(dest,sr->sizeLimit);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_asn1INTEGER(dest,sr->timeLimit);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_asn1BOOLEAN(dest,sr->typesOnly);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_ldapsearchfilter(dest,sr->filter);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
l=fmt_ldapadl(dest,sr->attributes);
|
||||
return sum+l;
|
||||
}
|
||||
@@ -1,48 +1,6 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
struct AttributeDescriptionList* x=adl;
|
||||
long sum=0;
|
||||
int tmp;
|
||||
while (x) {
|
||||
sum+=fmt_asn1OCTETSTRING(0,0,x->a.l);
|
||||
x=x->next;
|
||||
}
|
||||
tmp=fmt_asn1SET(dest,sum);
|
||||
sum+=tmp;
|
||||
if (dest) {
|
||||
dest+=tmp;
|
||||
x=adl;
|
||||
while (x) {
|
||||
dest+=fmt_ldapstring(dest,&x->a);
|
||||
x=x->next;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
||||
// int l,l2,sum;
|
||||
long sum,l,l2;
|
||||
if (!pal) return 0;
|
||||
sum=fmt_ldapstring(0,&pal->type);
|
||||
/* look how much space the adl needs */
|
||||
l=fmt_ldapadl(0,pal->values);
|
||||
/* write sequence header */
|
||||
l2=fmt_asn1SEQUENCE(dest,l+sum);
|
||||
if (dest) {
|
||||
fmt_ldapstring(dest+l2,&pal->type);
|
||||
dest+=sum+l2;
|
||||
}
|
||||
sum+=l+l2;
|
||||
if (dest) {
|
||||
fmt_ldapadl(dest,pal->values);
|
||||
dest+=l;
|
||||
}
|
||||
return sum+fmt_ldappal(dest,pal->next);
|
||||
}
|
||||
|
||||
int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) {
|
||||
int l,sum=0;
|
||||
sum=fmt_ldapstring(dest,&sre->objectName);
|
||||
|
||||
3
ldap.h
3
ldap.h
@@ -97,6 +97,9 @@ int fmt_ldapsearchfilter(char* dest,struct Filter* f);
|
||||
int fmt_ldapsearchrequest(char* dest,struct SearchRequest* s);
|
||||
int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre);
|
||||
int fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral);
|
||||
int fmt_ldappal(char* dest,struct PartialAttributeList* pal);
|
||||
int fmt_ldapava(char* dest,struct AttributeValueAssertion* a);
|
||||
int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl);
|
||||
|
||||
#define fmt_ldapbindresponse(a,b,c,d,e) fmt_ldapresult(a,b,c,d,e)
|
||||
#define fmt_ldapsearchresultdone(a,b,c,d,e) fmt_ldapresult(a,b,c,d,e)
|
||||
|
||||
94
ldapclient.c
94
ldapclient.c
@@ -7,11 +7,32 @@
|
||||
|
||||
#define BUFSIZE 8192
|
||||
|
||||
static long messageid=1;
|
||||
|
||||
int ldapbind(int sock) {
|
||||
char outbuf[1024];
|
||||
int s=100;
|
||||
int len=fmt_ldapbindrequest(outbuf+s,3,"","");
|
||||
int hlen=fmt_ldapmessage(0,messageid,BindRequest,len);
|
||||
int res;
|
||||
long op,Len,result;
|
||||
struct string matcheddn,errormessage,referral;
|
||||
fmt_ldapmessage(outbuf+s-hlen,messageid,BindRequest,len);
|
||||
if (write(sock,outbuf+s-hlen,len+hlen)!=len+hlen) return 0;;
|
||||
len=read(sock,outbuf,1024);
|
||||
res=scan_ldapmessage(outbuf,outbuf+len,&messageid,&op,&Len);
|
||||
if (!res) return 0;
|
||||
if (op!=BindResponse) return 0;
|
||||
res=scan_ldapbindresponse(outbuf+res,outbuf+res+len,&result,&matcheddn,&errormessage,&referral);
|
||||
if (!res) return 0;
|
||||
if (result) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int sock;
|
||||
char buf[BUFSIZE];
|
||||
int len=0;
|
||||
long messageid=1;
|
||||
|
||||
sock=socket_tcp4();
|
||||
{
|
||||
@@ -22,53 +43,30 @@ int main() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
char outbuf[1024];
|
||||
int s=100;
|
||||
int len=fmt_ldapbindrequest(outbuf+s,3,"","");
|
||||
int hlen=fmt_ldapmessage(0,messageid,BindRequest,len);
|
||||
fmt_ldapmessage(outbuf+s-hlen,messageid,BindRequest,len);
|
||||
write(sock,outbuf+s-hlen,len+hlen);
|
||||
}
|
||||
for (;;) {
|
||||
int tmp=read(sock,buf+len,BUFSIZE-len);
|
||||
int res;
|
||||
long messageid,op,Len;
|
||||
if (tmp==0) { write(2,"eof!\n",5); return 0; }
|
||||
if (tmp<1) { write(2,"error!\n",7); return 1; }
|
||||
len+=tmp;
|
||||
res=scan_ldapmessage(buf,buf+len,&messageid,&op,&Len);
|
||||
if (res>0) {
|
||||
buffer_puts(buffer_2,"got message of length ");
|
||||
buffer_putulong(buffer_2,Len);
|
||||
buffer_puts(buffer_2," with id ");
|
||||
buffer_putulong(buffer_2,messageid);
|
||||
buffer_puts(buffer_2,": op ");
|
||||
buffer_putulong(buffer_2,op);
|
||||
buffer_putsflush(buffer_2,".\n");
|
||||
switch (op) {
|
||||
case BindResponse:
|
||||
{
|
||||
long result;
|
||||
struct string matcheddn,errormessage,referral;
|
||||
res=scan_ldapbindresponse(buf+res,buf+res+len,&result,&matcheddn,&errormessage,&referral);
|
||||
if (res>=0) {
|
||||
buffer_puts(buffer_2,"bind response: result ");
|
||||
buffer_putulong(buffer_2,result);
|
||||
buffer_puts(buffer_2,", matched dn \"");
|
||||
buffer_put(buffer_2,matcheddn.s,matcheddn.l);
|
||||
buffer_puts(buffer_2,"\", error message \"");
|
||||
buffer_put(buffer_2,errormessage.s,errormessage.l);
|
||||
buffer_puts(buffer_2,"\", referral \"");
|
||||
buffer_put(buffer_2,referral.s,referral.l);
|
||||
buffer_putsflush(buffer_2,"\".\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Len<len) {
|
||||
byte_copyr(buf,len-Len,buf+len);
|
||||
len-=Len;
|
||||
}
|
||||
if (ldapbind(sock)) {
|
||||
struct Filter f;
|
||||
struct AttributeDescriptionList adl;
|
||||
struct SearchRequest sr;
|
||||
f.x=f.next=0;
|
||||
f.type=EQUAL;
|
||||
f.ava.desc.s="sn"; f.ava.desc.l=2;
|
||||
f.ava.value.s="boeke"; f.ava.value.l=5;
|
||||
f.a=&adl;
|
||||
adl.a.s="mail"; adl.a.l=4;
|
||||
adl.next=0;
|
||||
sr.baseObject.s="o=Bundestag, c=de"; sr.baseObject.l=strlen(sr.baseObject.s);
|
||||
sr.scope=wholeSubtree; sr.derefAliases=neverDerefAliases;
|
||||
sr.sizeLimit=sr.timeLimit=sr.typesOnly=0;
|
||||
sr.filter=&f;
|
||||
sr.attributes=&adl;
|
||||
len=fmt_ldapsearchrequest(buf+100,&sr);
|
||||
{
|
||||
int tmp=fmt_ldapmessage(buf,++messageid,SearchRequest,len);
|
||||
fmt_ldapmessage(buf+100-tmp,messageid,SearchRequest,len);
|
||||
write(sock,buf+100-tmp,len+tmp);
|
||||
}
|
||||
} else {
|
||||
buffer_putsflush(buffer_2,"ldapbind failed\n");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ int scan_ldapbindresponse(const char* src,const char* max,
|
||||
errormessage->s=0; errormessage->l=0;
|
||||
}
|
||||
if (src+res<max) {
|
||||
if (!(tmp=scan_ldapstring(src+res,max,referral))) return 0;
|
||||
if (!(tmp=scan_ldapstring(src+res,max,referral))) return res;
|
||||
res+=tmp;
|
||||
} else {
|
||||
referral->s=0; referral->l=0;
|
||||
|
||||
@@ -98,7 +98,9 @@ int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) {
|
||||
break;
|
||||
}
|
||||
case 7: /* present [7] AttributeDescription, */
|
||||
goto error;
|
||||
if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) goto error;
|
||||
res+=tmp;
|
||||
break;
|
||||
case 9: /* extensibleMatch [9] MatchingRuleAssertion } */
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,8 @@ int scan_ldapsearchrequest(const char* src,const char* max,
|
||||
if (!(tmp=scan_ldapsearchfilter(src+res,max,&s->filter))) goto error;
|
||||
res+=tmp;
|
||||
/* now for the attributelist */
|
||||
#if 1
|
||||
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&etmp))) goto error;
|
||||
res+=tmp;
|
||||
#endif
|
||||
{
|
||||
const char* nmax=src+res+etmp;
|
||||
//#define nmax max
|
||||
@@ -39,7 +37,6 @@ int scan_ldapsearchrequest(const char* src,const char* max,
|
||||
res+=tmp;
|
||||
a=&(*a)->next;
|
||||
}
|
||||
/* TODO: parse attributedescriptionlist */
|
||||
return res;
|
||||
}
|
||||
error:
|
||||
|
||||
Reference in New Issue
Block a user