From bedd2e7ccb1595c23e159eaa952ae1b0b5a3d2ad Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sat, 15 Mar 2014 01:49:50 +0100 Subject: Lean and mean initial commit Not much functionality yet --- ldap_match_sre.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 ldap_match_sre.c (limited to 'ldap_match_sre.c') diff --git a/ldap_match_sre.c b/ldap_match_sre.c new file mode 100644 index 0000000..b0e69c1 --- /dev/null +++ b/ldap_match_sre.c @@ -0,0 +1,166 @@ +#include +#include "ldap.h" +#include "byte.h" +#include "case.h" +#include + +static int matchcasestr(struct string* a,struct string* b) { + unsigned long l=a->l; + unsigned long r; + if (b->ll; + if ((r=case_diffb(a->s,l,b->s))) return r; + if (a->l>l) return 1; + if (b->l>l) return -1; + return 0; +} + +static int matchstr(struct string* a,struct string* b) { + unsigned long l=a->l; + unsigned long r; + if (b->ll; + if ((r=byte_diff(a->s,l,b->s))) return r; + if (a->l>l) return 1; + if (b->l>l) return -1; + return 0; +} + +static int matchstr_sre(struct Filter* f,struct string* s) { + int r; + if (f->attrflag&1) + r=matchcasestr(&f->ava.value,s); + else + r=matchstr(&f->ava.value,s); + if (f->type==EQUAL) return (r==0); + if (f->type==LESSEQUAL) return (r>0); + return (r<0); +} + +static int ldap_match_present_sre(struct SearchResultEntry* sre,struct string* s) { + struct PartialAttributeList* p; + for (p=sre->attributes; p; p=p->next) { + int r; + if ((r=matchstr(&p->type,s))) return r; + } + return 0; +} + +static int substrmatch(struct Substring* x,struct string* s,int ignorecase) { + int (*diff)(const void* a, unsigned long len, const void* b); + if (ignorecase) + diff=case_diffb; + else + diff=byte_diff; + while (x) { + unsigned long i; + if (x->s.l>s->l) return 0; + switch (x->substrtype) { + case prefix: + if (diff(x->s.s,x->s.l,s->s)) return 0; +found: + break; + case any: + if (s->ls.l) return 0; + for (i=0; i<=s->l-x->s.l; ++i) + if (!diff(x->s.s,x->s.l,s->s+i)) + goto found; + return 0; + case suffix: + if (diff(x->s.s,x->s.l,s->s+s->l-x->s.l)) return 0; + } + x=x->next; + } + return 1; +} + +extern uint32_t dn_ofs; + +int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f) { + struct PartialAttributeList* p; + struct Filter* y=f->x; + if (!f) return 1; + switch (f->type) { + case AND: + while (y) { + if (!ldap_matchfilter_sre(sre,y)) return 0; + y=y->next; + } + return 1; + case OR: + while (y) { + if (ldap_matchfilter_sre(sre,y)) return 1; + y=y->next; + } + return 0; + case NOT: + return !ldap_matchfilter_sre(sre,y); + case PRESENT: + return ldap_match_present_sre(sre,&f->ava.desc); + case EQUAL: + case LESSEQUAL: + case GREATEQUAL: + if (f->attrofs==dn_ofs) + return matchstr_sre(f,&sre->objectName); + for (p=sre->attributes; p; p=p->next) { + int r; + struct AttributeDescriptionList* a; + if (matchstr(&f->ava.desc,&p->type)) { + for (a=p->values; a; a=a->next) + if ((r=matchstr_sre(f,&a->a))) return r; + return 0; + } + } + return 0; + case SUBSTRING: + if (f->attrofs==dn_ofs) + return substrmatch(f->substrings,&sre->objectName,f->attrflag&1); + for (p=sre->attributes; p; p=p->next) { + if (matchstr(&f->ava.desc,&p->type)) { + struct AttributeDescriptionList* a; + int r; + for (a=p->values; a; a=a->next) + if ((r=substrmatch(f->substrings,&a->a,f->attrflag&1))) return r; + return 0; + } + } + 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,int blen) { + const char* A=a+len; + const char* B=b+blen; + 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 b+blen-B; +} + +int ldap_match_sre(struct SearchResultEntry* sre,struct SearchRequest* sr) { + unsigned long i; + if (sr->baseObject.l>sre->objectName.l) + /* baseObject is longer than dn */ + return 0; + if (sr->baseObject.l && !match(sr->baseObject.s,sr->baseObject.l,sre->objectName.s,sre->objectName.l)) + /* baseObject is not a suffix of dn */ + return 0; + switch (sr->scope) { + case wholeSubtree: break; + case baseObject: if (sre->objectName.l==sr->baseObject.l) break; return 0; + default: + for (i=0; iobjectName.l; ++i) + if (sre->objectName.s[i]==',') + break; + if (i+2>=sre->objectName.l-sr->baseObject.l) break; + return 0; + } + return ldap_matchfilter_sre(sre,sr->filter); +} -- cgit v1.2.3-55-g7522