#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); }