diff --git a/Makefile b/Makefile index 3721671..9c785a1 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ t1 parse: ldif.a storage.a t2: ldap.a asn1.a t3 t4 t5 addindex: storage.a t6: storage.a -tinyldap tinyldap_standalone tinyldap_debug: ldif.a auth.a +tinyldap tinyldap_standalone tinyldap_debug: ldif.a storage.a auth.a bindrequest tinyldap tinyldap_standalone tinyldap_debug ldapclient ldapclient_str: ldap.a asn1.a idx2ldif: ldap.a dumpacls: ldap.a asn1.a diff --git a/TODO b/TODO index d37cb22..08cc626 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,20 @@ + 1. let tinyldap check for and incorporate updates from the journal in + the hash table + + 2. support modify and delete requests (should be easy) + + 9. test whether the acls for add actually work + + 10. think about how to incorporate the journal into the database while + still allowing new writes. Second journal? Switch to one-process + model? + + 11. think about compressed database (maybe add first n chars of each + string to index to avoid decompressing too much) + +[old and obsolete] + - add auth method (openldap md5: base64, 4 bytes salt, direct hash) - add write support with an external journal We can also implement clustering through this journal. diff --git a/addindex.c b/addindex.c index 53aa370..37b5367 100644 --- a/addindex.c +++ b/addindex.c @@ -58,7 +58,7 @@ uint32 hashmapped(uint32 ofs,int ignorecase) { unsigned char* c=(unsigned char*)map+ofs; uint32 len; if (*c) return ignorecase?hash_tolower(c,strlen((char*)c)):hash(c,strlen((char*)c)); - uint32_unpack(c+1,&len); + uint32_unpack((char*)c+1,&len); return ignorecase?hash_tolower(c+5,len):hash(c+5,len); } diff --git a/asn1.h b/asn1.h index 6e4e413..ea38fcf 100644 --- a/asn1.h +++ b/asn1.h @@ -1,6 +1,8 @@ /* parser and formatter for ASN.1 DER encoding. * The parser can read BER encoding, too. */ +#include + enum asn1_tagclass { UNIVERSAL=(0<<6), APPLICATION=(1<<6), @@ -24,29 +26,32 @@ enum asn1_tag { /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 tag */ -unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long tag); +size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt, + unsigned long tag); /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 length */ -unsigned int fmt_asn1length(char* dest,unsigned long l); +size_t fmt_asn1length(char* dest,size_t l); /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 INTEGER. This only does the payload, not the tag * and length headers! */ -unsigned int fmt_asn1intpayload(char* dest,unsigned long l); +size_t fmt_asn1intpayload(char* dest,unsigned long val); /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 INTEGER. This only does the payload, not the tag * and length headers! */ -unsigned int fmt_asn1sintpayload(char* dest,signed long l); +size_t fmt_asn1sintpayload(char* dest,signed long val); /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 INTEGER or ENUMERATED. */ -unsigned int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l); +size_t fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt, + enum asn1_tag tag,unsigned long val); /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 INTEGER or ENUMERATED. */ -unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l); +size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt, + enum asn1_tag tag,signed long val); /* write any data type that does not require transformation in the least * amount of bytes, return number of bytes */ @@ -54,11 +59,13 @@ unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt, /* does not wrote the payload itself, just the header! First construct * the sequence/octet string so you know the length, then use * fmt_asn1transparent to write the header before it */ -unsigned int fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l); +size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc, + enum asn1_tagtype tt,enum asn1_tag tag,size_t len); /* write string in least amount of bytes, return number of bytes */ /* as used in ASN.1 OCTET STRING. */ -unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,unsigned long l); +size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt, + enum asn1_tag tag,const char* c,size_t l); /* write ASN.1 OCTET STRING */ #define fmt_asn1OCTETSTRING(dest,c,l) fmt_asn1string(dest,UNIVERSAL,PRIMITIVE,OCTET_STRING,c,l) @@ -85,32 +92,32 @@ unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype t * the return value is the number of bytes parsed or 0 for parse error */ /* parse ASN.1 tag into a tag class, tag type and tag number */ -unsigned int scan_asn1tag(const char* src,const char* max, - enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag); +size_t scan_asn1tag(const char* src,const char* max, + enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag); /* parse ASN.1 length */ -unsigned int scan_asn1length(const char* src,const char* max,unsigned long* length); +size_t scan_asn1length(const char* src,const char* max,size_t* length); /* parse ASN.1 integer with tag and length */ -unsigned int scan_asn1int(const char* src,const char* max, - enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag, - long* l); +size_t scan_asn1int(const char* src,const char* max, + enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag, + long* val); /* parse raw integer (payload after tag and length); internal helper */ -unsigned int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* i); +size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* val); /* parse string with tag and length. * Points s to the first byte in the string, and writes the length of * the string to l. */ -unsigned int scan_asn1string(const char* src,const char* max, +size_t scan_asn1string(const char* src,const char* max, enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag, - const char** s,unsigned long* l); + const char** s,size_t* l); /* the following expect a specific universal type and return a parse * error if the tag does not match that type */ -unsigned int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l); -unsigned int scan_asn1INTEGER(const char* src,const char* max,signed long* l); -unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l); -unsigned int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l); -unsigned int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len); -unsigned int scan_asn1SET(const char* src,const char* max,unsigned long* len); +size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l); +size_t scan_asn1INTEGER(const char* src,const char* max,signed long* l); +size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l); +size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l); +size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len); +size_t scan_asn1SET(const char* src,const char* max,size_t* len); diff --git a/bstr.h b/bstr.h index f3ea5ae..5b18778 100644 --- a/bstr.h +++ b/bstr.h @@ -1,11 +1,12 @@ +#include int bstr_diff(const char* a,const char* b); #define bstr_equal(s,t) (!bstr_diff((s),(t))) -int bstr_diff2(const char* a,const char* b,unsigned int blen); +int bstr_diff2(const char* a,const char* b,size_t blen); #define bstr_equal2(s,t,l) (!bstr_diff2((s),(t),(l))) -int bstrlen(const char* a); -int bstrstart(const char* a); /* offset of first byte of bstring */ +size_t bstrlen(const char* a); +size_t bstrstart(const char* a); /* offset of first byte of bstring */ const char* bstrfirst(const char* a); /* pointer to first byte of bstring */ diff --git a/bstr_diff2.c b/bstr_diff2.c index c31b172..525f8bf 100644 --- a/bstr_diff2.c +++ b/bstr_diff2.c @@ -3,7 +3,7 @@ #include "uint32.h" #include "bstr.h" -int bstr_diff2(const char* a,const char* b,unsigned int blen) { +int bstr_diff2(const char* a,const char* b,size_t blen) { const char* A,* B; int j; /* like str_diff, just for bstrs */ @@ -23,7 +23,7 @@ int bstr_diff2(const char* a,const char* b,unsigned int blen) { } else if (b==B) return 1; - if ((j=(*a-*b))) break; + if ((j=((unsigned char)*a-(unsigned char)*b))) break; ++a; ++b; } return j; diff --git a/bstrlen.c b/bstrlen.c index e4c4c93..61825d5 100644 --- a/bstrlen.c +++ b/bstrlen.c @@ -3,6 +3,6 @@ #include "uint32.h" #include "str.h" -int bstrlen(const char* a) { +size_t bstrlen(const char* a) { if (*a) return str_len(a); else return uint32_read(a+1); } diff --git a/bstrstart.c b/bstrstart.c index b9b4164..5094d34 100644 --- a/bstrstart.c +++ b/bstrstart.c @@ -1,6 +1,6 @@ #include "bstr.h" #include "uint32.h" -int bstrstart(const char* a) { +size_t bstrstart(const char* a) { if (*a) return 0; else return 5; } diff --git a/fmt_asn1int.c b/fmt_asn1int.c index 718af7f..5b3adda 100644 --- a/fmt_asn1int.c +++ b/fmt_asn1int.c @@ -1,7 +1,7 @@ #include -unsigned int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) { - unsigned int len,tmp; +size_t fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) { + size_t len,tmp; /* first the tag */ if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l); len=fmt_asn1tag(dest,tc,tt,tag); diff --git a/fmt_asn1intpayload.c b/fmt_asn1intpayload.c index 2f4b8e8..66ff772 100644 --- a/fmt_asn1intpayload.c +++ b/fmt_asn1intpayload.c @@ -1,16 +1,14 @@ #include -unsigned int fmt_asn1intpayload(char* dest,unsigned long l) { - unsigned int needed=sizeof l; - unsigned int i; - unsigned int fixup; +size_t fmt_asn1intpayload(char* dest,unsigned long l) { + size_t needed=sizeof l,i,fixup; for (i=1; i>(i*8))) break; } fixup=(l>>((i-1)*8))&0x80 ? 1 : 0; if (dest) { - unsigned int j=i; + size_t j=i; if (fixup) *dest++=0; while (j) { --j; diff --git a/fmt_asn1length.c b/fmt_asn1length.c index 7c1a0d4..3df929b 100644 --- a/fmt_asn1length.c +++ b/fmt_asn1length.c @@ -2,10 +2,9 @@ /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 length */ -unsigned int fmt_asn1length(char* dest,unsigned long l) { +size_t fmt_asn1length(char* dest,size_t l) { /* encoding is either l%128 or (0x80+number of bytes,bytes) */ - int needed=(sizeof l); - int i; + size_t needed=(sizeof l),i; if (l<128) { if (dest) *dest=l&0x7f; return 1; diff --git a/fmt_asn1sint.c b/fmt_asn1sint.c index af8a022..dfa0b23 100644 --- a/fmt_asn1sint.c +++ b/fmt_asn1sint.c @@ -1,7 +1,7 @@ #include -unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) { - unsigned int len,tmp; +size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) { + size_t len,tmp; /* first the tag */ if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l); len=fmt_asn1tag(dest,tc,tt,tag); diff --git a/fmt_asn1sintpayload.c b/fmt_asn1sintpayload.c index 4443b77..0992df5 100644 --- a/fmt_asn1sintpayload.c +++ b/fmt_asn1sintpayload.c @@ -1,8 +1,7 @@ #include -unsigned int fmt_asn1sintpayload(char* dest,signed long l) { - unsigned int needed=sizeof l; - unsigned int i; +size_t fmt_asn1sintpayload(char* dest,signed long l) { + size_t needed=sizeof l,i; signed long tmp=0x7f; if (l>=0) return fmt_asn1intpayload(dest,l); for (i=1; i>(j*8))&0xff; diff --git a/fmt_asn1string.c b/fmt_asn1string.c index 7f459b2..e0ef6ac 100644 --- a/fmt_asn1string.c +++ b/fmt_asn1string.c @@ -1,8 +1,9 @@ #include "asn1.h" #include "byte.h" -unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,unsigned long l) { - int len; +size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,size_t l) { + size_t len; + if (l>(size_t)-100) return (size_t)-1; len=fmt_asn1transparent(dest,tc,tt,tag,l); if (dest) byte_copy(dest+len,l,c); return len+l; diff --git a/fmt_asn1tag.c b/fmt_asn1tag.c index b1f1484..8189cae 100644 --- a/fmt_asn1tag.c +++ b/fmt_asn1tag.c @@ -2,10 +2,9 @@ /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 tags */ -unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) { +size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) { /* encoding is either l%128 or (0x1f,...) */ - int needed=(sizeof l)*7/8; - int i; + size_t needed=(sizeof l)*7/8,i; if (l<0x1f) { if (dest) *dest=(int)tc+(int)tt+(l&0x1f); return 1; @@ -14,7 +13,7 @@ unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,u if (!(l>>(i*7))) break; if (dest) { - int j=i; + size_t j=i; *dest=(int)tc+(int)tt+0x1f; ++dest; while (j) { --j; diff --git a/fmt_asn1transparent.c b/fmt_asn1transparent.c index 4a162d2..d1f9895 100644 --- a/fmt_asn1transparent.c +++ b/fmt_asn1transparent.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "byte.h" -unsigned int fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) { - unsigned int len,tmp; +size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,size_t l) { + size_t len,tmp; /* first the tag */ len=fmt_asn1tag(dest,tc,tt,tag); tmp=fmt_asn1length(dest?dest+len:dest,l); diff --git a/fmt_ldapadl.c b/fmt_ldapadl.c index cc3544d..cc51999 100644 --- a/fmt_ldapadl.c +++ b/fmt_ldapadl.c @@ -1,10 +1,9 @@ #include "asn1.h" #include "ldap.h" -static int doit(char* dest,struct AttributeDescriptionList* adl,int seq) { +static size_t doit(char* dest,struct AttributeDescriptionList* adl,int seq) { struct AttributeDescriptionList* x=adl; - long sum=0; - int tmp; + size_t sum=0,tmp; while (x) { sum+=fmt_asn1OCTETSTRING(0,0,x->a.l); x=x->next; @@ -25,10 +24,10 @@ static int doit(char* dest,struct AttributeDescriptionList* adl,int seq) { return sum; } -unsigned int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) { +size_t fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) { return doit(dest,adl,1); } -unsigned int fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl) { +size_t fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl) { return doit(dest,adl,0); } diff --git a/fmt_ldapava.c b/fmt_ldapava.c index b1990b1..c1f9fc3 100644 --- a/fmt_ldapava.c +++ b/fmt_ldapava.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldapava(char* dest,struct AttributeValueAssertion* a) { - long sum,l; +size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a) { + size_t sum,l; sum=fmt_ldapstring(dest,&a->desc); if (dest) dest+=sum; l=fmt_ldapstring(dest,&a->value); diff --git a/fmt_ldapbindrequest.c b/fmt_ldapbindrequest.c index f6c27f5..76a0bc9 100644 --- a/fmt_ldapbindrequest.c +++ b/fmt_ldapbindrequest.c @@ -2,16 +2,18 @@ #include "asn1.h" #include "ldap.h" #include "str.h" +#include "rangecheck.h" -unsigned int fmt_ldapbindrequest(char* dest,long version,char* name,char* simple) { - unsigned int l,sum; - unsigned int nlen=str_len(name); +size_t fmt_ldapbindrequest(char* dest,long version,char* name,char* simple) { + size_t l,sum; + size_t nlen=str_len(name); sum=l=fmt_asn1INTEGER(dest,version); if (dest) dest+=l; l=fmt_asn1OCTETSTRING(dest,name,nlen); - sum+=l; if (dest) dest+=l; + if (add_of(sum,sum,l)) return (size_t)-1; if (dest) dest+=l; +// sum+=l; if (dest) dest+=l; nlen=str_len(simple); l=fmt_asn1string(dest,PRIVATE,PRIMITIVE,0,simple,nlen); - if (dest) dest+=l; - return sum+l; + if (add_of(sum,sum,l)) return (size_t)-1; if (dest) dest+=l; + return sum; } diff --git a/fmt_ldapmessage.c b/fmt_ldapmessage.c index 9eb5531..b9b9f59 100644 --- a/fmt_ldapmessage.c +++ b/fmt_ldapmessage.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldapmessage(char* dest,long messageid,long op,long len) { - unsigned int l,l2,l3; +size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len) { + size_t l,l2,l3; l2=fmt_asn1INTEGER(0,messageid); l3=fmt_asn1transparent(0,APPLICATION,CONSTRUCTED,op,len); l=fmt_asn1SEQUENCE(dest,len+l2+l3); diff --git a/fmt_ldappal.c b/fmt_ldappal.c index ef4d4c5..d4322ff 100644 --- a/fmt_ldappal.c +++ b/fmt_ldappal.c @@ -1,9 +1,9 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldappal(char* dest,struct PartialAttributeList* pal) { +size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal) { // int l,l2,sum; - long sum,l,l2; + size_t sum,l,l2; if (!pal) return 0; sum=fmt_ldapstring(0,&pal->type); /* look how much space the adl needs */ diff --git a/fmt_ldapresult.c b/fmt_ldapresult.c index 4fb07e8..0ef6df1 100644 --- a/fmt_ldapresult.c +++ b/fmt_ldapresult.c @@ -2,9 +2,8 @@ #include "ldap.h" #include "str.h" -unsigned int fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral) { - unsigned int l,sum=0; - unsigned int nlen; +size_t fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral) { + size_t l,sum=0,nlen; sum=l=fmt_asn1ENUMERATED(dest,result); if (dest) dest+=l; nlen=str_len(matcheddn); diff --git a/fmt_ldapsearchfilter.c b/fmt_ldapsearchfilter.c index b5f7a09..1ad3cea 100644 --- a/fmt_ldapsearchfilter.c +++ b/fmt_ldapsearchfilter.c @@ -17,8 +17,8 @@ extensibleMatch [9] MatchingRuleAssertion } */ -int fmt_ldapsubstring(char* dest,struct Substring* s) { - long sum=0,tmp=0; +size_t fmt_ldapsubstring(char* dest,struct Substring* s) { + size_t sum=0,tmp=0; while (s) { tmp=fmt_asn1string(dest,PRIVATE,PRIMITIVE,s->substrtype,s->s.s,s->s.l); if (dest) dest+=tmp; sum+=tmp; @@ -27,9 +27,8 @@ int fmt_ldapsubstring(char* dest,struct Substring* s) { return sum; } -unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f) { - long sum=0,tmp; - long savesum; +size_t fmt_ldapsearchfilter(char* dest,struct Filter* f) { + size_t sum=0,tmp,savesum; if (!f) return 0; switch (f->type) { @@ -40,7 +39,7 @@ unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f) { case SUBSTRING: { char* nd=dest; - long l=0,tmp=0; + size_t l,tmp; tmp=fmt_ldapsubstring(0,f->substrings); l=fmt_ldapstring(nd,&f->ava.desc); diff --git a/fmt_ldapsearchfilterstring.c b/fmt_ldapsearchfilterstring.c index c769aed..a4fa1aa 100644 --- a/fmt_ldapsearchfilterstring.c +++ b/fmt_ldapsearchfilterstring.c @@ -3,8 +3,8 @@ #include "str.h" #include "ldap.h" -unsigned int fmt_ldapsearchfilterstring(char* dest,struct Filter* f) { - unsigned int len; +size_t fmt_ldapsearchfilterstring(char* dest,struct Filter* f) { + size_t len; len = fmt_str(dest,"("); switch (f->type) { case AND: case OR: case NOT: diff --git a/fmt_ldapsearchrequest.c b/fmt_ldapsearchrequest.c index 8389138..e73bb3c 100644 --- a/fmt_ldapsearchrequest.c +++ b/fmt_ldapsearchrequest.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) { - int l,sum=0; +size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) { + size_t l,sum=0; sum=fmt_ldapstring(dest,&sr->baseObject); if (dest) dest+=sum; l=fmt_asn1ENUMERATED(dest,sr->scope); diff --git a/fmt_ldapsearchresultentry.c b/fmt_ldapsearchresultentry.c index 8f50e1a..50f5690 100644 --- a/fmt_ldapsearchresultentry.c +++ b/fmt_ldapsearchresultentry.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) { - unsigned int l,sum=0; +size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) { + size_t l,sum=0; sum=fmt_ldapstring(dest,&sre->objectName); if (dest) dest+=sum; l=fmt_asn1SEQUENCE(dest,fmt_ldappal(0,sre->attributes)); diff --git a/fmt_ldapstring.c b/fmt_ldapstring.c index e26f449..3507262 100644 --- a/fmt_ldapstring.c +++ b/fmt_ldapstring.c @@ -1,6 +1,6 @@ #include "asn1.h" #include "ldap.h" -unsigned int fmt_ldapstring(char* dest,struct string* s) { +size_t fmt_ldapstring(char* dest,struct string* s) { return fmt_asn1OCTETSTRING(dest,s->s,s->l); } diff --git a/idx2ldif.c b/idx2ldif.c index b1c63b2..5e25c67 100644 --- a/idx2ldif.c +++ b/idx2ldif.c @@ -6,27 +6,32 @@ #include "uint32.h" #include "bstr.h" #include "textcode.h" +#include static void dumpbstr(const char* c) { - int printable=1; - int i,l; + size_t i,l,up; const char* d; l=bstrlen(c); d=bstrfirst(c); - for (i=0; i=l); + if (up==l) { buffer_puts(buffer_1," "); if (*c) buffer_puts(buffer_1,c); else buffer_put(buffer_1,bstrfirst(c),bstrlen(c)); - } else { + } else if (up > (l+2)/3*4) { char* e; i=fmt_base64(0,d,l); e=alloca(i+1); buffer_puts(buffer_1,": "); buffer_put(buffer_1,e,fmt_base64(e,d,l)); + } else { + char* e; + e=alloca(up); + buffer_puts(buffer_1,": "); + buffer_put(buffer_1,e,fmt_ldapescape(e,d,l)); } } diff --git a/ldap.h b/ldap.h index f3da7aa..eb6cbbd 100644 --- a/ldap.h +++ b/ldap.h @@ -1,10 +1,11 @@ #ifndef _LDAP_H #define _LDAP_H -#include "uint32.h" +#include +#include struct string { - unsigned long l; + size_t l; const char* s; }; @@ -19,7 +20,7 @@ struct AttributeValueAssertion { struct AttributeDescriptionList { struct string a; - uint32 attrofs; + uint32_t attrofs; struct AttributeDescriptionList *next; }; @@ -42,8 +43,8 @@ enum FilterType { struct Filter { enum FilterType type; struct AttributeValueAssertion ava; - uint32 attrofs; /* offset of attribute name in index */ - uint32 attrflag; /* "case sensitivity" flag from index */ + uint32_t attrofs; /* offset of attribute name in index */ + uint32_t attrflag; /* "case sensitivity" flag from index */ struct Substring* substrings; struct AttributeDescriptionList *a; struct Filter* x,*next; @@ -152,40 +153,40 @@ void freefilter(struct Filter* f); void freeava(struct AttributeDescriptionList* a); void freepal(struct PartialAttributeList* a); -unsigned int scan_ldapstring(const char* src,const char* max,struct string* s); -unsigned int scan_ldapmessage(const char* src,const char* max, - unsigned long* messageid,unsigned long* op, - unsigned long* len); -unsigned int scan_ldapbindrequest(const char* src,const char* max, - unsigned long* version,struct string* name, - unsigned long* method); -unsigned int scan_ldapbindresponse(const char* src,const char* max, - unsigned long* result,struct string* matcheddn, - struct string* errormessage,struct string* referral); -unsigned int scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* a); -unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f); -unsigned int scan_ldapsearchrequest(const char* src,const char* max,struct SearchRequest* s); -unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre); -unsigned int scan_ldapresult(const char* src,const char* max,unsigned long* result, - struct string* matcheddn,struct string* errormessage, - struct string* referral); -unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m); -unsigned int scan_ldapaddrequest(const char * src, const char * max, struct AddRequest * a); -unsigned int scan_ldapsearchfilterstring(const char* src,struct Filter** f); +size_t scan_ldapstring(const char* src,const char* max,struct string* s); +size_t scan_ldapmessage(const char* src,const char* max, + unsigned long* messageid,unsigned long* op, + size_t* len); +size_t scan_ldapbindrequest(const char* src,const char* max, + unsigned long* version,struct string* name, + unsigned long* method); +size_t scan_ldapbindresponse(const char* src,const char* max, + unsigned long* result,struct string* matcheddn, + struct string* errormessage,struct string* referral); +size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* a); +size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f); +size_t scan_ldapsearchrequest(const char* src,const char* max,struct SearchRequest* s); +size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre); +size_t scan_ldapresult(const char* src,const char* max,unsigned long* result, + struct string* matcheddn,struct string* errormessage, + struct string* referral); +size_t scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m); +size_t scan_ldapaddrequest(const char* src, const char * max, struct AddRequest * a); +size_t scan_ldapsearchfilterstring(const char* src,struct Filter** f); -unsigned int fmt_ldapstring(char* dest,struct string* s); -unsigned int fmt_ldapmessage(char* dest,long messageid,long op,long len); -unsigned int fmt_ldapbindrequest(char* dest,long version,char* name,char* simple); -unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f); -unsigned int fmt_ldapsearchrequest(char* dest,struct SearchRequest* s); -unsigned int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre); -unsigned int fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral); -unsigned int fmt_ldappal(char* dest,struct PartialAttributeList* pal); -unsigned int fmt_ldapava(char* dest,struct AttributeValueAssertion* a); -unsigned int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl); -unsigned int fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl); -unsigned int fmt_ldapmodifyrequest(char* dest,struct ModifyRequest* m); -unsigned int fmt_ldapsearchfilterstring(char* dest,struct Filter* f); +size_t fmt_ldapstring(char* dest,struct string* s); +size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len); +size_t fmt_ldapbindrequest(char* dest,long version,char* name,char* simple); +size_t fmt_ldapsearchfilter(char* dest,struct Filter* f); +size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* s); +size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre); +size_t fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral); +size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal); +size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a); +size_t fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl); +size_t fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl); +size_t fmt_ldapmodifyrequest(char* dest,struct ModifyRequest* m); +size_t fmt_ldapsearchfilterstring(char* dest,struct Filter* f); #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) @@ -204,5 +205,7 @@ void free_ldapsearchresultentry(struct SearchResultEntry* e); int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f); +int matchint(struct Filter* f,const char* t); +int substringmatch(struct Substring* x,const char* attr,int ignorecase); #endif diff --git a/ldap_match_mapped.c b/ldap_match_mapped.c index d9b76dc..dc80397 100644 --- a/ldap_match_mapped.c +++ b/ldap_match_mapped.c @@ -14,7 +14,7 @@ extern long filelen; extern uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table; extern uint32 dn_ofs,objectClass_ofs; -static int substringmatch(struct Substring* x,const char* attr,int ignorecase) { +int substringmatch(struct Substring* x,const char* attr,int ignorecase) { int (*diff)(const void* a, unsigned long len, const void* b); if (ignorecase) diff=case_diffb; @@ -66,7 +66,7 @@ uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs) { return 0; } -static inline int matchint(struct Filter* f,const char* t) { +int matchint(struct Filter* f,const char* t) { int r; if (f->attrflag&1) diff --git a/ldap_match_sre.c b/ldap_match_sre.c index c7b5750..b0e69c1 100644 --- a/ldap_match_sre.c +++ b/ldap_match_sre.c @@ -72,7 +72,7 @@ found: return 1; } -extern uint32 dn_ofs; +extern uint32_t dn_ofs; int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f) { struct PartialAttributeList* p; diff --git a/ldapclient.c b/ldapclient.c index 8d72761..e80e8f3 100644 --- a/ldapclient.c +++ b/ldapclient.c @@ -9,12 +9,20 @@ #include "socket.h" #include "ip4.h" #include "str.h" +#include "textcode.h" #include #include #define BUFSIZE 8192 +static void buffer_putescaped(buffer* b,const char* x,size_t l) { + size_t needed=fmt_ldapescape(0,x,l); + char* buf=alloca(needed); + fmt_ldapescape(buf,x,l); + buffer_put(b,buf,needed); +} + static unsigned long messageid=1; static int ldapbind(int sock) { @@ -118,7 +126,7 @@ usage: } shutdown(sock,SHUT_WR); { - char buf[8192]; /* arbitrary limit, bad! */ + char buf[32*1024]; /* arbitrary limit, bad! */ int len=0,tmp,tmp2; char* max; struct SearchResultEntry sre; @@ -158,16 +166,16 @@ nextmessage: if (durchlauf==0) { buffer_puts(buffer_1,"dn: "); - buffer_put(buffer_1,sre.objectName.s,sre.objectName.l); + buffer_putescaped(buffer_1,sre.objectName.s,sre.objectName.l); buffer_puts(buffer_1,"\n"); while (pal) { struct AttributeDescriptionList* adl=pal->values; do { - buffer_puts(buffer_1," "); - buffer_put(buffer_1,pal->type.s,pal->type.l); +// buffer_puts(buffer_1," "); + buffer_putescaped(buffer_1,pal->type.s,pal->type.l); buffer_puts(buffer_1,": "); if (adl) { - buffer_put(buffer_1,adl->a.s,adl->a.l); + buffer_putescaped(buffer_1,adl->a.s,adl->a.l); buffer_puts(buffer_1,"\n"); adl=adl->next; if (!adl) break; diff --git a/ldif.h b/ldif.h index 10799f6..21d7417 100644 --- a/ldif.h +++ b/ldif.h @@ -1,21 +1,21 @@ -#include "uint32.h" +#include #include /* how many attributes do we allow per record? */ #define ATTRIBS 100 struct attribute { - uint32 name, value; + uint32_t name, value; }; struct ldaprec { - uint32 dn; - int n; /* number of attributes */ + uint32_t dn; + unsigned int n; /* number of attributes */ struct attribute a[ATTRIBS]; struct ldaprec* next; }; -extern uint32 dn, mail, sn, cn, objectClass; +extern uint32_t dn, mail, sn, cn, objectClass; extern struct ldaprec *first; extern unsigned long ldifrecords; @@ -23,7 +23,7 @@ int ldif_parse(const char* filename); /* return non-zero if the record matches the search request */ int ldap_match(struct ldaprec* r,struct SearchRequest* sr); -int ldap_match_mapped(uint32 ofs,struct SearchRequest* sr); -int ldap_match_present(uint32 ofs,uint32 attrofs); -uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs); -int ldap_matchfilter_mapped(uint32 ofs,struct Filter* f); +int ldap_match_mapped(uint32_t ofs,struct SearchRequest* sr); +int ldap_match_present(uint32_t ofs,uint32_t attrofs); +uint32_t ldap_find_attr_value(uint32_t ofs,uint32_t attrofs); +int ldap_matchfilter_mapped(uint32_t ofs,struct Filter* f); diff --git a/ldif_parse.c b/ldif_parse.c index 3348a2e..005931e 100644 --- a/ldif_parse.c +++ b/ldif_parse.c @@ -12,10 +12,11 @@ #include "byte.h" #include "textcode.h" #include "stralloc.h" +#include "uint32.h" mduptab_t attributes,classes; mstorage_t stringtable; -uint32 dn, objectClass; +uint32_t dn, objectClass; unsigned long lines; /* this is called after each record. @@ -27,11 +28,11 @@ unsigned long lines; * If the callback is NULL, a callback that always returns 1 is assumed. * */ int (*ldif_parse_callback)(struct ldaprec* l); -uint32 (*ldif_addstring_callback)(const char* s,unsigned long len); +uint32_t (*ldif_addstring_callback)(const char* s,unsigned long len); unsigned long ldifrecords; -static void addattribute(struct ldaprec** l,uint32 name,uint32 val) { +static void addattribute(struct ldaprec** l,uint32_t name,uint32_t val) { if (name==dn) (*l)->dn=val; else if ((*l)->na[(*l)->n].name=name; @@ -80,28 +81,28 @@ static int unbase64(char* buf) { return destlen; } -uint32 (*ldif_addstring_callback)(const char* s,unsigned long len); +uint32_t (*ldif_addstring_callback)(const char* s,unsigned long len); -static uint32 addstring(const char* s,unsigned long len) { +static uint32_t addstring(const char* s,unsigned long len) { return mstorage_add(&stringtable,s,len); } static long commit_string_bin(const char* s,unsigned long n) { unsigned int i; static char zero; - uint32 x; + uint32_t x; char intbuf[4]; if (n==0 || (n==1 && s[0]==0)) goto encodebinary; for (i=0; inext=0; (*l)->n=0; ldifrecords=0; do { - uint32 tmp, val; + uint32_t tmp, val; base64=binary=0; n=ofs+buffer_get_token(b,buf+ofs,8192-ofs,":",1); if (n==0) break; @@ -139,7 +140,7 @@ nomem: buf[i2]=0; if (str_equal("binary",buf+i2+1)) binary=1; } - if ((tmp=mduptab_adds(&attributes,buf+i))==(uint32)-1) goto nomem; + if ((tmp=mduptab_adds(&attributes,buf+i))==(uint32_t)-1) goto nomem; if (!stralloc_copys(&payload,"")) goto nomem; { char dummy; @@ -178,8 +179,12 @@ lookagain: if (base64) { len=unbase64(payload.s); if (!binary) { payload.s[len]=0; ++len; } - } else - len=n+1; + } else { + len=n; + scan_ldapescape(payload.s,payload.s,&len); + payload.s[len]=0; + ++len; + } } else len=0; @@ -192,11 +197,11 @@ lookagain: #endif if (tmp==objectClass) { - if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32)-1) goto nomem; + if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32_t)-1) goto nomem; } else if (tmp==dn) { - if ((val=add_normalized(payload.s,len))==(uint32)-1) goto nomem; + if ((val=add_normalized(payload.s,len))==(uint32_t)-1) goto nomem; } else - if ((val=commit_string_bin(payload.s,len))==(uint32)-1) goto nomem; + if ((val=commit_string_bin(payload.s,len))==(uint32_t)-1) goto nomem; addattribute(l,tmp,val); m=0; @@ -236,8 +241,12 @@ lookagain: if (base64) { len=unbase64(payload.s); if (!binary) { payload.s[len]=0; ++len; } - } else - len=n+1; + } else { + len=n; + scan_ldapescape(payload.s,payload.s,&len); + payload.s[len]=0; + ++len; + } } else len=0; @@ -250,16 +259,16 @@ lookagain: #endif if (tmp==objectClass) { - if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32)-1) goto nomem; + if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32_t)-1) goto nomem; } else if (tmp==dn) { - if ((val=add_normalized(payload.s,payload.len))==(uint32)-1) goto nomem; + if ((val=add_normalized(payload.s,payload.len))==(uint32_t)-1) goto nomem; } else - if ((val=commit_string_bin(payload.s,len))==(uint32)-1) goto nomem; + if ((val=commit_string_bin(payload.s,len))==(uint32_t)-1) goto nomem; addattribute(l,tmp,val); #endif } while (!eof); if (ldif_parse_callback && ldif_parse_callback(*l)==-1) return -1; - if ((*l)->dn==(uint32)-1 && ((*l)->next)) { + if ((*l)->dn==(uint32_t)-1 && ((*l)->next)) { struct ldaprec* m=(*l)->next; free((*l)); (*l)=m; diff --git a/mduptab.h b/mduptab.h index f640450..cb6198a 100644 --- a/mduptab.h +++ b/mduptab.h @@ -14,5 +14,5 @@ typedef struct mduptable { void mduptab_init(mduptab_t* t); void mduptab_init_reuse(mduptab_t* t,mstorage_t* s); -long mduptab_add(mduptab_t* t,const char* s,unsigned int len); +long mduptab_add(mduptab_t* t,const char* s,size_t len); long mduptab_adds(mduptab_t* t,const char* s); diff --git a/mduptab_add.c b/mduptab_add.c index b72532f..ddf5b46 100644 --- a/mduptab_add.c +++ b/mduptab_add.c @@ -6,7 +6,7 @@ #include "mduptab.h" #include "uint32.h" -long mduptab_add(mduptab_t* t,const char* s,unsigned int len) { +long mduptab_add(mduptab_t* t,const char* s,size_t len) { unsigned int i; unsigned long* l=(unsigned long*)t->table.root; long x,bak; diff --git a/mstorage.h b/mstorage.h index ce3c481..258e786 100644 --- a/mstorage.h +++ b/mstorage.h @@ -1,11 +1,13 @@ #ifndef _MSTORAGE_H #define _MSTORAGE_H +#include + /* (optionally persistent) mmapped storage. */ typedef struct mstorage { char* root; - unsigned long mapped,used; + size_t mapped,used; int fd; } mstorage_t; @@ -16,7 +18,7 @@ int mstorage_init_persistent(mstorage_t* p,int fd); /* Works like strstorage_add, but will return an * offset to mstorage_root, which is mmapped and may thus change. */ /* offset -1 ==> error */ -long mstorage_add(mstorage_t* p,const char* s,unsigned long n); +long mstorage_add(mstorage_t* p,const char* s,size_t n); /* undo mapping */ void mstorage_unmap(mstorage_t* p); @@ -26,6 +28,6 @@ void mstorage_unmap(mstorage_t* p); * char 0; * uint32 len; * char data[len] */ -long mstorage_add_bin(mstorage_t* p,const char* s,unsigned long n); +long mstorage_add_bin(mstorage_t* p,const char* s,size_t n); #endif diff --git a/parse.c b/parse.c index d120594..f59cef3 100644 --- a/parse.c +++ b/parse.c @@ -85,7 +85,7 @@ uint32 my_addstring(const char* s,unsigned long len) { int ldif_callback(struct ldaprec* l) { char x[8]; /* temp buf for endianness conversion */ - int i; + unsigned int i; // uint32 ofs; uint32 oc=(uint32)-1; /* value of the first objectClass */ @@ -99,7 +99,7 @@ int ldif_callback(struct ldaprec* l) { } if (oc==(uint32)-1) { extern long lines; - buffer_puts(buffer_1,"ignoring record without objectClass... (line"); + buffer_puts(buffer_1,"ignoring record without objectClass... (line "); buffer_putulong(buffer_1,lines); buffer_putsflush(buffer_1,")\n"); return 0; diff --git a/scan_asn1BOOLEAN.c b/scan_asn1BOOLEAN.c index 9b0636e..8a3958f 100644 --- a/scan_asn1BOOLEAN.c +++ b/scan_asn1BOOLEAN.c @@ -1,15 +1,15 @@ #include "asn1.h" -unsigned int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l) { - unsigned int tmp; +size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* val) { + size_t tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; long ltmp; if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,<mp))) if (tc==UNIVERSAL && tt==PRIMITIVE && tag==BOOLEAN) { - if (ltmp<0 || src+tmp+ltmp>max) return 0; - *l=(unsigned long)ltmp; + if (ltmp!=0 && ltmp!=1) return 0; + *val=(unsigned long)ltmp; return tmp; } return 0; diff --git a/scan_asn1ENUMERATED.c b/scan_asn1ENUMERATED.c index 09bd5ff..799d1e7 100644 --- a/scan_asn1ENUMERATED.c +++ b/scan_asn1ENUMERATED.c @@ -1,7 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l) { - unsigned int tmp; +size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* val) { + size_t tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; @@ -9,7 +9,7 @@ unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,<mp))) if (tc==UNIVERSAL && tt==PRIMITIVE && tag==ENUMERATED) { if (ltmp<0 || src+tmp+ltmp>max) return 0; - *l=(unsigned long)ltmp; + *val=(unsigned long)ltmp; return tmp; } return 0; diff --git a/scan_asn1INTEGER.c b/scan_asn1INTEGER.c index 041493b..61d3ac5 100644 --- a/scan_asn1INTEGER.c +++ b/scan_asn1INTEGER.c @@ -1,11 +1,11 @@ #include "asn1.h" -unsigned int scan_asn1INTEGER(const char* src,const char* max,signed long* l) { - unsigned int tmp; +size_t scan_asn1INTEGER(const char* src,const char* max,signed long* val) { + size_t tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; - if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,l))) + if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,val))) if (tc==UNIVERSAL && tt==PRIMITIVE && tag==INTEGER) return tmp; return 0; diff --git a/scan_asn1SEQUENCE.c b/scan_asn1SEQUENCE.c index b14a2ea..41bdb4b 100644 --- a/scan_asn1SEQUENCE.c +++ b/scan_asn1SEQUENCE.c @@ -1,7 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len) { - unsigned int res,tmp; +size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len) { + size_t res,tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; diff --git a/scan_asn1SET.c b/scan_asn1SET.c index 238e494..7cced52 100644 --- a/scan_asn1SET.c +++ b/scan_asn1SET.c @@ -1,7 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1SET(const char* src,const char* max,unsigned long* len) { - unsigned int res,tmp; +size_t scan_asn1SET(const char* src,const char* max,size_t* len) { + size_t res,tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; diff --git a/scan_asn1STRING.c b/scan_asn1STRING.c index ac88844..a6edd14 100644 --- a/scan_asn1STRING.c +++ b/scan_asn1STRING.c @@ -1,7 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l) { - unsigned int tmp; +size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l) { + size_t tmp; unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; diff --git a/scan_asn1int.c b/scan_asn1int.c index 61db7ae..0a01737 100644 --- a/scan_asn1int.c +++ b/scan_asn1int.c @@ -1,8 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) { - unsigned int len,tmp; - unsigned long tlen; +size_t scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) { + size_t len,tmp,tlen; if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0; if (!(tmp=scan_asn1length(src+len,max,&tlen))) return 0; len+=tmp; diff --git a/scan_asn1length.c b/scan_asn1length.c index 7102274..832309e 100644 --- a/scan_asn1length.c +++ b/scan_asn1length.c @@ -1,14 +1,14 @@ #include #include "asn1.h" -unsigned int scan_asn1length(const char* src,const char* max,unsigned long* length) { +size_t scan_asn1length(const char* src,const char* max,size_t* length) { const char* orig=src; if (src>max) return 0; /* If the highest bit of the first byte is clear, the byte is the length. * Otherwise the next n bytes are the length (n being the lower 7 bits) */ if (*src&0x80) { int chars=*src&0x7f; - unsigned long l=0; + size_t l=0; while (chars>0) { if (++src>=max) return 0; if (l>(((unsigned long)-1)>>8)) return 0; /* catch integer overflow */ @@ -20,6 +20,6 @@ unsigned int scan_asn1length(const char* src,const char* max,unsigned long* leng *length=*src&0x7f; src++; if (src+*length>max) return 0; /* catch integer overflow */ - if ((uintptr_t)src+*length<(uintptr_t)src) return 0; /* gcc 4 removes this check without the cast to uintptr_t */ + if ((uintptr_t)src+*length<(uintptr_t)src) return 0; /* gcc 4.1 removes this check without the cast to uintptr_t */ return src-orig; } diff --git a/scan_asn1oid.c b/scan_asn1oid.c index a6938e2..a2a4a1d 100644 --- a/scan_asn1oid.c +++ b/scan_asn1oid.c @@ -1,15 +1,15 @@ #include "asn1.h" -unsigned int scan_asn1oid(const char* src,const char* max) { - unsigned int res,tmp; - unsigned long tag,tlen; +size_t scan_asn1oid(const char* src,const char* max) { + size_t res,tmp,tlen; + unsigned long tag; enum asn1_tagclass tc; enum asn1_tagtype tt; if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error; if (!(tmp=scan_asn1length(src+res,max,&tlen))) goto error; res+=tmp; { - unsigned int i,x,y; + size_t i,x,y; tmp=0; for(i=0;src[res+i]&128;++i) tmp=(tmp<<7)+((unsigned char)src[res+i]&(~128)); diff --git a/scan_asn1rawint.c b/scan_asn1rawint.c index f9c7718..263c25b 100644 --- a/scan_asn1rawint.c +++ b/scan_asn1rawint.c @@ -1,7 +1,7 @@ #include "asn1.h" -unsigned int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* l) { - unsigned int i,j; +size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) { + size_t i,j; long m; if (*src<0) m=-1; else m=0; for (i=j=0; ientry))) goto error; @@ -28,7 +27,7 @@ unsigned int scan_ldapaddrequest(const char* src,const char* max,struct AddReque max=src+res+oslen; if (src+res>=max) goto error; /* need at least one record */ do { - unsigned long islen; + size_t islen; if (last) { struct Addition* cur; if (!(cur=malloc(sizeof(struct Addition)))) @@ -49,7 +48,7 @@ unsigned int scan_ldapaddrequest(const char* src,const char* max,struct AddReque /* scan set of AttributeValue: */ { - unsigned long set_len; + size_t set_len; const char* set_max; struct AttributeDescriptionList* ilast=0; if (!(tmp=scan_asn1SET(src+res,max,&set_len))) { diff --git a/scan_ldapava.c b/scan_ldapava.c index f85dc77..d5724ff 100644 --- a/scan_ldapava.c +++ b/scan_ldapava.c @@ -1,8 +1,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) { - unsigned int res,tmp; +size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) { + size_t res,tmp; if (!(res=scan_ldapstring(src,max,&ava->desc))) goto error; if (!(tmp=scan_ldapstring(src+res,max,&ava->value))) goto error; return res+tmp; diff --git a/scan_ldapbindrequest.c b/scan_ldapbindrequest.c index 900d553..0bd8f42 100644 --- a/scan_ldapbindrequest.c +++ b/scan_ldapbindrequest.c @@ -1,10 +1,10 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapbindrequest(const char* src,const char* max, - unsigned long* version,struct string* name, - unsigned long* method) { - unsigned int res,tmp; +size_t scan_ldapbindrequest(const char* src,const char* max, + unsigned long* version,struct string* name, + unsigned long* method) { + size_t res,tmp; if (!(res=scan_asn1INTEGER(src,max,(signed long*)version))) return 0; if (!(tmp=scan_ldapstring(src+res,max,name))) return 0; res+=tmp; diff --git a/scan_ldapbindresponse.c b/scan_ldapbindresponse.c index 3514abd..eef04bf 100644 --- a/scan_ldapbindresponse.c +++ b/scan_ldapbindresponse.c @@ -1,10 +1,10 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapbindresponse(const char* src,const char* max, - unsigned long* result,struct string* matcheddn, - struct string* errormessage,struct string* referral) { - unsigned int res,tmp; +size_t scan_ldapbindresponse(const char* src,const char* max, + unsigned long* result,struct string* matcheddn, + struct string* errormessage,struct string* referral) { + size_t res,tmp; if (!(res=scan_asn1ENUMERATED(src,max,result))) return 0; if (!(tmp=scan_ldapstring(src+res,max,matcheddn))) return 0; res+=tmp; diff --git a/scan_ldapmessage.c b/scan_ldapmessage.c index 3d31563..dd179b5 100644 --- a/scan_ldapmessage.c +++ b/scan_ldapmessage.c @@ -1,9 +1,9 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapmessage(const char* src,const char* max, - unsigned long* messageid,unsigned long* op,unsigned long* len) { - unsigned int res,tmp; +size_t scan_ldapmessage(const char* src,const char* max, + unsigned long* messageid,unsigned long* op,size_t* len) { + size_t res,tmp; if (!(res=scan_asn1SEQUENCE(src,max,len))) goto error; if (!(tmp=scan_asn1INTEGER(src+res,max,(long*)messageid))) goto error; res+=tmp; diff --git a/scan_ldapmodifyrequest.c b/scan_ldapmodifyrequest.c index d024497..0edb686 100644 --- a/scan_ldapmodifyrequest.c +++ b/scan_ldapmodifyrequest.c @@ -17,9 +17,8 @@ vals SET OF AttributeValue } #endif -unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m) { - unsigned int res,tmp; - unsigned long oslen; /* outer sequence length */ +size_t scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m) { + size_t res,tmp,oslen; /* outer sequence length */ struct Modification* last=0; m->m.next=0; if (!(res=scan_ldapstring(src,max,&m->object))) goto error; @@ -29,7 +28,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif max=src+res+oslen; if (src+res>=max) goto error; /* need at least one record */ do { - unsigned long islen, etmp; + size_t islen, etmp; if (last) { struct Modification* cur; if (!(cur=malloc(sizeof(struct Modification)))) goto error; @@ -42,7 +41,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif if (!(tmp=scan_asn1ENUMERATED(src+res,max,&etmp))) goto error; if (etmp>2) goto error; last->operation=etmp; res+=tmp; { - unsigned long iislen; /* urgh, _three_ levels of indirection */ + size_t iislen; /* urgh, _three_ levels of indirection */ const char* imax; if (!(tmp=scan_asn1SEQUENCE(src+res,max,&iislen))) goto error; res+=tmp; @@ -51,7 +50,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif if (!(tmp=scan_ldapstring(src+res,imax,&last->AttributeDescription))) goto error; res+=tmp; { - unsigned long iiislen; /* waah, _four_ levels of indirection! It doesn't get more inefficient than this */ + size_t iiislen; /* waah, _four_ levels of indirection! It doesn't get more inefficient than this */ const char* iimax; struct AttributeDescriptionList* ilast=0; if (!(tmp=scan_asn1SET(src+res,max,&iiislen))) goto error; diff --git a/scan_ldapresult.c b/scan_ldapresult.c index f8ac914..7743228 100644 --- a/scan_ldapresult.c +++ b/scan_ldapresult.c @@ -1,10 +1,10 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapresult(const char* src,const char* max,unsigned long* result, - struct string* matcheddn,struct string* errormessage, - struct string* referral) { - unsigned int res,tmp; +size_t scan_ldapresult(const char* src,const char* max,unsigned long* result, + struct string* matcheddn,struct string* errormessage, + struct string* referral) { + size_t res,tmp; if (!(res=scan_asn1ENUMERATED(src,max,result))) return 0; if (!(tmp=scan_ldapstring(src+res,max,matcheddn))) return 0; res+=tmp; diff --git a/scan_ldapsearchfilter.c b/scan_ldapsearchfilter.c index 1689964..24bafda 100644 --- a/scan_ldapsearchfilter.c +++ b/scan_ldapsearchfilter.c @@ -30,12 +30,10 @@ dnAttributes [4] BOOLEAN DEFAULT FALSE } */ -unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) { +size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) { enum asn1_tagclass tc; enum asn1_tagtype tt; - unsigned long tag,len; - unsigned int res; - unsigned int tmp; + size_t tag,len,res,tmp; const char* nmax; *f=0; if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error; @@ -80,7 +78,7 @@ unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter break; case 4: /* substrings [4] SubstringFilter, */ { - unsigned long len2; + size_t len2; if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) goto error; res+=tmp; if (!(tmp=scan_asn1SEQUENCE(src+res,nmax,&len2))) goto error; diff --git a/scan_ldapsearchfilterstring.c b/scan_ldapsearchfilterstring.c index 6116340..4f67dd4 100644 --- a/scan_ldapsearchfilterstring.c +++ b/scan_ldapsearchfilterstring.c @@ -2,11 +2,11 @@ #include "ldap.h" #include "str.h" -unsigned int scan_ldapsearchfilterstring(const char* src,struct Filter** f) { +size_t scan_ldapsearchfilterstring(const char* src,struct Filter** f) { char* s=(char*)src; if (!(*f=calloc(sizeof(struct Filter),1))) goto error; if (s[0]=='*' && (s[1]==0 || s[1]=='(')) { - int i=scan_ldapsearchfilterstring("(objectClass=*)",f); + size_t i=scan_ldapsearchfilterstring("(objectClass=*)",f); if (i) return 1; } if (*s!='(') goto error; @@ -18,7 +18,7 @@ scan_filterlist: s+=scan_ldapsearchfilterstring(s,&(*f)->x); n=&(*f)->x->next; while (*s!=')') { - unsigned long l=scan_ldapsearchfilterstring(s,n); + size_t l=scan_ldapsearchfilterstring(s,n); if (!l) return 0; s+=l; n=&(*n)->next; @@ -51,7 +51,7 @@ scan_filterlist: (*f)->type=SUBSTRING; substring: while (*s!=')') { - int i,j; + size_t i,j; struct Substring* substring=malloc(sizeof(struct Substring)); if (!substring) goto error; substring->s.s=s; @@ -70,7 +70,7 @@ substring: if (*s==0) goto error; } } else { - int i,j; + size_t i,j; i=str_chr(s,')'); j=str_chr(s,'*'); if (i>j) { diff --git a/scan_ldapsearchrequest.c b/scan_ldapsearchrequest.c index 2517c19..f58f24c 100644 --- a/scan_ldapsearchrequest.c +++ b/scan_ldapsearchrequest.c @@ -2,9 +2,9 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapsearchrequest(const char* src,const char* max, - struct SearchRequest* s) { - unsigned int res,tmp; +size_t scan_ldapsearchrequest(const char* src,const char* max, + struct SearchRequest* s) { + size_t res,tmp; unsigned long etmp; signed long ltmp; s->attributes=0; diff --git a/scan_ldapsearchresultentry.c b/scan_ldapsearchresultentry.c index 5b81833..08f82b4 100644 --- a/scan_ldapsearchresultentry.c +++ b/scan_ldapsearchresultentry.c @@ -2,9 +2,8 @@ #include "asn1.h" #include "ldap.h" -unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) { - unsigned int res,tmp; - unsigned long oslen; /* outer sequence length */ +size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) { + size_t res,tmp,oslen; /* outer sequence length */ struct PartialAttributeList** a=&sre->attributes; *a=0; if (!(res=scan_ldapstring(src,max,&sre->objectName))) goto error; @@ -15,7 +14,7 @@ unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct S while (src+resmax) goto error; diff --git a/scan_ldapstring.c b/scan_ldapstring.c index 6590608..7f3047d 100644 --- a/scan_ldapstring.c +++ b/scan_ldapstring.c @@ -1,6 +1,6 @@ #include #include -unsigned int scan_ldapstring(const char* src,const char* max,struct string* s) { +size_t scan_ldapstring(const char* src,const char* max,struct string* s) { return scan_asn1STRING(src,max,&s->s,&s->l); } diff --git a/strduptab.c b/strduptab.c index 41bb539..07dd244 100644 --- a/strduptab.c +++ b/strduptab.c @@ -7,7 +7,7 @@ #define PAGESIZE 4096 const char* strduptab_add(struct stringduptable* t,const char* s) { - int i; + size_t i; for (i=0; in; ++i) if (str_equal(t->s[i],s)) return t->s[i]; diff --git a/strduptab.h b/strduptab.h index 48097b6..2bbc67c 100644 --- a/strduptab.h +++ b/strduptab.h @@ -6,7 +6,7 @@ * the new string. */ struct stringduptable { - int n,a; + size_t n,a; const char** s; }; diff --git a/strstorage.c b/strstorage.c index 309049b..3cc98b7 100644 --- a/strstorage.c +++ b/strstorage.c @@ -4,9 +4,9 @@ #define PAGESIZE 4096 -const char* strstorage_add(const char* s,int n) { +const char* strstorage_add(const char* s,size_t n) { static char* page=0; - static int leftonpage=0; + static size_t leftonpage=0; if (leftonpage>=n) { copyit: byte_copy(page,n,s); diff --git a/strstorage.h b/strstorage.h index ea51ca1..c1837ac 100644 --- a/strstorage.h +++ b/strstorage.h @@ -2,5 +2,5 @@ * later. On the plus side, the allocation overhead is close to zero. * Will return a pointer to the stored copy of the string. */ -const char* strstorage_add(const char* s,int n); +const char* strstorage_add(const char* s,size_t n); diff --git a/t2.c b/t2.c index 18dcfc1..3e707d4 100644 --- a/t2.c +++ b/t2.c @@ -120,7 +120,7 @@ int main(int argc,char* argv[]) { { unsigned long result; struct string matcheddn,errormessage,referral; - printf("scan_ldapbindresponse: %d\n", + printf("scan_ldapbindresponse: %zd\n", scan_ldapbindresponse(ldapsequence+done+res,ldapsequence+done+res+len, &result,&matcheddn,&errormessage,&referral)); printf("result %lu, matcheddn \"%.*s\", errormessage \"%.*s\", referral \"%.*s\"\n", @@ -184,7 +184,7 @@ int main(int argc,char* argv[]) { { unsigned long result; struct string matcheddn,errormessage,referral; - printf("scan_ldapresult: %d\n", + printf("scan_ldapresult: %zd\n", scan_ldapresult(ldapsequence+done+res,ldapsequence+done+res+len, &result,&matcheddn,&errormessage,&referral)); printf("result %lu, matcheddn \"%.*s\", errormessage \"%.*s\", referral \"%.*s\"\n", diff --git a/tinyldap.c b/tinyldap.c index 6408133..577bbc7 100644 --- a/tinyldap.c +++ b/tinyldap.c @@ -1,10 +1,12 @@ #include #include #include +#include "str.h" #include "case.h" #include "byte.h" #include "buffer.h" #include "ldap.h" +#include "mduptab.h" #include "ldif.h" #include "open.h" #include "mmap.h" @@ -28,6 +30,9 @@ #include #include #include +#include "errmsg.h" +#include "textcode.h" +#include "fmt.h" #ifdef DEBUG #include @@ -38,9 +43,11 @@ #define debug 0 #endif +#define HUGE_SIZE_FOR_SANITY_CHECKS 1024*1024 + /* basic operation: the whole data file is mmapped read-only at the beginning and stays there. */ char* map; /* where the file is mapped */ -unsigned long filelen; /* how many bytes are mapped (the whole file) */ +size_t filelen; /* how many bytes are mapped (the whole file) */ uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table; /* these are the first values from the file, see the file "FORMAT" * basic counts and offsets needed to calculate the positions of @@ -58,6 +65,23 @@ uint32 dn_ofs,objectClass_ofs,userPassword_ofs,any_ofs; + +/* journal hash structures */ +struct attribute2 { + unsigned char* a,* v; +}; + +struct hashnode { + struct hashnode* next; + unsigned long hashval; + unsigned char* dn; + size_t n; + struct attribute2 a[1]; +}; + + + + /* to avoid string compares, we don't work with char* but with uint32 (offsets within * the mmapped file) whenever it's about values that will be mentioned in the file, such * as attribute names. So, for each filter we get sent, we look up the attributes in the @@ -82,7 +106,7 @@ static void fixup(struct Filter* f) { case APPROX: { char* x=map+5*4+size_of_string_table; - unsigned int i; + size_t i; f->attrofs=f->attrflag=0; for (i=0; iattrofs=0; for (i=0; i < | (_| (_) | (_| | __/ |_|_| |_|\__,_|\___/_/\_\ \___\___/ \__,_|\___| -#endif +*/ /* find out whether this filter can be accelerated with the indices */ static int indexable(struct Filter* f) { @@ -463,14 +487,14 @@ static long findrec(uint32 dat) { struct bitfield { unsigned long* bits; #ifdef RANGECHECK - unsigned long n; + size_t n; #endif - unsigned long first,last; + size_t first,last; }; /* basic bit-set support: set all bits to 0 */ static inline void emptyset(struct bitfield* b) { - unsigned long i; + size_t i; #ifdef RANGECHECK b->n= #endif @@ -481,7 +505,7 @@ static inline void emptyset(struct bitfield* b) { /* basic bit-set support: set all bits to 1 */ static inline void fillset(struct bitfield* b) { - unsigned long i; + size_t i; b->first=0; #ifdef RANGECHECK b->n= @@ -491,7 +515,7 @@ static inline void fillset(struct bitfield* b) { } /* basic bit-set support: set one bit to 1 */ -static inline void setbit(struct bitfield* b,unsigned long bit) { +static inline void setbit(struct bitfield* b,size_t bit) { #ifdef RANGECHECK if (bit<=b->n) { #endif @@ -504,7 +528,7 @@ static inline void setbit(struct bitfield* b,unsigned long bit) { } /* basic bit-set support: see if given bit is set */ -static inline int isset(struct bitfield* b,unsigned long bit) { +static inline int isset(struct bitfield* b,size_t bit) { #ifdef RANGECHECK if (bit>b->n) return 0; #endif @@ -514,7 +538,7 @@ static inline int isset(struct bitfield* b,unsigned long bit) { /* use index (sorted table of offsets to records) to do a binary search * for all records that match the value in s. Set the corresponding * bits to 1 in bitfield. */ -static void tagmatches(uint32* index,unsigned int elements,struct string* s, +static void tagmatches(uint32* index,size_t elements,struct string* s, struct bitfield* b,int (*match)(struct string* s,const char* c), uint32 index_type,enum FilterType ft) { uint32 bottom=0; @@ -623,9 +647,8 @@ static void tagmatches(uint32* index,unsigned int elements,struct string* s, } } -uint32 hash(const unsigned char* c,unsigned long keylen) { - unsigned long h=0; - unsigned long i; +uint32 hash(const unsigned char* c,size_t keylen) { + size_t h=0,i; for (i=0; ibits[i] &= tmp.bits[i]; if (tmp.first>b->first) b->first=tmp.first; @@ -724,7 +746,7 @@ static int useindex(struct Filter* f,struct bitfield* b) { emptyset(b); while (y) { if (useindex(y,&tmp)) { - unsigned int i; + size_t i; for (i=0; ibits[i] |= tmp.bits[i]; if (tmp.firstfirst) b->first=tmp.first; @@ -765,7 +787,7 @@ static int useindex(struct Filter* f,struct bitfield* b) { * through the record table, but since each check is very cheap, * we pretend it's indexed */ char* x=map+5*4+size_of_string_table+attribute_count*8; - unsigned long i; + size_t i; emptyset(b); for (i=0; iattrofs)) @@ -801,17 +823,17 @@ static int useindex(struct Filter* f,struct bitfield* b) { -#if 0 +/* _ __ _ _ _ ___ _ __ _ _ __ _ _ __ _____ _____ _ __(_)_ __ __ _ / _` | | | |/ _ \ '__| | | | / _` | '_ \/ __\ \ /\ / / _ \ '__| | '_ \ / _` | | (_| | |_| | __/ | | |_| | | (_| | | | \__ \\ V V / __/ | | | | | | (_| | \__, |\__,_|\___|_| \__, | \__,_|_| |_|___/ \_/\_/ \___|_| |_|_| |_|\__, | |_| |___/ |___/ -#endif +*/ -static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct SearchResultEntry* sre) { - uint32_t j; +static int checkacl(uint32 recofs,uint32 attrofs,unsigned long operation,struct SearchResultEntry* sre) { + uint32 j; for (j=0; jsubject]) continue; @@ -824,9 +846,9 @@ static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct Sea if (Filters[Acls[j]->object]==(struct Filter*)Any) match=1; else if (Filters[Acls[j]->object]==(struct Filter*)Self) - match=(ofs==authenticated_as); - else if (ofs) - match=ldap_matchfilter_mapped(ofs,Filters[Acls[j]->object]); + match=(recofs==authenticated_as); + else if (recofs) + match=ldap_matchfilter_mapped(recofs,Filters[Acls[j]->object]); else if (sre) match=ldap_matchfilter_sre(sre,Filters[Acls[j]->object]); else @@ -853,12 +875,62 @@ static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct Sea return 0; } +static int ldap_matchfilter_hn(struct hashnode* hn,struct Filter* f); + +static int checkacl_hn(struct hashnode* hn,const unsigned char* attr,unsigned long operation) { + uint32 j; + for (j=0; jsubject]) continue; + /* does the ACL even apply to the wanted operation? */ + if ((Acls[j]->may | Acls[j]->maynot) & operation) { + uint32 k; + if (acl_ec_subjects[filters+Acls[j]->object]==-1) continue; + if (acl_ec_subjects[filters+Acls[j]->object]==0) { + int match=0; + if (Filters[Acls[j]->object]==(struct Filter*)Any) + match=1; + else if (Filters[Acls[j]->object]==(struct Filter*)Self) + match=dn && !strcmp((char*)hn->dn,map+authenticated_as); + else if (dn) + match=ldap_matchfilter_hn(hn,Filters[Acls[j]->object]); + else + match=-1; + if (match) + acl_ec_subjects[filters+Acls[j]->object]=1; + else { + acl_ec_subjects[filters+Acls[j]->object]=-1; + continue; + } + } + for (k=0; kattrs; ++k) { +/* if (Acls[j]->Attrs[k]==any_ofs || !matchstring(&adl->a,map+Acls[j]->Attrs[k])) { */ + if (Acls[j]->Attrs[k]==any_ofs || bstr_equal((char*)attr,map+Acls[j]->Attrs[k])) { + if (Acls[j]->may&operation) + return 1; + else + return -1; + break; + } + } + } + } + return 0; +} + + +static struct hashnode** dn_in_journal(unsigned char* dn); + /* this routine is called for each record matched the query. It basically puts together * an answer LDAP message from the record and the list of attributes the other side said * it wanted to have. */ static void answerwith(uint32 ofs,struct SearchRequest* sr,long messageid,int out) { struct SearchResultEntry sre; struct PartialAttributeList** pal=&sre.attributes; + struct hashnode** hn; + + if ((hn=dn_in_journal((unsigned char*)map+uint32_read(map+ofs+8))) && *hn) + return; #if (debug != 0) if (debug) { @@ -897,20 +969,21 @@ static void answerwith(uint32 ofs,struct SearchRequest* sr,long messageid,int ou /* now go through list of requested attributes */ { struct AttributeDescriptionList* adl=sr->attributes; - if (!adl) { + if (!adl && attribute_count>2) { /* did not ask for any attributes. send 'em all. */ /* to do that, construct a list of all attributes */ - /* FIXME! This adl appears to create a segfault later on */ uint32 i; char* x=map+5*4+size_of_string_table+4; + if (attribute_count>HUGE_SIZE_FOR_SANITY_CHECKS/sizeof(struct AttributeDescriptionList)) + return; adl=alloca((attribute_count)*sizeof(struct AttributeDescriptionList)); for (i=0; is=malloc(src->l+1); @@ -1037,6 +1113,7 @@ static int copypal(struct PartialAttributeList** dest,struct PartialAttributeLis } #endif +/* small helper for addreq2sre */ static int ar2sreh1(struct PartialAttributeList** dest,struct Addition* src) { *dest=0; while (src) { @@ -1050,25 +1127,112 @@ static int ar2sreh1(struct PartialAttributeList** dest,struct Addition* src) { return 0; } -int addreq2sre(struct SearchResultEntry* sre,struct AddRequest* ar) { +/* convert an AddRequest to a SearchResultEntry */ +static int addreq2sre(struct SearchResultEntry* sre,struct AddRequest* ar) { byte_zero(sre,sizeof(*sre)); - if (copystring(&sre->objectName,&ar->entry)) goto allocfailed; - if (!(sre->attributes=malloc(sizeof(*sre->attributes)))) goto allocfailed; - if (ar2sreh1(&sre->attributes,&ar->a)) goto allocfailed; + if (copystring(&sre->objectName,&ar->entry) || + !(sre->attributes=malloc(sizeof(*sre->attributes))) || + ar2sreh1(&sre->attributes,&ar->a)) { + free_ldapsearchresultentry(sre); + return -1; + } return 0; -allocfailed: - free_ldapsearchresultentry(sre); - return -1; +} + +/* write a search result entry to a file */ +static int writesretofd(int fd,struct SearchResultEntry* sre) { + /* we have no locking, but we open using O_APPEND, so the OS synchronizes for us as long + * as we write atomically. Therefore we have to buffer here. */ + size_t i,l,nl; + char* c; + struct PartialAttributeList* pal=sre->attributes; + l=5+fmt_ldapescape(0,sre->objectName.s,sre->objectName.l); /* "\ndn: ...\n" */ + if (l<=5) return -1; + while (pal) { + struct AttributeDescriptionList* adl=pal->values; + while (adl) { + nl=fmt_ldapescape(0,pal->type.s,pal->type.l); + if (nl>HUGE_SIZE_FOR_SANITY_CHECKS) return -1; + l+=nl; + nl=fmt_ldapescape(0,adl->a.s,adl->a.l); + if (nl>HUGE_SIZE_FOR_SANITY_CHECKS) return -1; + l+=nl; + if (l+3>HUGE_SIZE_FOR_SANITY_CHECKS) return -1; + l+=3; + adl=adl->next; + } + pal=pal->next; + } + c=alloca(l+1); + if (!c) return -1; + i=fmt_str(c,"dn: "); + i+=fmt_ldapescape(c+i,sre->objectName.s,sre->objectName.l); + i+=fmt_str(c+i,"\n"); + pal=sre->attributes; + while (pal) { + struct AttributeDescriptionList* adl=pal->values; + while (adl) { + i+=fmt_ldapescape(c+i,pal->type.s,pal->type.l); + i+=fmt_str(c+i,": "); + i+=fmt_ldapescape(c+i,adl->a.s,adl->a.l); + i+=fmt_str(c+i,"\n"); + adl=adl->next; + } + pal=pal->next; + } + i+=fmt_str(c+i,"\n"); + + return (write(fd,c,i)==(ssize_t)i)?0:-1; } /* This is the high level LDAP handling code. It reads queries from the socket at in, and * then writes the answers to out. Normally in == out, but they are separate here so this * can also be called with in=stdin and out=stdout. */ -int writesretofd(int fd,struct SearchResultEntry* sre) { - unsigned long l=fmt_ldapsearchresultentry(0,sre); - char* c=alloca(l+10); /* you never know */ - return (write(fd,c,l)==(ssize_t)l)?0:-1; +static void answerwithjournal(struct SearchRequest* sr,long messageid,int out); +static struct hashnode** dn_in_journal2(const char* dn,size_t dnlen); + +static int lookupdn(struct string* dn,size_t* index, struct hashnode** hn) { + struct Filter f; + struct hashnode** tmphn; + if ((tmphn=dn_in_journal2(dn->s,dn->l)) && *tmphn) { + *hn=*tmphn; + *index=-1; + return (*hn)->n > 0; + } + *hn=0; + f.type=EQUAL; + f.ava.desc.l=2; f.ava.desc.s="dn"; + f.ava.value=*dn; + f.next=0; + fixup(&f); + if (!indexable(&f)) { + buffer_putsflush(buffer_2,"no index for dn, lookup failed!\n"); + return -1; + } else { + struct bitfield result; + size_t i,done; + result.bits=alloca(record_set_length*sizeof(unsigned long)); + useindex(&f,&result); + done=0; + if (result.first>result.last) + return 0; + done=0; + assert(result.last<=record_count); + for (i=result.first; i<=result.last; ) { + if (!result.bits[i/(8*sizeof(long))]) { + i+=8*sizeof(long); + continue; + } + for (; i<=result.last; ++i) { + if (isset(&result,i)) { + *index=i; + return 1; + } + } + } + } + return 0; } /* a standard LDAP session looks like this: @@ -1083,12 +1247,12 @@ int writesretofd(int fd,struct SearchResultEntry* sre) { * tinyldap does not complain if you don't unbind before hanging up. */ int handle(int in,int out) { - unsigned int len; + size_t len; char buf[BUFSIZE]; for (len=0;;) { int tmp=read(in,buf+len,BUFSIZE-len); int res; - unsigned long messageid,op,Len; + size_t messageid,op,Len; if (tmp==0) { close(in); if (in!=out) close(out); @@ -1140,16 +1304,16 @@ int handle(int in,int out) { authfailure: { char outbuf[1024]; - int s=100; - int len=fmt_ldapbindresponse(outbuf+s,inappropriateAuthentication,"","authentication failure",""); - int hlen=fmt_ldapmessage(0,messageid,BindResponse,len); + size_t s=100; + size_t len=fmt_ldapbindresponse(outbuf+s,inappropriateAuthentication,"","authentication failure",""); + size_t hlen=fmt_ldapmessage(0,messageid,BindResponse,len); fmt_ldapmessage(outbuf+s-hlen,messageid,BindResponse,len); write(out,outbuf+s-hlen,len+hlen); continue; } } else { struct bitfield result; - unsigned long i,done; + size_t i,done; result.bits=alloca(record_set_length*sizeof(unsigned long)); useindex(&f,&result); done=0; @@ -1220,7 +1384,7 @@ found: } #endif if ((tmp=scan_ldapsearchrequest(buf+res,buf+res+len,&sr))) { - unsigned long returned=0; + size_t returned=0; #if (debug != 0) if (debug) { @@ -1247,7 +1411,7 @@ found: fixupadl(sr.attributes); if (indexable(sr.filter)) { struct bitfield result; - unsigned long i; + size_t i; #if (debug != 0) if (debug) buffer_putsflush(buffer_2,"query can be answered with index!\n"); #endif @@ -1258,7 +1422,7 @@ found: useindex(sr.filter,&result); assert(result.last<=record_count); for (i=result.first; i<=result.last; ) { - unsigned long ni=i+8*sizeof(long); + size_t ni=i+8*sizeof(long); if (!result.bits[i/(8*sizeof(long))]) { i=ni; continue; @@ -1278,7 +1442,7 @@ found: } } else { char* x=map+5*4+size_of_string_table+attribute_count*8; - unsigned long i; + size_t i; #if (debug != 0) if (debug) buffer_putsflush(buffer_2,"query can NOT be answered with index!\n"); #endif @@ -1293,6 +1457,9 @@ found: x+=j*8; } } + + /* now answer with the results from the journal */ + answerwithjournal(&sr,messageid,out); free_ldapsearchrequest(&sr); } else { buffer_putsflush(buffer_2,"couldn't parse search request!\n"); @@ -1353,15 +1520,23 @@ found: // buffer_putsflush(buffer_2,"AddRequest!\n"); if ((tmp=scan_ldapaddrequest(buf+res,buf+res+len,&ar))) { struct SearchResultEntry sre; - addreq2sre(&sre,&ar); /* convert addrequest to searchresultentry */ + addreq2sre(&sre,&ar); /* TODO: do something with the add request ;-) */ /* 1. check ACLs */ if (!acls || checkacl(0,0,acl_add,&sre)==1) { - /* 2. check is there already is a record with this dn */ + /* 2. check if there already is a record with this dn */ + struct hashnode* hn; + size_t idx; + switch (lookupdn(&sre.objectName,&idx,&hn)) { + case -1: err=operationsError; break; + case 1: err=entryAlreadyExists; break; + case 0: break; + default: err=operationsError; + } + if (err==success) { /* 3. write record to "data.upd" */ - { - int fd=open("data.upd",O_WRONLY|O_APPEND|O_CREAT,0600); + int fd=open("journal",O_WRONLY|O_APPEND|O_CREAT,0600); if (fd==-1) err=operationsError; else { @@ -1426,19 +1601,360 @@ found: } } -#if 0 + + +/* journal reading code */ + +extern int (*ldif_parse_callback)(struct ldaprec* l); + +extern mstorage_t stringtable; +extern mduptab_t attributes,classes; + +unsigned long hash2(const unsigned char* c) { + unsigned long h=0; + if (*c==0) { + uint32 len=uint32_read((char*)c+1); + return hash(c+5,len); + } + while (*c) { + /* from djb's cdb */ + h += (h<<5); + h ^= *c; + ++c; + } + return h; +} + +#define HASHTABSIZE 8191 + +unsigned char* bstrdup(unsigned char* c) { + size_t len; + unsigned char* x; + if (*c) + len=str_len((char*)c); + else { + len=5+uint32_read((char*)c+1); + if (len<5) return 0; + } + x=malloc(len); + if (x) byte_copy(x,len,c); + return x; +} + +unsigned char* bstrdup_attrib(unsigned char* c) { + char* x=map+5*4+size_of_string_table; + size_t i,l; + if (*c) + l=str_len((char*)c)+1; + else { + l=uint32_read((char*)c+1); + c+=5; + } + for (i=0; ihashval==hashval) { + if (!bstr_diff((char*)(*hn)->dn,(char*)dn)) + break; + } + hn=&((*hn)->next); + } + return hn; +} + +static struct hashnode** dn_in_journal2(const char* dn,size_t dnlen) { + unsigned long hashval; + struct hashnode** hn; + hashval=hash2((const unsigned char*)dn); + hn=hashtab+(hashval%HASHTABSIZE); + while (*hn) { + if ((*hn)->hashval==hashval) { + if (!bstr_diff2((char*)(*hn)->dn,dn,dnlen)) + break; + } + hn=&((*hn)->next); + } + return hn; +} + + +int parse_callback(struct ldaprec* l) { + size_t i; + unsigned long hashval; + struct hashnode** hn; + if (l->dn==(uint32)-1) return -1; + hashval=hash2((unsigned char*)stringtable.root+l->dn); + hn=hashtab+(hashval%HASHTABSIZE); + while (*hn) { + if ((*hn)->hashval==hashval) { + if (!bstr_diff((char*)(*hn)->dn,stringtable.root+l->dn)) + break; + } + hn=&((*hn)->next); + } + if (*hn) { + /* a record with this dn exists */ + /* adjust it to the new reality */ + for (i=0; i<(*hn)->n; ++i) { + free((*hn)->a[i].a); + free((*hn)->a[i].v); + } + *hn = realloc(*hn,sizeof(**hn)-sizeof(struct attribute2)+l->n*sizeof(struct attribute2)); + if (!*hn) nomem: die(1,"out of memory!"); + } else { + *hn = malloc(sizeof(**hn)-sizeof(struct attribute2)+l->n*sizeof(struct attribute2)); + if (!*hn) goto nomem; + if (!((*hn)->dn=bstrdup((unsigned char*)stringtable.root+l->dn))) goto nomem; + (*hn)->hashval=hashval; + (*hn)->next=0; + } + (*hn)->n=l->n; + for (i=0; in; ++i) { + if (!((*hn)->a[i].a=bstrdup_attrib((unsigned char*)attributes.strings.root+l->a[i].name)) || + !((*hn)->a[i].v=bstrdup((unsigned char*)((*hn)->a[i].a==(unsigned char*)map+objectClass_ofs?classes.strings.root:stringtable.root)+l->a[i].value))) goto nomem; + } + stringtable.used=0; + return 0; +} + +int readjournal() { + ldif_parse_callback=parse_callback; + mduptab_init(&attributes); + mduptab_init(&classes); + return ldif_parse("journal"); +} + +static int ldap_matchfilter_hn(struct hashnode* hn,struct Filter* f) { + struct Filter* y=f->x; + size_t i; + if (!hn->n) return 0; + if (!f) return 1; + switch (f->type) { + case AND: + while (y) { + if (!ldap_matchfilter_hn(hn,y)) return 0; + y=y->next; + } + return 1; + case OR: + while (y) { + if (ldap_matchfilter_hn(hn,y)) return 1; + y=y->next; + } + return 0; + case NOT: + return !ldap_matchfilter_hn(hn,y); + case PRESENT: + if (f->attrofs==dn_ofs) + return 1; + for (i=0; in; ++i) + if (!matchstring(&f->ava.desc,(char*)hn->a[i].a)) + return 1; + return 0; + case EQUAL: + case LESSEQUAL: + case GREATEQUAL: + if (f->attrofs==dn_ofs) + return matchint(f,(char*)hn->dn); + for (i=0; in; ++i) + if (!matchstring(&f->ava.desc,(char*)hn->a[i].a) && + matchint(f,(char*)hn->a[i].v)) return 1; + return 0; + case SUBSTRING: + if (f->attrofs==dn_ofs) + return substringmatch(f->substrings,(char*)hn->dn,f->attrflag&1); + for (i=0; in; ++i) + if (!matchstring(&f->ava.desc,(char*)hn->a[i].a) && + substringmatch(f->substrings,(char*)hn->a[i].v,f->attrflag&1)) return 1; + return 0; + default: + write(2,"unsupported query type\n",23); + return 0; + } + return 1; +} + +/* return 0 if they didn't match, otherwise return length in b */ +static int match(const char* a,int len,const char* b) { + const char* A=a+len; + const char* B=b+str_len(b); + while (len>0 && A>a && B>b) { + --A; --B; --len; + while (*A==' ' && A>a) { --A; --len; } + while (*B==' ' && B>b) --B; + if (tolower(*A) != tolower(*B)) + return 0; + } + return str_len(B); +} + +static int matchhashnode(struct hashnode* hn,struct SearchRequest* sr) { + size_t i,len=bstrlen((char*)hn->dn); + unsigned char* c; + if (sr->baseObject.l>len) + /* baseObject is longer than dn */ + return 0; + if (sr->baseObject.l && !match(sr->baseObject.s,sr->baseObject.l,(char*)hn->dn)) + /* baseObject is not a suffix of dn */ + return 0; + switch (sr->scope) { + case wholeSubtree: break; + case baseObject: if (len==sr->baseObject.l) break; return 0; + default: + c=hn->dn+bstrstart((char*)hn->dn); + for (i=0; i=len-sr->baseObject.l) break; + return 0; + } + return ldap_matchfilter_hn(hn,sr->filter); +} + +static void answerwith_hn(struct hashnode* hn,struct SearchRequest* sr,long messageid,int out) { + struct SearchResultEntry sre; + struct PartialAttributeList** pal=&sre.attributes; + + if (acls) + byte_zero(acl_ec_subjects+filters,filters); + + if (acls && checkacl_hn(hn,(unsigned char*)map+dn_ofs,acl_read)!=1) return; + + sre.objectName.l=bstrlen(sre.objectName.s=(char*)hn->dn); + sre.attributes=0; + + /* now go through list of requested attributes */ + { + struct AttributeDescriptionList* adl=sr->attributes; + if (!adl && hn->n && hn->nn*sizeof(*adl)); + for (i=k=0; in; ++i) { + adl[k].a.s=(char*)hn->a[i].a; + adl[k].a.l=str_len((char*)hn->a[i].a); + adl[k].attrofs=0; + adl[k].next=adl+k+1; + for (j=0; ja[i].a,(char*)hn->a[j].a)) { + --k; + break; + } + } + ++k; + } + if (k) adl[k-1].next=0; + } + while (adl) { + const unsigned char* val=0; + uint32 i=0; + + if (!acls || checkacl_hn(hn,(unsigned char*)adl->a.s,acl_read)==1) { + if (!matchstring(&adl->a,"dn")) + val=hn->dn; + else { + for (; in; ++i) + if (!matchstring(&adl->a,(char*)hn->a[i].a)) { + val=hn->a[i].v; + ++i; + break; + } + } + if (val) { + *pal=malloc(sizeof(struct PartialAttributeList)); + if (!*pal) { +nomem: + buffer_putsflush(buffer_2,"out of virtual memory!\n"); + exit(1); + } + (*pal)->type=adl->a; + { + struct AttributeDescriptionList** a; + a=&(*pal)->values; +add_attribute: + *a=malloc(sizeof(struct AttributeDescriptionList)); + if (!*a) goto nomem; + (*a)->a.s=bstrfirst((char*)val); + (*a)->a.l=bstrlen((char*)val); + for (;in; ++i) + if (!matchstring(&adl->a,(char*)hn->a[i].a)) { + val=hn->a[i].v; + ++i; + a=&(*a)->next; + goto add_attribute; + } + (*a)->next=0; + } + (*pal)->next=0; + pal=&(*pal)->next; + } + } + adl=adl->next; + } + } + { + long l=fmt_ldapsearchresultentry(0,&sre); + char *buf; + long tmp; + if (lnext; + } + } +} + +/* _ _ __ ___ __ _(_)_ __ | '_ ` _ \ / _` | | '_ \ | | | | | | (_| | | | | | |_| |_| |_|\__,_|_|_| |_| -#endif +*/ int main(int argc,char* argv[]) { #ifdef STANDALONE int sock; #endif + errmsg_iam("tinyldap"); + signal(SIGPIPE,SIG_IGN); map=mmap_read(argc>1?argv[1]:"data",&filelen); @@ -1456,7 +1972,7 @@ int main(int argc,char* argv[]) { /* look up "dn" and "objectClass" */ { char* x=map+5*4+size_of_string_table; - unsigned int i; + size_t i; dn_ofs=objectClass_ofs=userPassword_ofs=any_ofs=0; for (i=0; i