diff --git a/Makefile b/Makefile index 26b563b..bf76e50 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ DEBUG=1 -all: t t1 t2 bindrequest tinyldap ldapclient +all: t t1 t2 bindrequest tinyldap ldapclient ldapclient_str asn1.a: fmt_asn1intpayload.o fmt_asn1length.o fmt_asn1tag.o \ fmt_asn1int.o fmt_asn1string.o fmt_asn1transparent.o scan_asn1tag.o \ @@ -37,13 +37,13 @@ endif t1: ldif.a t2: ldap.a asn1.a -bindrequest tinyldap ldapclient: ldap.a asn1.a +bindrequest tinyldap ldapclient ldapclient_str: ldap.a asn1.a tinyldap: ldif.a .PHONY: clean tar clean: - rm -f t t1 t2 *.[ao] bindrequest tinyldap + rm -f t t1 t2 *.[ao] bindrequest tinyldap ldapclient tar: clean cd ..; tar cvvf ldap.tar.bz2 ldap --use=bzip2 --exclude CVS --exclude exp.ldif --exclude polyp* --exclude rfc* @@ -79,6 +79,7 @@ ldif_parse.o: ldif_parse.c strduptab.h strstorage.h ldif.h tinyldap.o: tinyldap.c ldap.h ldif.h ldapclient.o: ldapclient.c ldap.h +ldapclient_str.o: ldapclient_str.c ldap.h bindrequest.o: bindrequest.c ldap.h strduptab.o: strduptab.c strduptab.h strstorage.h diff --git a/THANKS b/THANKS index 4075626..6978c77 100644 --- a/THANKS +++ b/THANKS @@ -1,3 +1,5 @@ Trevor Harrison found a bug in fmt_asn1tag for the multibyte encoding. David Lichteblau found lots of problems in the ASN.1 code. + +Özgür Kesim helped fix the substring search. diff --git a/fmt_ldapadl.c b/fmt_ldapadl.c index bffd4b0..409cbc9 100644 --- a/fmt_ldapadl.c +++ b/fmt_ldapadl.c @@ -9,7 +9,7 @@ int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) { sum+=fmt_asn1OCTETSTRING(0,0,x->a.l); x=x->next; } - tmp=fmt_asn1SET(dest,sum); + tmp=fmt_asn1SEQUENCE(dest,sum); sum+=tmp; if (dest) { dest+=tmp; diff --git a/fmt_ldapsearchfilter.c b/fmt_ldapsearchfilter.c index ac34712..6ba32d1 100644 --- a/fmt_ldapsearchfilter.c +++ b/fmt_ldapsearchfilter.c @@ -18,7 +18,7 @@ */ int fmt_ldapsubstring(char* dest,struct Substring* s) { - long sum=0,tmp; + long sum=0,tmp=0; while (s) { tmp=fmt_asn1string(dest,PRIVATE,CONSTRUCTED,s->substrtype,s->s.s,s->s.l); if (dest) dest+=tmp; sum+=tmp; @@ -37,8 +37,13 @@ int fmt_ldapsearchfilter(char* dest,struct Filter* f) { case SUBSTRING: { char* nd=dest; - sum=fmt_ldapstring(nd,&f->ava.desc); - sum+=fmt_ldapsubstring(nd+sum,f->substrings); + long l=0,tmp=0; + + tmp=fmt_ldapsubstring(0,f->substrings); + l=fmt_ldapstring(nd,&f->ava.desc); + l+=fmt_asn1SEQUENCE(nd+l,tmp); + l+=fmt_ldapsubstring(nd+l,f->substrings); + sum+=l; } break; case PRESENT: diff --git a/ldapclient.c b/ldapclient.c index 7f9880e..67c27f3 100644 --- a/ldapclient.c +++ b/ldapclient.c @@ -59,7 +59,7 @@ usage: f.type=EQUAL; f.ava.desc.s=argv[3]; f.ava.desc.l=str_chr(argv[3],'='); if (argv[3][f.ava.desc.l] != '=') goto usage; - f.ava.value.s=argv[3]+f.ava.desc.l+1; f.ava.value.l=5; + f.ava.value.s=argv[3]+f.ava.desc.l+1; f.ava.value.l=str_len(f.ava.value.s); f.a=&adl; adl.a.s="mail"; adl.a.l=4; adl.next=0; diff --git a/ldapclient_str.c b/ldapclient_str.c new file mode 100644 index 0000000..6c83717 --- /dev/null +++ b/ldapclient_str.c @@ -0,0 +1,145 @@ +#include +#include +#include "byte.h" +#include "buffer.h" +#include "asn1.h" +#include "ldap.h" +#include "socket.h" +#include "ip4.h" +#include "str.h" +#include "open.h" + +#define BUFSIZE 8192 + +static long messageid=1; + +static 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 argc,char* argv[]) { + int sock; + char buf[BUFSIZE]; + int len=0; + + if (argc<4) { +usage: + buffer_putsflush(buffer_2,"usage: ldapclient_src ip baseObject Attrib Prefix\n"); + return 0; + } + sock=socket_tcp4(); + { + char ip[4]; + if (argv[1][scan_ip4(argv[1],ip)]) goto usage; + if (socket_connect4(sock,ip,389) && !argv[5]) { + buffer_putsflush(buffer_2,"could not connect to ldap server!\n"); + return 1; + } + } + if (argv[5] || ldapbind(sock)) { + struct Filter f; + struct AttributeDescriptionList adl; + struct SearchRequest sr; + struct Substring ssr; + f.x=f.next=0; + f.type=SUBSTRING; + f.ava.desc.s=argv[3]; f.ava.desc.l=str_len(argv[3]); + // if (argv[3][f.ava.desc.l] != '=') goto usage; + //f.ava.value.s=argv[3]+f.ava.desc.l+1; f.ava.value.l=str_len(f.ava.value.s); + f.ava.value.s=""; + f.ava.value.l=0; + ssr.substrtype=prefix; + ssr.s.s=argv[4]; + ssr.s.l=str_len(ssr.s.s); + ssr.next=0; + f.a=&adl; + //f.a=0; + f.substrings=&ssr; + adl.a.s="mail"; adl.a.l=4; + adl.next=0; + sr.baseObject.s=argv[2]; 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(0,++messageid,SearchRequest,len); + fmt_ldapmessage(buf+100-tmp,messageid,SearchRequest,len); + if (argv[5]) { int w; + puts("writing file"); + w=open_trunc(argv[5]); + write(w,buf+100-tmp,len+tmp); + close(w); + return 0; + } + write(sock,buf+100-tmp,len+tmp); + } + { + char buf[8192]; /* arbitrary limit, bad! */ + int len=0,tmp,tmp2; + char* max; + struct SearchResultEntry sre; + for (;;) { + long slen,mid,op; + tmp=read(sock,buf+len,sizeof(buf)-len); + if (tmp<=0) { + buffer_putsflush(buffer_2,"read error.\n"); + return 0; + } + len+=tmp; + if ((tmp2=scan_ldapmessage(buf,buf+len,&mid,&op,&slen))) { + max=buf+slen+tmp2; + if (op==SearchResultEntry) break; + if (op==SearchResultDone) { + buffer_putsflush(buffer_2,"no matches.\n"); + return 0; + } else { + buffer_putsflush(buffer_2,"unexpected response.\n"); + return 0; + } + } + } + if ((tmp=scan_ldapsearchresultentry(buf+tmp2,max,&sre))) { + struct PartialAttributeList* pal=sre.attributes; + buffer_puts(buffer_1,"objectName \""); + buffer_put(buffer_1,sre.objectName.s,sre.objectName.l); + buffer_puts(buffer_1,"\"\n"); + while (pal) { + struct AttributeDescriptionList* adl=pal->values; + buffer_puts(buffer_1," "); + buffer_put(buffer_1,pal->type.s,pal->type.l); + buffer_puts(buffer_1,":"); + while (adl) { + buffer_put(buffer_1,adl->a.s,adl->a.l); + if (adl->next) buffer_puts(buffer_1,", "); + adl=adl->next; + } + buffer_putsflush(buffer_1,"\n"); + pal=pal->next; + } + } else + buffer_putsflush(buffer_1,"punt!\n"); + } + } else { + buffer_putsflush(buffer_2,"ldapbind failed\n"); + return 2; + } + return 0; +} diff --git a/scan_ldapsearchrequest.c b/scan_ldapsearchrequest.c index bc0c014..312fcb2 100644 --- a/scan_ldapsearchrequest.c +++ b/scan_ldapsearchrequest.c @@ -20,7 +20,7 @@ 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 (!(tmp=scan_asn1SET(src+res,max,&etmp))) goto error; + if (!(tmp=scan_asn1SEQUENCE(src+res,max,&etmp))) goto error; res+=tmp; { const char* nmax=src+res+etmp; diff --git a/t.c b/t.c index 27e8c9c..760223a 100644 --- a/t.c +++ b/t.c @@ -538,7 +538,7 @@ int main() { char* max; int l,fd,res; // fd=open_read("/tmp/ldap/127.000.000.001.32875-127.000.000.001.00389"); - fd=open_read("/tmp/ldap/127.000.000.001.32779-127.000.000.001.00389"); + fd=open_read(argv[1] ? argv[1] : "data"); // fd=open_read("/tmp/ldap/127.000.000.001.38433-127.000.000.001.00389"); // fd=open_read("/tmp/ldap/127.000.000.001.00389-127.000.000.001.32779"); // fd=open_read("answer");