r9595: Add ldb map module
[samba.git] / source4 / lib / ldb / ldb_map / ldb_map.c
1 /* 
2    ldb database library - map backend
3
4    Copyright (C) Jelmer Vernooij 2005
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 #include "includes.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "lib/ldb/include/ldb_private.h"
28 #include "lib/ldb/ldb_map/ldb_map.h"
29
30 struct map_private {
31         struct ldb_map_mappings *mappings;
32 };
33
34 static struct ldb_dn *ldb_map_dn(struct ldb_module *module, const struct ldb_dn *dn)
35 {
36         /* FIXME */
37         return NULL;
38 }
39
40 static char *ldb_map_expression(struct ldb_module *module, const char *expr)
41 {
42         /* FIXME */
43         return NULL;
44 }
45
46 static const char **ldb_map_attrs(struct ldb_module *module, const char *const attrs[])
47 {
48         /* FIXME */
49         return NULL;
50 }
51
52 static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, const struct ldb_message *mi)
53 {
54         /* FIXME */
55         return NULL;
56 }
57
58 static struct ldb_message *ldb_map_message_outgoing(struct ldb_module *module, const struct ldb_message *mi)
59 {
60         /* FIXME */
61         return NULL;
62 }
63
64 /*
65   rename a record
66 */
67 static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
68 {
69         struct ldb_dn *n_olddn, *n_newdn;
70         int ret;
71         
72         n_olddn = ldb_map_dn(module, olddn);
73         n_newdn = ldb_map_dn(module, newdn);
74
75         ret = ldb_next_rename_record(module, n_olddn, n_newdn);
76
77         talloc_free(n_olddn);
78         talloc_free(n_newdn);
79         
80         return ret;
81 }
82
83 /*
84   delete a record
85 */
86 static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
87 {
88         struct ldb_dn *newdn;
89         int ret;
90
91         newdn = ldb_map_dn(module, dn);
92
93         ret = ldb_next_delete_record(module, newdn);
94
95         talloc_free(newdn);
96
97         return ret;
98 }
99
100
101 /*
102   search for matching records
103 */
104 static int map_search(struct ldb_module *module, const struct ldb_dn *base,
105                        enum ldb_scope scope, const char *expression,
106                        const char * const *attrs, struct ldb_message ***res)
107 {
108         char *newexpr;
109         int ret;
110         const char **newattrs;
111         struct ldb_dn *new_base;
112         struct ldb_message **newres;
113         int i;
114
115         newexpr = ldb_map_expression(module, expression);
116         newattrs = ldb_map_attrs(module, attrs); 
117         new_base = ldb_map_dn(module, base);
118
119         ret = ldb_next_search(module, new_base, scope, newexpr, newattrs, &newres);
120
121         talloc_free(new_base);
122         talloc_free(newexpr);
123         talloc_free(newattrs);
124
125         for (i = 0; i < ret; i++) {
126                 *res[i] = ldb_map_message_incoming(module, newres[i]);
127                 talloc_free(newres[i]);
128         }
129
130         return ret;
131 }
132
133 /*
134   add a record
135 */
136 static int map_add(struct ldb_module *module, const struct ldb_message *msg)
137 {
138         struct ldb_message *nmsg = ldb_map_message_outgoing(module, msg);
139         int ret;
140
141         ret = ldb_next_add_record(module, nmsg);
142
143         talloc_free(nmsg);
144
145         return ret;
146 }
147
148
149 /*
150   search for matching records using a ldb_parse_tree
151 */
152 static int map_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
153                               enum ldb_scope scope, struct ldb_parse_tree *tree,
154                               const char * const *attrs, struct ldb_message ***res)
155 {
156         struct map_private *privdat = module->private_data;
157         char *expression;
158         int ret;
159
160         expression = ldb_filter_from_tree(privdat, tree);
161         if (expression == NULL) {
162                 return -1;
163         }
164         ret = map_search(module, base, scope, expression, attrs, res);
165         talloc_free(expression);
166         return ret;
167 }
168
169 /*
170   modify a record
171 */
172 static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
173 {
174         struct ldb_message *nmsg = ldb_map_message_outgoing(module, msg);
175         int ret;
176
177         ret = ldb_next_modify_record(module, nmsg);
178
179         talloc_free(nmsg);
180
181         return ret;
182 }
183
184 static int map_lock(struct ldb_module *module, const char *lockname)
185 {
186         return ldb_next_named_lock(module, lockname);
187 }
188
189 static int map_unlock(struct ldb_module *module, const char *lockname)
190 {
191         return ldb_next_named_unlock(module, lockname);
192 }
193
194 /*
195   return extended error information
196 */
197 static const char *map_errstring(struct ldb_module *module)
198 {
199         return ldb_next_errstring(module);
200 }
201
202 static const struct ldb_module_ops map_ops = {
203         .name          = "map",
204         .search        = map_search,
205         .search_bytree = map_search_bytree,
206         .add_record    = map_add,
207         .modify_record = map_modify,
208         .delete_record = map_delete,
209         .rename_record = map_rename,
210         .named_lock    = map_lock,
211         .named_unlock  = map_unlock,
212         .errstring     = map_errstring
213 };
214
215 /* the init function */
216 struct ldb_module *ldb_map_init(struct ldb_context *ldb, struct ldb_map_mappings *mappings, const char *options[])
217 {
218         struct ldb_module *ctx;
219         struct map_private *data;
220
221         ctx = talloc(ldb, struct ldb_module);
222         if (!ctx)
223                 return NULL;
224
225         data = talloc(ctx, struct map_private);
226         if (!data) {
227                 talloc_free(ctx);
228                 return NULL;
229         }
230
231         data->mappings = mappings;
232         ctx->private_data = data;
233         ctx->ldb = ldb;
234         ctx->prev = ctx->next = NULL;
235         ctx->ops = &map_ops;
236
237         return ctx;
238 }