r4474: - converted ldb to use talloc internally
[kamenim/samba.git] / source4 / lib / ldb / ldb_tdb / ldb_match.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9    
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldb expression matching
29  *
30  *  Description: ldb expression matching for tdb backend
31  *
32  *  Author: Andrew Tridgell
33  */
34
35 #include "includes.h"
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
38 #include "ldb/ldb_tdb/ldb_tdb.h"
39 #include "ldb/include/ldb_parse.h"
40 #include <fnmatch.h>
41
42 /*
43   see if two ldb_val structures contain the same data as integers
44   return 1 for a match, 0 for a mis-match
45 */
46 static int ltdb_val_equal_integer(const struct ldb_val *v1, const struct ldb_val *v2)
47 {
48         int i1, i2;
49
50         i1 = strtol(v1->data, NULL, 0);
51         i2 = strtol(v2->data, NULL, 0);
52
53         return i1 == i2;
54 }
55
56 /*
57   see if two ldb_val structures contain the same data as case insensitive strings
58   return 1 for a match, 0 for a mis-match
59 */
60 static int ltdb_val_equal_case_insensitive(const struct ldb_val *v1, 
61                                           const struct ldb_val *v2)
62 {
63         if (v1->length != v2->length) {
64                 return 0;
65         }
66         if (strncasecmp(v1->data, v2->data, v1->length) == 0) {
67                 return 1;
68         }
69         return 0;
70 }
71
72 /*
73   see if two ldb_val structures contain the same data with wildcards 
74   and case insensitive
75   return 1 for a match, 0 for a mis-match
76 */
77 static int ltdb_val_equal_wildcard_ci(struct ldb_module *module,
78                                      const struct ldb_val *v1, 
79                                      const struct ldb_val *v2)
80 {
81         struct ldb_context *ldb = module->ldb;
82         char *s1, *s2;
83         int ret;
84
85         if (!v1->data || !v2->data) {
86                 return v1->data == v2->data;
87         }
88
89         s1 = ldb_casefold(ldb, v1->data);
90         if (!s1) {
91                 return -1;
92         }
93
94         s2 = ldb_casefold(ldb, v2->data);
95         if (!s2) {
96                 talloc_free(s1);
97                 return -1;
98         }
99
100         ret = fnmatch(s2, s1, 0);
101
102         talloc_free(s1);
103         talloc_free(s2);
104
105         if (ret == 0) {
106                 return 1;
107         }
108
109         return 0;
110 }
111
112 /*
113   see if two ldb_val structures contain the same data with wildcards
114   return 1 for a match, 0 for a mis-match
115 */
116 static int ltdb_val_equal_wildcard(struct ldb_module *module,
117                                   const struct ldb_val *v1, 
118                                   const struct ldb_val *v2,
119                                   int flags)
120 {
121         if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
122                 return ltdb_val_equal_wildcard_ci(module, v1, v2);
123         }
124         if (!v1->data || !v2->data) {
125                 return v1->data == v2->data;
126         }
127         if (fnmatch(v2->data, v1->data, 0) == 0) {
128                 return 1;
129         }
130         return 0;
131 }
132
133
134 /*
135   see if two objectclasses are considered equal. This handles
136   the subclass attributes
137
138   v1 contains the in-database value, v2 contains the value
139   that the user gave
140
141   return 1 for a match, 0 for a mis-match
142 */
143 static int ltdb_val_equal_objectclass(struct ldb_module *module, 
144                                      const struct ldb_val *v1, const struct ldb_val *v2)
145 {
146         struct ltdb_private *ltdb = module->private_data;
147         unsigned int i;
148
149         if (ltdb_val_equal_case_insensitive(v1, v2) == 1) {
150                 return 1;
151         }
152
153         for (i=0;i<ltdb->cache->subclasses->num_elements;i++) {
154                 struct ldb_message_element *el = &ltdb->cache->subclasses->elements[i];
155                 if (ldb_attr_cmp(el->name, v2->data) == 0) {
156                         unsigned int j;
157                         for (j=0;j<el->num_values;j++) {
158                                 if (ltdb_val_equal_objectclass(module, v1, &el->values[j])) {
159                                         return 1;
160                                 }
161                         }
162                 }
163         }
164
165         return 0;
166 }
167                                      
168
169 /*
170   see if two ldb_val structures contain the same data
171   
172   v1 contains the in-database value, v2 contains the value
173   that the user gave
174   
175   return 1 for a match, 0 for a mis-match
176 */
177 int ltdb_val_equal(struct ldb_module *module,
178                   const char *attr_name,
179                   const struct ldb_val *v1, const struct ldb_val *v2)
180 {
181         int flags = ltdb_attribute_flags(module, attr_name);
182
183         if (flags & LTDB_FLAG_OBJECTCLASS) {
184                 return ltdb_val_equal_objectclass(module, v1, v2);
185         }
186
187         if (flags & LTDB_FLAG_INTEGER) {
188                 return ltdb_val_equal_integer(v1, v2);
189         }
190
191         if (flags & LTDB_FLAG_WILDCARD) {
192                 return ltdb_val_equal_wildcard(module, v1, v2, flags);
193         }
194
195         if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
196                 return ltdb_val_equal_case_insensitive(v1, v2);
197         }
198
199         if (v1->length != v2->length) return 0;
200
201         if (v1->length == 0) return 1;
202
203         if (memcmp(v1->data, v2->data, v1->length) == 0) {
204                 return 1;
205         }
206
207         return 0;
208 }
209
210 /*
211   check if the scope matches in a search result
212 */
213 static int scope_match(const char *dn, const char *base, enum ldb_scope scope)
214 {
215         size_t dn_len, base_len;
216
217         if (base == NULL) {
218                 return 1;
219         }
220
221         base_len = strlen(base);
222         dn_len = strlen(dn);
223
224         if (scope != LDB_SCOPE_ONELEVEL && ldb_dn_cmp(dn, base) == 0) {
225                 return 1;
226         }
227
228         if (base_len+1 >= dn_len) {
229                 return 0;
230         }
231
232         switch (scope) {
233         case LDB_SCOPE_BASE:
234                 break;
235
236         case LDB_SCOPE_ONELEVEL:
237                 if (ldb_dn_cmp(dn + (dn_len - base_len), base) == 0 &&
238                     dn[dn_len - base_len - 1] == ',' &&
239                     strchr(dn, ',') == &dn[dn_len - base_len - 1]) {
240                         return 1;
241                 }
242                 break;
243                 
244         case LDB_SCOPE_SUBTREE:
245         default:
246                 if (ldb_dn_cmp(dn + (dn_len - base_len), base) == 0 &&
247                     dn[dn_len - base_len - 1] == ',') {
248                         return 1;
249                 }
250                 break;
251         }
252
253         return 0;
254 }
255
256
257 /*
258   match a leaf node
259 */
260 static int match_leaf(struct ldb_module *module, 
261                       struct ldb_message *msg,
262                       struct ldb_parse_tree *tree,
263                       const char *base,
264                       enum ldb_scope scope)
265 {
266         unsigned int i, j;
267
268         if (!scope_match(msg->dn, base, scope)) {
269                 return 0;
270         }
271
272         if (ldb_attr_cmp(tree->u.simple.attr, "dn") == 0) {
273                 if (strcmp(tree->u.simple.value.data, "*") == 0) {
274                         return 1;
275                 }
276                 return ldb_dn_cmp(msg->dn, tree->u.simple.value.data) == 0;
277         }
278
279         for (i=0;i<msg->num_elements;i++) {
280                 if (ldb_attr_cmp(msg->elements[i].name, tree->u.simple.attr) == 0) {
281                         if (strcmp(tree->u.simple.value.data, "*") == 0) {
282                                 return 1;
283                         }
284                         for (j=0;j<msg->elements[i].num_values;j++) {
285                                 if (ltdb_val_equal(module, msg->elements[i].name,
286                                                   &msg->elements[i].values[j], 
287                                                   &tree->u.simple.value)) {
288                                         return 1;
289                                 }
290                         }
291                 }
292         }
293
294         return 0;
295 }
296
297 /*
298   return 0 if the given parse tree matches the given message. Assumes
299   the message is in sorted order
300
301   return 1 if it matches, and 0 if it doesn't match
302
303   this is a recursive function, and does short-circuit evaluation
304  */
305 int ltdb_message_match(struct ldb_module *module, 
306                       struct ldb_message *msg,
307                       struct ldb_parse_tree *tree,
308                       const char *base,
309                       enum ldb_scope scope)
310 {
311         unsigned int i;
312         int v;
313
314         switch (tree->operation) {
315         case LDB_OP_SIMPLE:
316                 break;
317
318         case LDB_OP_NOT:
319                 return ! ltdb_message_match(module, msg, tree->u.not.child, base, scope);
320
321         case LDB_OP_AND:
322                 for (i=0;i<tree->u.list.num_elements;i++) {
323                         v = ltdb_message_match(module, msg, tree->u.list.elements[i],
324                                               base, scope);
325                         if (!v) return 0;
326                 }
327                 return 1;
328
329         case LDB_OP_OR:
330                 for (i=0;i<tree->u.list.num_elements;i++) {
331                         v = ltdb_message_match(module, msg, tree->u.list.elements[i],
332                                               base, scope);
333                         if (v) return 1;
334                 }
335                 return 0;
336         }
337
338         return match_leaf(module, msg, tree, base, scope);
339 }