1 #include <unistd.h>
2 #include "ldap.h"
3 #include "byte.h"
4 #include "case.h"
5 #include <ctype.h>
6 
matchcasestr(struct string * a,struct string * b)7 static int matchcasestr(struct string* a,struct string* b) {
8   unsigned long l=a->l;
9   unsigned long r;
10   if (b->l<l) l=b->l;
11   if ((r=case_diffb(a->s,l,b->s))) return r;
12   if (a->l>l) return 1;
13   if (b->l>l) return -1;
14   return 0;
15 }
16 
matchstr(struct string * a,struct string * b)17 static int matchstr(struct string* a,struct string* b) {
18   unsigned long l=a->l;
19   unsigned long r;
20   if (b->l<l) l=b->l;
21   if ((r=byte_diff(a->s,l,b->s))) return r;
22   if (a->l>l) return 1;
23   if (b->l>l) return -1;
24   return 0;
25 }
26 
matchstr_sre(struct Filter * f,struct string * s)27 static int matchstr_sre(struct Filter* f,struct string* s) {
28   int r;
29   if (f->attrflag&1)
30     r=matchcasestr(&f->ava.value,s);
31   else
32     r=matchstr(&f->ava.value,s);
33   if (f->type==EQUAL) return (r==0);
34   if (f->type==LESSEQUAL) return (r>0);
35   return (r<0);
36 }
37 
ldap_match_present_sre(struct SearchResultEntry * sre,struct string * s)38 static int ldap_match_present_sre(struct SearchResultEntry* sre,struct string* s) {
39   struct PartialAttributeList* p;
40   for (p=sre->attributes; p; p=p->next) {
41     int r;
42     if ((r=matchstr(&p->type,s))) return r;
43   }
44   return 0;
45 }
46 
substrmatch(struct Substring * x,struct string * s,int ignorecase)47 static int substrmatch(struct Substring* x,struct string* s,int ignorecase) {
48   int (*diff)(const void* a, unsigned long len, const void* b);
49   if (ignorecase)
50     diff=case_diffb;
51   else
52     diff=byte_diff;
53   while (x) {
54     unsigned long i;
55     if (x->s.l>s->l) return 0;
56     switch (x->substrtype) {
57     case prefix:
58       if (diff(x->s.s,x->s.l,s->s)) return 0;
59 found:
60       break;
61     case any:
62       if (s->l<x->s.l) return 0;
63       for (i=0; i<=s->l-x->s.l; ++i)
64 	if (!diff(x->s.s,x->s.l,s->s+i))
65 	  goto found;
66       return 0;
67     case suffix:
68       if (diff(x->s.s,x->s.l,s->s+s->l-x->s.l)) return 0;
69     }
70     x=x->next;
71   }
72   return 1;
73 }
74 
75 extern uint32_t dn_ofs;
76 
ldap_matchfilter_sre(struct SearchResultEntry * sre,struct Filter * f)77 int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f) {
78   struct PartialAttributeList* p;
79   struct Filter* y=f->x;
80   if (!f) return 1;
81   switch (f->type) {
82   case AND:
83     while (y) {
84       if (!ldap_matchfilter_sre(sre,y)) return 0;
85       y=y->next;
86     }
87     return 1;
88   case OR:
89     while (y) {
90       if (ldap_matchfilter_sre(sre,y)) return 1;
91       y=y->next;
92     }
93     return 0;
94   case NOT:
95     return !ldap_matchfilter_sre(sre,y);
96   case PRESENT:
97     return ldap_match_present_sre(sre,&f->ava.desc);
98   case EQUAL:
99   case LESSEQUAL:
100   case GREATEQUAL:
101     if (f->attrofs==dn_ofs)
102       return matchstr_sre(f,&sre->objectName);
103     for (p=sre->attributes; p; p=p->next) {
104       int r;
105       struct AttributeDescriptionList* a;
106       if (matchstr(&f->ava.desc,&p->type)) {
107 	for (a=p->values; a; a=a->next)
108 	  if ((r=matchstr_sre(f,&a->a))) return r;
109 	return 0;
110       }
111     }
112     return 0;
113   case SUBSTRING:
114     if (f->attrofs==dn_ofs)
115       return substrmatch(f->substrings,&sre->objectName,f->attrflag&1);
116     for (p=sre->attributes; p; p=p->next) {
117       if (matchstr(&f->ava.desc,&p->type)) {
118 	struct AttributeDescriptionList* a;
119 	int r;
120 	for (a=p->values; a; a=a->next)
121 	  if ((r=substrmatch(f->substrings,&a->a,f->attrflag&1))) return r;
122 	return 0;
123       }
124     }
125     return 0;
126   default:
127     write(2,"unsupported query type\n",23);
128     return 0;
129   }
130   return 1;
131 }
132 
133 /* return 0 if they didn't match, otherwise return length in b */
match(const char * a,int len,const char * b,int blen)134 static int match(const char* a,int len,const char* b,int blen) {
135   const char* A=a+len;
136   const char* B=b+blen;
137   while (len>0 && A>a && B>b) {
138     --A; --B; --len;
139     while (*A==' ' && A>a) { --A; --len; }
140     while (*B==' ' && B>b) --B;
141     if (tolower(*A) != tolower(*B))
142       return 0;
143   }
144   return b+blen-B;
145 }
146 
ldap_match_sre(struct SearchResultEntry * sre,struct SearchRequest * sr)147 int ldap_match_sre(struct SearchResultEntry* sre,struct SearchRequest* sr) {
148   unsigned long i;
149   if (sr->baseObject.l>sre->objectName.l)
150     /* baseObject is longer than dn */
151     return 0;
152   if (sr->baseObject.l && !match(sr->baseObject.s,sr->baseObject.l,sre->objectName.s,sre->objectName.l))
153     /* baseObject is not a suffix of dn */
154     return 0;
155   switch (sr->scope) {
156   case wholeSubtree: break;
157   case baseObject: if (sre->objectName.l==sr->baseObject.l) break; return 0;
158   default:
159     for (i=0; i<sre->objectName.l; ++i)
160       if (sre->objectName.s[i]==',')
161 	break;
162     if (i+2>=sre->objectName.l-sr->baseObject.l) break;
163     return 0;
164   }
165   return ldap_matchfilter_sre(sre,sr->filter);
166 }
167