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