e755b7e4427ef34b65f14afc4c3db224f78f6c0a
[metze/samba/wip.git] / lib / ldb / ldb_map / ldb_map_outbound.c
1 /*
2    ldb database mapping module
3
4    Copyright (C) Jelmer Vernooij 2005
5    Copyright (C) Martin Kuehl <mkhl@samba.org> 2006
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
7    Copyright (C) Simo Sorce <idra@samba.org> 2008
8
9      ** NOTE! The following LGPL license applies to the ldb
10      ** library. This does NOT imply that all of Samba is released
11      ** under the LGPL
12    
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 3 of the License, or (at your option) any later version.
17
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, see <http://www.gnu.org/licenses/>.
25
26 */
27
28 #include "replace.h"
29 #include "system/filesys.h"
30 #include "system/time.h"
31 #include "ldb_map.h"
32 #include "ldb_map_private.h"
33
34
35 /* Mapping attributes
36  * ================== */
37
38 /* Select attributes that stay in the local partition. */
39 static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs)
40 {
41         const struct ldb_map_context *data = map_get_context(module);
42         const char **result;
43         unsigned int i, last;
44
45         if (attrs == NULL)
46                 return NULL;
47
48         last = 0;
49         result = talloc_array(mem_ctx, const char *, 1);
50         if (result == NULL) {
51                 goto failed;
52         }
53         result[0] = NULL;
54
55         for (i = 0; attrs[i]; i++) {
56                 /* Wildcards and ignored attributes are kept locally */
57                 if ((ldb_attr_cmp(attrs[i], "*") == 0) ||
58                     (!map_attr_check_remote(data, attrs[i]))) {
59                         result = talloc_realloc(mem_ctx, result, const char *, last+2);
60                         if (result == NULL) {
61                                 goto failed;
62                         }
63
64                         result[last] = talloc_strdup(result, attrs[i]);
65                         result[last+1] = NULL;
66                         last++;
67                 }
68         }
69
70         return result;
71
72 failed:
73         talloc_free(result);
74         map_oom(module);
75         return NULL;
76 }
77
78 /* Collect attributes that are mapped into the remote partition. */
79 static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, 
80                                              const char * const *attrs)
81 {
82         const struct ldb_map_context *data = map_get_context(module);
83         const char **result;
84         const struct ldb_map_attribute *map;
85         const char *name=NULL;
86         unsigned int i, j, last;
87         int ret;
88
89         last = 0;
90         result = talloc_array(mem_ctx, const char *, 1);
91         if (result == NULL) {
92                 goto failed;
93         }
94         result[0] = NULL;
95
96         for (i = 0; attrs[i]; i++) {
97                 /* Wildcards are kept remotely, too */
98                 if (ldb_attr_cmp(attrs[i], "*") == 0) {
99                         const char **new_attrs = NULL;
100                         ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs);
101                         if (ret != LDB_SUCCESS) {
102                                 goto failed;
103                         }
104                         ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes);
105                         if (ret != LDB_SUCCESS) {
106                                 goto failed;
107                         }
108
109                         attrs = new_attrs;
110                         break;
111                 }
112         }
113
114         for (i = 0; attrs[i]; i++) {
115                 /* Wildcards are kept remotely, too */
116                 if (ldb_attr_cmp(attrs[i], "*") == 0) {
117                         /* Add all 'include in wildcard' attributes */
118                         name = attrs[i];
119                         goto named;
120                 }
121
122                 /* Add remote names of mapped attrs */
123                 map = map_attr_find_local(data, attrs[i]);
124                 if (map == NULL) {
125                         continue;
126                 }
127
128                 switch (map->type) {
129                 case LDB_MAP_IGNORE:
130                         continue;
131
132                 case LDB_MAP_KEEP:
133                         name = attrs[i];
134                         goto named;
135
136                 case LDB_MAP_RENAME:
137                 case LDB_MAP_RENDROP:
138                 case LDB_MAP_CONVERT:
139                         name = map->u.rename.remote_name;
140                         goto named;
141
142                 case LDB_MAP_GENERATE:
143                         /* Add all remote names of "generate" attrs */
144                         for (j = 0; map->u.generate.remote_names[j]; j++) {
145                                 result = talloc_realloc(mem_ctx, result, const char *, last+2);
146                                 if (result == NULL) {
147                                         goto failed;
148                                 }
149
150                                 result[last] = talloc_strdup(result, map->u.generate.remote_names[j]);
151                                 result[last+1] = NULL;
152                                 last++;
153                         }
154                         continue;
155                 }
156
157         named:  /* We found a single remote name, add that */
158                 result = talloc_realloc(mem_ctx, result, const char *, last+2);
159                 if (result == NULL) {
160                         goto failed;
161                 }
162
163                 result[last] = talloc_strdup(result, name);
164                 result[last+1] = NULL;
165                 last++;
166         }
167
168         return result;
169
170 failed:
171         talloc_free(result);
172         map_oom(module);
173         return NULL;
174 }
175
176 /* Split attributes that stay in the local partition from those that
177  * are mapped into the remote partition. */
178 static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs)
179 {
180         *local_attrs = map_attrs_select_local(module, mem_ctx, attrs);
181         *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs);
182
183         return 0;
184 }
185
186 /* Mapping message elements
187  * ======================== */
188
189 /* Add an element to a message, overwriting any old identically named elements. */
190 static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el)
191 {
192         struct ldb_message_element *old;
193         int j;
194         old = ldb_msg_find_element(msg, el->name);
195
196         /* no local result, add as new element */
197         if (old == NULL) {
198                 if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) {
199                         return LDB_ERR_OPERATIONS_ERROR;
200                 }
201         }
202         else {
203                 talloc_free(old->values);
204         }
205
206         old->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
207         old->num_values = el->num_values;
208         if (old->values == NULL) {
209                 return LDB_ERR_OPERATIONS_ERROR;
210         }
211         /* copy the values into the element */
212         for (j=0;j<el->num_values;j++) {
213                 old->values[j] = ldb_val_dup(old->values, &el->values[j]);
214                 if (old->values[j].data == NULL && el->values[j].length != 0) {
215                         return LDB_ERR_OPERATIONS_ERROR;
216                 }
217         }
218
219         return 0;
220 }
221
222 /* Map a message element back into the local partition. */
223 static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, 
224                                                          void *mem_ctx, 
225                                                          const struct ldb_map_attribute *map, 
226                                                          const char *attr_name,
227                                                          const struct ldb_message_element *old)
228 {
229         const struct ldb_map_context *data = map_get_context(module);
230         const char *local_attr_name = attr_name;
231         struct ldb_message_element *el;
232         unsigned int i;
233
234         el = talloc_zero(mem_ctx, struct ldb_message_element);
235         if (el == NULL) {
236                 map_oom(module);
237                 return NULL;
238         }
239
240         el->values = talloc_array(el, struct ldb_val, old->num_values);
241         if (el->values == NULL) {
242                 talloc_free(el);
243                 map_oom(module);
244                 return NULL;
245         }
246
247         for (i = 0; data->attribute_maps[i].local_name; i++) {
248                 struct ldb_map_attribute *am = &data->attribute_maps[i];
249                 if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) &&
250                         !strcmp(am->u.rename.remote_name, attr_name))
251                     || (am->type == LDB_MAP_CONVERT &&
252                         !strcmp(am->u.convert.remote_name, attr_name))) {
253
254                         local_attr_name = am->local_name;
255                         break;
256                 }
257         }
258
259         el->name = talloc_strdup(el, local_attr_name);
260         if (el->name == NULL) {
261                 talloc_free(el);
262                 map_oom(module);
263                 return NULL;
264         }
265
266         for (i = 0; i < old->num_values; i++) {
267                 el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]);
268                 /* Conversions might fail, in which case bail */
269                 if (!el->values[i].data) {
270                         talloc_free(el);
271                         return NULL;
272                 }
273                 el->num_values++;
274         }
275
276         return el;
277 }
278
279 /* Merge a remote message element into a local message. */
280 static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, 
281                             struct ldb_message *remote, const char *attr_name)
282 {
283         const struct ldb_map_context *data = map_get_context(module);
284         const struct ldb_map_attribute *map;
285         struct ldb_message_element *old, *el=NULL;
286         const char *remote_name = NULL;
287         struct ldb_context *ldb;
288
289         ldb = ldb_module_get_ctx(module);
290
291         /* We handle wildcards in ldb_msg_el_merge_wildcard */
292         if (ldb_attr_cmp(attr_name, "*") == 0) {
293                 return LDB_SUCCESS;
294         }
295
296         map = map_attr_find_local(data, attr_name);
297
298         /* Unknown attribute in remote message:
299          * skip, attribute was probably auto-generated */
300         if (map == NULL) {
301                 return LDB_SUCCESS;
302         }
303
304         switch (map->type) {
305         case LDB_MAP_IGNORE:
306                 break;
307         case LDB_MAP_CONVERT:
308                 remote_name = map->u.convert.remote_name;
309                 break;
310         case LDB_MAP_KEEP:
311                 remote_name = attr_name;
312                 break;
313         case LDB_MAP_RENAME:
314         case LDB_MAP_RENDROP:
315                 remote_name = map->u.rename.remote_name;
316                 break;
317         case LDB_MAP_GENERATE:
318                 break;
319         }
320
321         switch (map->type) {
322         case LDB_MAP_IGNORE:
323                 return LDB_SUCCESS;
324
325         case LDB_MAP_CONVERT:
326                 if (map->u.convert.convert_remote == NULL) {
327                         ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
328                                   "Skipping attribute '%s': "
329                                   "'convert_remote' not set",
330                                   attr_name);
331                         return LDB_SUCCESS;
332                 }
333                 /* fall through */
334         case LDB_MAP_KEEP:
335         case LDB_MAP_RENAME:
336         case LDB_MAP_RENDROP:
337                 old = ldb_msg_find_element(remote, remote_name);
338                 if (old) {
339                         el = ldb_msg_el_map_remote(module, local, map, attr_name, old);
340                 } else {
341                         return LDB_ERR_NO_SUCH_ATTRIBUTE;
342                 }
343                 break;
344
345         case LDB_MAP_GENERATE:
346                 if (map->u.generate.generate_local == NULL) {
347                         ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
348                                   "Skipping attribute '%s': "
349                                   "'generate_local' not set",
350                                   attr_name);
351                         return LDB_SUCCESS;
352                 }
353
354                 el = map->u.generate.generate_local(module, local, attr_name, remote);
355                 if (!el) {
356                         /* Generation failure is probably due to lack of source attributes */
357                         return LDB_ERR_NO_SUCH_ATTRIBUTE;
358                 }
359                 break;
360         }
361
362         if (el == NULL) {
363                 return LDB_ERR_NO_SUCH_ATTRIBUTE;
364         }
365
366         return ldb_msg_replace(local, el);
367 }
368
369 /* Handle wildcard parts of merging a remote message element into a local message. */
370 static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, 
371                                      struct ldb_message *remote)
372 {
373         const struct ldb_map_context *data = map_get_context(module);
374         const struct ldb_map_attribute *map = map_attr_find_local(data, "*");
375         struct ldb_message_element *el=NULL;
376         unsigned int i;
377         int ret;
378
379         /* Perhaps we have a mapping for "*" */
380         if (map && map->type == LDB_MAP_KEEP) {
381                 /* We copy everything over, and hope that anything with a 
382                    more specific rule is overwritten */
383                 for (i = 0; i < remote->num_elements; i++) {
384                         el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name,
385                                                    &remote->elements[i]);
386                         if (el == NULL) {
387                                 return LDB_ERR_OPERATIONS_ERROR;
388                         }
389                         
390                         ret = ldb_msg_replace(local, el);
391                         if (ret) {
392                                 return ret;
393                         }
394                 }
395         }
396         
397         /* Now walk the list of possible mappings, and apply each */
398         for (i = 0; data->attribute_maps[i].local_name; i++) {
399                 ret = ldb_msg_el_merge(module, local, remote, 
400                                        data->attribute_maps[i].local_name);
401                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
402                         continue;
403                 } else if (ret) {
404                         return ret;
405                 } else {
406                         continue;
407                 }
408         }
409
410         return LDB_SUCCESS;
411 }
412
413 /* Mapping messages
414  * ================ */
415
416 /* Merge two local messages into a single one. */
417 static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2)
418 {
419         unsigned int i;
420         int ret;
421
422         for (i = 0; i < msg2->num_elements; i++) {
423                 ret = ldb_msg_replace(msg1, &msg2->elements[i]);
424                 if (ret) {
425                         return ret;
426                 }
427         }
428
429         return LDB_SUCCESS;
430 }
431
432 /* Merge a local and a remote message into a single local one. */
433 static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, 
434                                 struct ldb_message *remote)
435 {
436         unsigned int i;
437         int ret;
438         const char * const *attrs = ac->all_attrs;
439         if (!attrs) {
440                 ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);
441                 if (ret) {
442                         return ret;
443                 }
444         }
445
446         for (i = 0; attrs && attrs[i]; i++) {
447                 if (ldb_attr_cmp(attrs[i], "*") == 0) {
448                         ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);
449                         if (ret) {
450                                 return ret;
451                         }
452                         break;
453                 }
454         }
455
456         /* Try to map each attribute back;
457          * Add to local message is possible,
458          * Overwrite old local attribute if necessary */
459         for (i = 0; attrs && attrs[i]; i++) {
460                 ret = ldb_msg_el_merge(ac->module, local, remote, 
461                                        attrs[i]);
462                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
463                 } else if (ret) {
464                         return ret;
465                 }
466         }
467
468         return LDB_SUCCESS;
469 }
470
471 /* Mapping search results
472  * ====================== */
473
474 /* Map a search result back into the local partition. */
475 static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares)
476 {
477         struct ldb_message *msg;
478         struct ldb_dn *dn;
479         int ret;
480
481         /* There is no result message, skip */
482         if (ares->type != LDB_REPLY_ENTRY) {
483                 return 0;
484         }
485
486         /* Create a new result message */
487         msg = ldb_msg_new(ares);
488         if (msg == NULL) {
489                 map_oom(ac->module);
490                 return LDB_ERR_OPERATIONS_ERROR;
491         }
492
493         /* Merge remote message into new message */
494         ret = ldb_msg_merge_remote(ac, msg, ares->message);
495         if (ret) {
496                 talloc_free(msg);
497                 return ret;
498         }
499
500         /* Create corresponding local DN */
501         dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn);
502         if (dn == NULL) {
503                 talloc_free(msg);
504                 return LDB_ERR_OPERATIONS_ERROR;
505         }
506         msg->dn = dn;
507
508         /* Store new message with new DN as the result */
509         talloc_free(ares->message);
510         ares->message = msg;
511
512         return 0;
513 }
514
515 /* Mapping parse trees
516  * =================== */
517
518 /* Check whether a parse tree can safely be split in two. */
519 static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree)
520 {
521         const struct ldb_parse_tree *subtree = tree;
522         bool negate = false;
523
524         while (subtree) {
525                 switch (subtree->operation) {
526                 case LDB_OP_NOT:
527                         negate = !negate;
528                         subtree = subtree->u.isnot.child;
529                         continue;
530
531                 case LDB_OP_AND:
532                         return !negate; /* if negate: False */
533
534                 case LDB_OP_OR:
535                         return negate;  /* if negate: True */
536
537                 default:
538                         return true;    /* simple parse tree */
539                 }
540         }
541
542         return true;                    /* no parse tree */
543 }
544
545 /* Collect a list of attributes required to match a given parse tree. */
546 static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree)
547 {
548         const char **new_attrs;
549         unsigned int i;
550         int ret;
551
552         if (tree == NULL) {
553                 return 0;
554         }
555
556         switch (tree->operation) {
557         case LDB_OP_OR:
558         case LDB_OP_AND:                /* attributes stored in list of subtrees */
559                 for (i = 0; i < tree->u.list.num_elements; i++) {
560                         ret = ldb_parse_tree_collect_attrs(module, mem_ctx, 
561                                                            attrs, tree->u.list.elements[i]);
562                         if (ret) {
563                                 return ret;
564                         }
565                 }
566                 return 0;
567
568         case LDB_OP_NOT:                /* attributes stored in single subtree */
569                 return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child);
570
571         default:                        /* single attribute in tree */
572                 new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr);
573                 talloc_free(*attrs);
574                 *attrs = new_attrs;
575                 return 0;
576         }
577 }
578
579 static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree);
580
581 /* Select a negated subtree that queries attributes in the local partition */
582 static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
583 {
584         struct ldb_parse_tree *child;
585         int ret;
586
587         /* Prepare new tree */
588         *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
589         if (*new == NULL) {
590                 map_oom(module);
591                 return LDB_ERR_OPERATIONS_ERROR;
592         }
593
594         /* Generate new subtree */
595         ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child);
596         if (ret) {
597                 talloc_free(*new);
598                 return ret;
599         }
600
601         /* Prune tree without subtree */
602         if (child == NULL) {
603                 talloc_free(*new);
604                 *new = NULL;
605                 return 0;
606         }
607
608         (*new)->u.isnot.child = child;
609
610         return ret;
611 }
612
613 /* Select a list of subtrees that query attributes in the local partition */
614 static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
615 {
616         unsigned int i, j;
617         int ret=0;
618
619         /* Prepare new tree */
620         *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
621         if (*new == NULL) {
622                 map_oom(module);
623                 return LDB_ERR_OPERATIONS_ERROR;
624         }
625
626         /* Prepare list of subtrees */
627         (*new)->u.list.num_elements = 0;
628         (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements);
629         if ((*new)->u.list.elements == NULL) {
630                 map_oom(module);
631                 talloc_free(*new);
632                 return LDB_ERR_OPERATIONS_ERROR;
633         }
634
635         /* Generate new list of subtrees */
636         j = 0;
637         for (i = 0; i < tree->u.list.num_elements; i++) {
638                 struct ldb_parse_tree *child = NULL;
639                 ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]);
640                 if (ret) {
641                         talloc_free(*new);
642                         return ret;
643                 }
644
645                 if (child) {
646                         (*new)->u.list.elements[j] = child;
647                         j++;
648                 }
649         }
650
651         /* Prune tree without subtrees */
652         if (j == 0) {
653                 talloc_free(*new);
654                 *new = NULL;
655                 return 0;
656         }
657
658         /* Fix subtree list size */
659         (*new)->u.list.num_elements = j;
660         (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements);
661
662         return ret;
663 }
664
665 /* Select a simple subtree that queries attributes in the local partition */
666 static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
667 {
668         /* Prepare new tree */
669         *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
670         if (*new == NULL) {
671                 map_oom(module);
672                 return LDB_ERR_OPERATIONS_ERROR;
673         }
674
675         return 0;
676 }
677
678 /* Select subtrees that query attributes in the local partition */
679 static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
680 {
681         const struct ldb_map_context *data = map_get_context(module);
682
683         if (tree == NULL) {
684                 return 0;
685         }
686
687         if (tree->operation == LDB_OP_NOT) {
688                 return map_subtree_select_local_not(module, mem_ctx, new, tree);
689         }
690
691         if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) {
692                 return map_subtree_select_local_list(module, mem_ctx, new, tree);
693         }
694
695         if (map_attr_check_remote(data, tree->u.equality.attr)) {
696                 *new = NULL;
697                 return 0;
698         }
699
700         return map_subtree_select_local_simple(module, mem_ctx, new, tree);
701 }
702
703 static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree);
704
705 /* Collect a negated subtree that queries attributes in the remote partition */
706 static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
707 {
708         struct ldb_parse_tree *child;
709         int ret;
710
711         /* Prepare new tree */
712         *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
713         if (*new == NULL) {
714                 map_oom(module);
715                 return LDB_ERR_OPERATIONS_ERROR;
716         }
717
718         /* Generate new subtree */
719         ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child);
720         if (ret) {
721                 talloc_free(*new);
722                 return ret;
723         }
724
725         /* Prune tree without subtree */
726         if (child == NULL) {
727                 talloc_free(*new);
728                 *new = NULL;
729                 return 0;
730         }
731
732         (*new)->u.isnot.child = child;
733
734         return ret;
735 }
736
737 /* Collect a list of subtrees that query attributes in the remote partition */
738 static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
739 {
740         unsigned int i, j;
741         int ret=0;
742
743         /* Prepare new tree */
744         *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
745         if (*new == NULL) {
746                 map_oom(module);
747                 return LDB_ERR_OPERATIONS_ERROR;
748         }
749
750         /* Prepare list of subtrees */
751         (*new)->u.list.num_elements = 0;
752         (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements);
753         if ((*new)->u.list.elements == NULL) {
754                 map_oom(module);
755                 talloc_free(*new);
756                 return LDB_ERR_OPERATIONS_ERROR;
757         }
758
759         /* Generate new list of subtrees */
760         j = 0;
761         for (i = 0; i < tree->u.list.num_elements; i++) {
762                 struct ldb_parse_tree *child;
763                 ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]);
764                 if (ret) {
765                         talloc_free(*new);
766                         return ret;
767                 }
768
769                 if (child) {
770                         (*new)->u.list.elements[j] = child;
771                         j++;
772                 }
773         }
774
775         /* Prune tree without subtrees */
776         if (j == 0) {
777                 talloc_free(*new);
778                 *new = NULL;
779                 return 0;
780         }
781
782         /* Fix subtree list size */
783         (*new)->u.list.num_elements = j;
784         (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements);
785
786         return ret;
787 }
788
789 /* Collect a simple subtree that queries attributes in the remote partition */
790 int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map)
791 {
792         const char *attr;
793
794         /* Prepare new tree */
795         *new = talloc(mem_ctx, struct ldb_parse_tree);
796         if (*new == NULL) {
797                 map_oom(module);
798                 return LDB_ERR_OPERATIONS_ERROR;
799         }
800         **new = *tree;
801         
802         if (map->type == LDB_MAP_KEEP) {
803                 /* Nothing to do here */
804                 return 0;
805         }
806
807         /* Store attribute and value in new tree */
808         switch (tree->operation) {
809         case LDB_OP_PRESENT:
810                 attr = map_attr_map_local(*new, map, tree->u.present.attr);
811                 (*new)->u.present.attr = attr;
812                 break;
813         case LDB_OP_SUBSTRING:
814         {
815                 attr = map_attr_map_local(*new, map, tree->u.substring.attr);
816                 (*new)->u.substring.attr = attr;
817                 break;
818         }
819         case LDB_OP_EQUALITY:
820                 attr = map_attr_map_local(*new, map, tree->u.equality.attr);
821                 (*new)->u.equality.attr = attr;
822                 break;
823         case LDB_OP_LESS:
824         case LDB_OP_GREATER:
825         case LDB_OP_APPROX:
826                 attr = map_attr_map_local(*new, map, tree->u.comparison.attr);
827                 (*new)->u.comparison.attr = attr;
828                 break;
829         case LDB_OP_EXTENDED:
830                 attr = map_attr_map_local(*new, map, tree->u.extended.attr);
831                 (*new)->u.extended.attr = attr;
832                 break;
833         default:                        /* unknown kind of simple subtree */
834                 talloc_free(*new);
835                 return LDB_ERR_OPERATIONS_ERROR;
836         }
837
838         if (attr == NULL) {
839                 talloc_free(*new);
840                 *new = NULL;
841                 return 0;
842         }
843
844         if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) {
845                 /* Nothing more to do here, the attribute has been renamed */
846                 return 0;
847         }
848
849         /* Store attribute and value in new tree */
850         switch (tree->operation) {
851         case LDB_OP_PRESENT:
852                 break;
853         case LDB_OP_SUBSTRING:
854         {
855                 int i;
856                 /* Map value */
857                 (*new)->u.substring.chunks = NULL;
858                 for (i=0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) {
859                         (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2);
860                         if (!(*new)->u.substring.chunks) {
861                                 talloc_free(*new);
862                                 *new = NULL;
863                                 return 0;
864                         }
865                         (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val);
866                         if (!(*new)->u.substring.chunks[i]) {
867                                 talloc_free(*new);
868                                 *new = NULL;
869                                 return 0;
870                         }
871                         *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]);
872                         (*new)->u.substring.chunks[i+1] = NULL;
873                 }
874                 break;
875         }
876         case LDB_OP_EQUALITY:
877                 (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value);
878                 break;
879         case LDB_OP_LESS:
880         case LDB_OP_GREATER:
881         case LDB_OP_APPROX:
882                 (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value);
883                 break;
884         case LDB_OP_EXTENDED:
885                 (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value);
886                 (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id);
887                 break;
888         default:                        /* unknown kind of simple subtree */
889                 talloc_free(*new);
890                 return LDB_ERR_OPERATIONS_ERROR;
891         }
892
893         return 0;
894 }
895
896 /* Collect subtrees that query attributes in the remote partition */
897 static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree)
898 {
899         const struct ldb_map_context *data = map_get_context(module);
900         const struct ldb_map_attribute *map;
901         struct ldb_context *ldb;
902
903         ldb = ldb_module_get_ctx(module);
904
905         if (tree == NULL) {
906                 return 0;
907         }
908
909         if (tree->operation == LDB_OP_NOT) {
910                 return map_subtree_collect_remote_not(module, mem_ctx, new, tree);
911         }
912
913         if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) {
914                 return map_subtree_collect_remote_list(module, mem_ctx, new, tree);
915         }
916
917         if (!map_attr_check_remote(data, tree->u.equality.attr)) {
918                 *new = NULL;
919                 return 0;
920         }
921
922         map = map_attr_find_local(data, tree->u.equality.attr);
923         if (map->convert_operator) {
924                 return map->convert_operator(module, mem_ctx, new, tree);
925         }
926
927         if (map->type == LDB_MAP_GENERATE) {
928                 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
929                           "Skipping attribute '%s': "
930                           "'convert_operator' not set",
931                           tree->u.equality.attr);
932                 *new = NULL;
933                 return 0;
934         }
935
936         return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map);
937 }
938
939 /* Split subtrees that query attributes in the local partition from
940  * those that query the remote partition. */
941 static int ldb_parse_tree_partition(struct ldb_module *module,
942                                         void *mem_ctx,
943                                         struct ldb_parse_tree **local_tree,
944                                         struct ldb_parse_tree **remote_tree,
945                                         const struct ldb_parse_tree *tree)
946 {
947         int ret;
948
949         *local_tree = NULL;
950         *remote_tree = NULL;
951
952         /* No original tree */
953         if (tree == NULL) {
954                 return 0;
955         }
956
957         /* Generate local tree */
958         ret = map_subtree_select_local(module, mem_ctx, local_tree, tree);
959         if (ret) {
960                 return ret;
961         }
962
963         /* Generate remote tree */
964         ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree);
965         if (ret) {
966                 talloc_free(*local_tree);
967                 return ret;
968         }
969
970         return 0;
971 }
972
973 /* Collect a list of attributes required either explicitly from a
974  * given list or implicitly  from a given parse tree; split the
975  * collected list into local and remote parts. */
976 static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac,
977                                            const char * const *search_attrs, 
978                                            const struct ldb_parse_tree *tree)
979 {
980         void *tmp_ctx;
981         const char **tree_attrs;
982         const char **remote_attrs;
983         const char **local_attrs;
984         int ret;
985
986         /* There is no tree, just partition the searched attributes */
987         if (tree == NULL) {
988                 ret = map_attrs_partition(module, ac, 
989                                           &local_attrs, &remote_attrs, search_attrs);
990                 if (ret == 0) {
991                         ac->local_attrs = local_attrs;
992                         ac->remote_attrs = remote_attrs;
993                         ac->all_attrs = search_attrs;
994                 }
995                 return ret; 
996         }
997
998         /* Create context for temporary memory */
999         tmp_ctx = talloc_new(ac);
1000         if (tmp_ctx == NULL) {
1001                 goto oom;
1002         }
1003
1004         /* Prepare list of attributes from tree */
1005         tree_attrs = talloc_array(tmp_ctx, const char *, 1);
1006         if (tree_attrs == NULL) {
1007                 talloc_free(tmp_ctx);
1008                 goto oom;
1009         }
1010         tree_attrs[0] = NULL;
1011
1012         /* Collect attributes from tree */
1013         ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree);
1014         if (ret) {
1015                 goto done;
1016         }
1017
1018         /* Merge attributes from search operation */
1019         ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs);
1020         if (ret) {
1021                 goto done;
1022         }
1023
1024         /* Split local from remote attributes */
1025         ret = map_attrs_partition(module, ac, &local_attrs, 
1026                                   &remote_attrs, tree_attrs);
1027         
1028         if (ret == 0) {
1029                 ac->local_attrs = local_attrs;
1030                 ac->remote_attrs = remote_attrs;
1031                 talloc_steal(ac, tree_attrs);
1032                 ac->all_attrs = tree_attrs;
1033         }
1034 done:
1035         /* Free temporary memory */
1036         talloc_free(tmp_ctx);
1037         return ret;
1038
1039 oom:
1040         map_oom(module);
1041         return LDB_ERR_OPERATIONS_ERROR;
1042 }
1043
1044
1045 /* Outbound requests: search
1046  * ========================= */
1047
1048 static int map_remote_search_callback(struct ldb_request *req,
1049                                         struct ldb_reply *ares);
1050 static int map_local_merge_callback(struct ldb_request *req,
1051                                         struct ldb_reply *ares);
1052 static int map_search_local(struct map_context *ac);
1053
1054 static int map_save_entry(struct map_context *ac, struct ldb_reply *ares)
1055 {
1056         struct map_reply *mr;
1057
1058         mr = talloc_zero(ac, struct map_reply);
1059         if (mr == NULL) {
1060                 map_oom(ac->module);
1061                 return LDB_ERR_OPERATIONS_ERROR;
1062         }
1063         mr->remote = talloc_steal(mr, ares);
1064         if (ac->r_current) {
1065                 ac->r_current->next = mr;
1066         } else {
1067                 /* first entry */
1068                 ac->r_list = mr;
1069         }
1070         ac->r_current = mr;
1071
1072         return LDB_SUCCESS;
1073 }
1074
1075 /* Pass a merged search result up the callback chain. */
1076 int map_return_entry(struct map_context *ac, struct ldb_reply *ares)
1077 {
1078         struct ldb_message_element *el;
1079         const char * const *attrs;
1080         struct ldb_context *ldb;
1081         unsigned int i;
1082         int ret;
1083         bool matched;
1084
1085         ldb = ldb_module_get_ctx(ac->module);
1086
1087         /* Merged result doesn't match original query, skip */
1088         ret = ldb_match_msg_error(ldb, ares->message,
1089                                   ac->req->op.search.tree,
1090                                   ac->req->op.search.base,
1091                                   ac->req->op.search.scope,
1092                                   &matched);
1093         if (ret != LDB_SUCCESS) return ret;
1094         if (!matched) {
1095                 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "
1096                           "Skipping record '%s': "
1097                           "doesn't match original search",
1098                           ldb_dn_get_linearized(ares->message->dn));
1099                 return LDB_SUCCESS;
1100         }
1101
1102         /* Limit result to requested attrs */
1103         if (ac->req->op.search.attrs &&
1104             (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) {
1105
1106                 attrs = ac->req->op.search.attrs;
1107                 i = 0;
1108
1109                 while (i < ares->message->num_elements) {
1110
1111                         el = &ares->message->elements[i];
1112                         if ( ! ldb_attr_in_list(attrs, el->name)) {
1113                                 ldb_msg_remove_element(ares->message, el);
1114                         } else {
1115                                 i++;
1116                         }
1117                 }
1118         }
1119
1120         return ldb_module_send_entry(ac->req, ares->message, ares->controls);
1121 }
1122
1123 /* Search a record. */
1124 int ldb_map_search(struct ldb_module *module, struct ldb_request *req)
1125 {
1126         struct ldb_parse_tree *remote_tree;
1127         struct ldb_parse_tree *local_tree;
1128         struct ldb_request *remote_req;
1129         struct ldb_context *ldb;
1130         struct map_context *ac;
1131         int ret;
1132
1133         const char *wildcard[] = { "*", NULL };
1134         const char * const *attrs;
1135
1136         ldb = ldb_module_get_ctx(module);
1137
1138         /* if we're not yet initialized, go to the next module */
1139         if (!ldb_module_get_private(module))
1140                 return ldb_next_request(module, req);
1141
1142         /* Do not manipulate our control entries */
1143         if (ldb_dn_is_special(req->op.search.base)) {
1144                 return ldb_next_request(module, req);
1145         }
1146
1147         /* No mapping requested, skip to next module */
1148         if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) {
1149                 return ldb_next_request(module, req);
1150         }
1151
1152         /* TODO: How can we be sure about which partition we are
1153          *       targetting when there is no search base? */
1154
1155         /* Prepare context and handle */
1156         ac = map_init_context(module, req);
1157         if (ac == NULL) {
1158                 return LDB_ERR_OPERATIONS_ERROR;
1159         }
1160
1161         /* It is easier to deal with the two different ways of
1162          * expressing the wildcard in the same codepath */
1163         attrs = req->op.search.attrs;
1164         if (attrs == NULL) {
1165                 attrs = wildcard;
1166         }
1167
1168         /* Split local from remote attrs */
1169         ret = map_attrs_collect_and_partition(module, ac, 
1170                                               attrs, req->op.search.tree);
1171         if (ret) {
1172                 return LDB_ERR_OPERATIONS_ERROR;
1173         }
1174
1175         /* Split local from remote tree */
1176         ret = ldb_parse_tree_partition(module, ac,
1177                                        &local_tree, &remote_tree,
1178                                        req->op.search.tree);
1179         if (ret) {
1180                 return LDB_ERR_OPERATIONS_ERROR;
1181         }
1182
1183         if (((local_tree != NULL) && (remote_tree != NULL)) &&
1184             (!ldb_parse_tree_check_splittable(req->op.search.tree))) {
1185                 /* The query can't safely be split, enumerate the remote partition */
1186                 local_tree = NULL;
1187                 remote_tree = NULL;
1188         }
1189
1190         if (local_tree == NULL) {
1191                 /* Construct default local parse tree */
1192                 local_tree = talloc_zero(ac, struct ldb_parse_tree);
1193                 if (local_tree == NULL) {
1194                         map_oom(ac->module);
1195                         return LDB_ERR_OPERATIONS_ERROR;
1196                 }
1197
1198                 local_tree->operation = LDB_OP_PRESENT;
1199                 local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED);
1200         }
1201         if (remote_tree == NULL) {
1202                 /* Construct default remote parse tree */
1203                 remote_tree = ldb_parse_tree(ac, NULL);
1204                 if (remote_tree == NULL) {
1205                         return LDB_ERR_OPERATIONS_ERROR;
1206                 }
1207         }
1208
1209         ac->local_tree = local_tree;
1210
1211         /* Prepare the remote operation */
1212         ret = ldb_build_search_req_ex(&remote_req, ldb, ac,
1213                                       req->op.search.base,
1214                                       req->op.search.scope,
1215                                       remote_tree,
1216                                       ac->remote_attrs,
1217                                       req->controls,
1218                                       ac, map_remote_search_callback,
1219                                       req);
1220         LDB_REQ_SET_LOCATION(remote_req);
1221         if (ret != LDB_SUCCESS) {
1222                 return LDB_ERR_OPERATIONS_ERROR;
1223         }
1224
1225         return ldb_next_remote_request(module, remote_req);
1226 }
1227
1228 /* Now, search the local part of a remote search result. */
1229 static int map_remote_search_callback(struct ldb_request *req,
1230                                         struct ldb_reply *ares)
1231 {
1232         struct map_context *ac;
1233         int ret;
1234
1235         ac = talloc_get_type(req->context, struct map_context);
1236
1237         if (!ares) {
1238                 return ldb_module_done(ac->req, NULL, NULL,
1239                                         LDB_ERR_OPERATIONS_ERROR);
1240         }
1241         if (ares->error != LDB_SUCCESS) {
1242                 return ldb_module_done(ac->req, ares->controls,
1243                                         ares->response, ares->error);
1244         }
1245
1246         switch (ares->type) {
1247         case LDB_REPLY_REFERRAL:
1248
1249                 /* ignore referrals */
1250                 talloc_free(ares);
1251                 return LDB_SUCCESS;
1252
1253         case LDB_REPLY_ENTRY:
1254
1255                 /* Map result record into a local message */
1256                 ret = map_reply_remote(ac, ares);
1257                 if (ret) {
1258                         talloc_free(ares);
1259                         return ldb_module_done(ac->req, NULL, NULL,
1260                                                 LDB_ERR_OPERATIONS_ERROR);
1261                 }
1262
1263                 /* if we have no local db, then we can just return the reply to
1264                  * the upper layer, otherwise we must save it and process it
1265                  * when all replies ahve been gathered */
1266                 if ( ! map_check_local_db(ac->module)) {
1267                         ret = map_return_entry(ac, ares);
1268                 } else {
1269                         ret = map_save_entry(ac,ares);
1270                 }
1271
1272                 if (ret != LDB_SUCCESS) {
1273                         talloc_free(ares);
1274                         return ldb_module_done(ac->req, NULL, NULL, ret);
1275                 }
1276                 break;
1277
1278         case LDB_REPLY_DONE:
1279
1280                 if ( ! map_check_local_db(ac->module)) {
1281                         return ldb_module_done(ac->req, ares->controls,
1282                                                 ares->response, LDB_SUCCESS);
1283                 }
1284
1285                 /* reset the pointer to the start of the list */
1286                 ac->r_current = ac->r_list;
1287
1288                 /* no entry just return */
1289                 if (ac->r_current == NULL) {
1290                         ret = ldb_module_done(ac->req, ares->controls,
1291                                                 ares->response, LDB_SUCCESS);
1292                         talloc_free(ares);
1293                         return ret;
1294                 }
1295
1296                 ac->remote_done_ares = talloc_steal(ac, ares);
1297
1298                 ret = map_search_local(ac);
1299                 if (ret != LDB_SUCCESS) {
1300                         return ldb_module_done(ac->req, NULL, NULL, ret);
1301                 }
1302         }
1303
1304         return LDB_SUCCESS;
1305 }
1306
1307 static int map_search_local(struct map_context *ac)
1308 {
1309         struct ldb_request *search_req;
1310
1311         if (ac->r_current == NULL || ac->r_current->remote == NULL) {
1312                 return LDB_ERR_OPERATIONS_ERROR;
1313         }
1314
1315         /* Prepare local search request */
1316         /* TODO: use GUIDs here instead? */
1317         search_req = map_search_base_req(ac,
1318                                          ac->r_current->remote->message->dn,
1319                                          NULL, NULL,
1320                                          ac, map_local_merge_callback);
1321         if (search_req == NULL) {
1322                 return LDB_ERR_OPERATIONS_ERROR;
1323         }
1324
1325         return ldb_next_request(ac->module, search_req);
1326 }
1327
1328 /* Merge the remote and local parts of a search result. */
1329 int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares)
1330 {
1331         struct ldb_context *ldb;
1332         struct map_context *ac;
1333         int ret;
1334
1335         ac = talloc_get_type(req->context, struct map_context);
1336         ldb = ldb_module_get_ctx(ac->module);
1337
1338         if (!ares) {
1339                 return ldb_module_done(ac->req, NULL, NULL,
1340                                         LDB_ERR_OPERATIONS_ERROR);
1341         }
1342         if (ares->error != LDB_SUCCESS) {
1343                 return ldb_module_done(ac->req, ares->controls,
1344                                         ares->response, ares->error);
1345         }
1346
1347         switch (ares->type) {
1348         case LDB_REPLY_ENTRY:
1349                 /* We have already found a local record */
1350                 if (ac->r_current->local) {
1351                         talloc_free(ares);
1352                         ldb_set_errstring(ldb, "ldb_map: Too many results!");
1353                         return ldb_module_done(ac->req, NULL, NULL,
1354                                                 LDB_ERR_OPERATIONS_ERROR);
1355                 }
1356
1357                 /* Store local result */
1358                 ac->r_current->local = talloc_steal(ac->r_current, ares);
1359
1360                 break;
1361
1362         case LDB_REPLY_REFERRAL:
1363                 /* ignore referrals */
1364                 talloc_free(ares);
1365                 break;
1366
1367         case LDB_REPLY_DONE:
1368                 /* We don't need the local 'ares', but we will use the remote one from below */
1369                 talloc_free(ares);
1370
1371                 /* No local record found, map and send remote record */
1372                 if (ac->r_current->local != NULL) {
1373                         /* Merge remote into local message */
1374                         ret = ldb_msg_merge_local(ac->module,
1375                                                   ac->r_current->local->message,
1376                                                   ac->r_current->remote->message);
1377                         if (ret == LDB_SUCCESS) {
1378                                 ret = map_return_entry(ac, ac->r_current->local);
1379                         }
1380                         if (ret != LDB_SUCCESS) {
1381                                 return ldb_module_done(ac->req, NULL, NULL,
1382                                                         LDB_ERR_OPERATIONS_ERROR);
1383                         }
1384                 } else {
1385                         ret = map_return_entry(ac, ac->r_current->remote);
1386                         if (ret != LDB_SUCCESS) {
1387                                 return ldb_module_done(ac->req,
1388                                                         NULL, NULL, ret);
1389                         }
1390                 }
1391
1392                 if (ac->r_current->next != NULL) {
1393                         ac->r_current = ac->r_current->next;
1394                         if (ac->r_current->remote->type == LDB_REPLY_ENTRY) {
1395                                 ret = map_search_local(ac);
1396                                 if (ret != LDB_SUCCESS) {
1397                                         return ldb_module_done(ac->req,
1398                                                                NULL, NULL, ret);
1399                                 }
1400                                 break;
1401                         }
1402                 }
1403
1404                 /* ok we are done with all search, finally it is time to
1405                  * finish operations for this module */
1406                 return ldb_module_done(ac->req,
1407                                         ac->remote_done_ares->controls,
1408                                         ac->remote_done_ares->response,
1409                                         ac->remote_done_ares->error);
1410         }
1411
1412         return LDB_SUCCESS;
1413 }