s4:registry - ldb.c - fix up a strange LDB filter
[sfrench/samba-autobuild/.git] / source4 / lib / registry / ldb.c
1 /*
2    Unix SMB/CIFS implementation.
3    Registry interface
4    Copyright (C) 2004-2007, Jelmer Vernooij, jelmer@samba.org
5    Copyright (C) 2008-2010, Matthias Dieter Wallnöfer, mdw@samba.org
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "registry.h"
23 #include "lib/ldb/include/ldb.h"
24 #include "lib/ldb/include/ldb_errors.h"
25 #include "ldb_wrap.h"
26 #include "librpc/gen_ndr/winreg.h"
27 #include "param/param.h"
28
29 static struct hive_operations reg_backend_ldb;
30
31 struct ldb_key_data
32 {
33         struct hive_key key;
34         struct ldb_context *ldb;
35         struct ldb_dn *dn;
36         struct ldb_message **subkeys, **values;
37         unsigned int subkey_count, value_count;
38 };
39
40 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
41                                  struct ldb_message *msg,
42                                  const char **name, uint32_t *type,
43                                  DATA_BLOB *data)
44 {
45         const struct ldb_val *val;
46         uint32_t value_type;
47
48         if (name != NULL) {
49                 *name = talloc_strdup(mem_ctx,
50                                       ldb_msg_find_attr_as_string(msg, "value",
51                                       NULL));
52         }
53
54         value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
55         *type = value_type;
56
57         val = ldb_msg_find_ldb_val(msg, "data");
58
59         switch (value_type)
60         {
61         case REG_SZ:
62         case REG_EXPAND_SZ:
63                 if (val != NULL) {
64                         convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16,
65                                                      val->data, val->length,
66                                                      (void **)&data->data, &data->length, false);
67                 } else {
68                         data->data = NULL;
69                         data->length = 0;
70                 }
71                 break;
72
73         case REG_DWORD:
74                 if (val != NULL) {
75                         uint32_t tmp = strtoul((char *)val->data, NULL, 0);
76                         data->data = talloc_size(mem_ctx, sizeof(uint32_t) + 1);
77                         if (data->data != NULL) {
78                                 SIVAL(data->data, 0, tmp);
79                         }
80                         data->length = sizeof(uint32_t);
81                 } else {
82                         data->data = NULL;
83                         data->length = 0;
84                 }
85                 break;
86
87         case REG_BINARY:
88         default:
89                 if (val != NULL) {
90                         data->data = talloc_memdup(mem_ctx, val->data,
91                                                    val->length);
92                         data->length = val->length;
93                 } else {
94                         data->data = NULL;
95                         data->length = 0;
96                 }
97                 break;
98         }
99 }
100
101 static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
102                                               TALLOC_CTX *mem_ctx,
103                                               const char *name,
104                                               uint32_t type, DATA_BLOB data)
105 {
106         struct ldb_message *msg;
107         char *name_dup, *type_str;
108         int ret;
109
110         msg = talloc_zero(mem_ctx, struct ldb_message);
111         if (msg == NULL) {
112                 return NULL;
113         }
114
115         name_dup = talloc_strdup(msg, name);
116         if (name_dup == NULL) {
117                 talloc_free(msg);
118                 return NULL;
119         }
120
121         ret = ldb_msg_add_string(msg, "value", name_dup);
122         if (ret != LDB_SUCCESS) {
123                 talloc_free(msg);
124                 return NULL;
125         }
126
127         switch (type) {
128         case REG_SZ:
129         case REG_EXPAND_SZ:
130                 if ((data.length > 0) && (data.data != NULL)
131                     && (data.data[0] != '\0')) {
132                         struct ldb_val *val;
133                         bool ret2;
134
135                         val = talloc_zero(msg, struct ldb_val);
136                         if (val == NULL) {
137                                 talloc_free(msg);
138                                 return NULL;
139                         }
140
141                         ret2 = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8,
142                                                      (void *)data.data, data.length,
143                                                      (void **)&val->data, &val->length,
144                                                      false);
145                         ret = ldb_msg_add_value(msg, "data", val, NULL);
146                 } else {
147                         ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
148                 }
149                 break;
150
151         case REG_DWORD:
152                 if ((data.length > 0) && (data.data != NULL)) {
153                         char *conv_str;
154
155                         conv_str = talloc_asprintf(msg, "0x%x", IVAL(data.data, 0));
156                         if (conv_str == NULL) {
157                                 talloc_free(msg);
158                                 return NULL;
159                         }
160
161                         ret = ldb_msg_add_string(msg, "data", conv_str);
162                 } else {
163                         ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
164                 }
165                 break;
166
167         case REG_BINARY:
168         default:
169                 if ((data.length > 0) && (data.data != NULL)
170                     && (data.data[0] != '\0')) {
171                         ret = ldb_msg_add_value(msg, "data", &data, NULL);
172                 } else {
173                         ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
174                 }
175                 break;
176         }
177
178         if (ret != LDB_SUCCESS) {
179                 talloc_free(msg);
180                 return NULL;
181         }
182
183         type_str = talloc_asprintf(mem_ctx, "%u", type);
184         if (type_str == NULL) {
185                 talloc_free(msg);
186                 return NULL;
187         }
188
189         ret = ldb_msg_add_string(msg, "type", type_str);
190         if (ret != LDB_SUCCESS) {
191                 talloc_free(msg);
192                 return NULL;
193         }
194
195         return msg;
196 }
197
198 static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value)
199 {
200         struct ldb_val val;
201
202         val.data = discard_const_p(uint8_t, value);
203         val.length = strlen(value);
204
205         return ldb_dn_escape_value(mem_ctx, val);
206 }
207
208 static int reg_close_ldb_key(struct ldb_key_data *key)
209 {
210         if (key->subkeys != NULL) {
211                 talloc_free(key->subkeys);
212                 key->subkeys = NULL;
213         }
214
215         if (key->values != NULL) {
216                 talloc_free(key->values);
217                 key->values = NULL;
218         }
219         return 0;
220 }
221
222 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
223                                       const struct hive_key *from,
224                                       const char *path, const char *add)
225 {
226         TALLOC_CTX *local_ctx;
227         struct ldb_dn *ret;
228         char *mypath = talloc_strdup(mem_ctx, path);
229         char *begin;
230         struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
231         struct ldb_context *ldb = kd->ldb;
232
233         local_ctx = talloc_new(mem_ctx);
234
235         ret = ldb_dn_new(mem_ctx, ldb, add);
236         if (!ldb_dn_validate(ret)) {
237                 talloc_free(ret);
238                 talloc_free(local_ctx);
239                 return NULL;
240         }
241
242         while (mypath) {
243                 char *keyname;
244
245                 begin = strrchr(mypath, '\\');
246
247                 if (begin) keyname = begin + 1;
248                 else keyname = mypath;
249
250                 if (keyname[0] != '\0') {
251                         if (!ldb_dn_add_base_fmt(ret, "key=%s",
252                                                  reg_ldb_escape(local_ctx,
253                                                                 keyname)))
254                         {
255                                 talloc_free(local_ctx);
256                                 return NULL;
257                         }
258                 }
259
260                 if(begin) {
261                         *begin = '\0';
262                 } else {
263                         break;
264                 }
265         }
266
267         ldb_dn_add_base(ret, kd->dn);
268
269         talloc_free(local_ctx);
270
271         return ret;
272 }
273
274 static WERROR cache_subkeys(struct ldb_key_data *kd)
275 {
276         struct ldb_context *c = kd->ldb;
277         struct ldb_result *res;
278         int ret;
279
280         ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL, NULL, "(key=*)");
281
282         if (ret != LDB_SUCCESS) {
283                 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
284                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
285                 return WERR_FOOBAR;
286         }
287
288         kd->subkey_count = res->count;
289         kd->subkeys = talloc_steal(kd, res->msgs);
290         talloc_free(res);
291
292         return WERR_OK;
293 }
294
295 static WERROR cache_values(struct ldb_key_data *kd)
296 {
297         struct ldb_context *c = kd->ldb;
298         struct ldb_result *res;
299         int ret;
300
301         ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
302                          NULL, "(value=*)");
303
304         if (ret != LDB_SUCCESS) {
305                 DEBUG(0, ("Error getting values for '%s': %s\n",
306                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
307                 return WERR_FOOBAR;
308         }
309
310         kd->value_count = res->count;
311         kd->values = talloc_steal(kd, res->msgs);
312         talloc_free(res);
313
314         return WERR_OK;
315 }
316
317
318 static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
319                                    const struct hive_key *k, uint32_t idx,
320                                    const char **name,
321                                    const char **classname,
322                                    NTTIME *last_mod_time)
323 {
324         struct ldb_message_element *el;
325         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
326
327         /* Initialization */
328         if (name != NULL)
329                 *name = NULL;
330         if (classname != NULL)
331                 *classname = NULL; /* TODO: Store properly */
332         if (last_mod_time != NULL)
333                 *last_mod_time = 0; /* TODO: we need to add this to the
334                                                 ldb backend properly */
335
336         /* Do a search if necessary */
337         if (kd->subkeys == NULL) {
338                 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
339         }
340
341         if (idx >= kd->subkey_count)
342                 return WERR_NO_MORE_ITEMS;
343
344         el = ldb_msg_find_element(kd->subkeys[idx], "key");
345         SMB_ASSERT(el != NULL);
346         SMB_ASSERT(el->num_values != 0);
347
348         if (name != NULL)
349                 *name = talloc_strdup(mem_ctx, (char *)el->values[0].data);
350
351         return WERR_OK;
352 }
353
354 static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
355                                   const char **name, uint32_t *data_type,
356                                    DATA_BLOB *data)
357 {
358         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
359         struct ldb_context *c = kd->ldb;
360         const char* attrs[] = { "data", "type", NULL };
361         struct ldb_result *res;
362         int ret;
363
364         ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs, "(key=*)");
365
366         if (ret != LDB_SUCCESS) {
367                 DEBUG(0, ("Error getting default value for '%s': %s\n",
368                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
369                 return WERR_FOOBAR;
370         }
371
372         if (res->count == 0 || res->msgs[0]->num_elements == 0)
373                 return WERR_BADFILE;
374
375         reg_ldb_unpack_value(mem_ctx,
376                  res->msgs[0], name, data_type, data);
377
378         talloc_free(res);
379
380         return WERR_OK;
381 }
382
383 static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
384                                   uint32_t idx, const char **name,
385                                   uint32_t *data_type, DATA_BLOB *data)
386 {
387         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
388
389         /* if default value exists, give it back */
390         if (W_ERROR_IS_OK(ldb_get_default_value(mem_ctx, k, name, data_type,
391                 data))) {
392                 if (idx == 0)
393                         return WERR_OK;
394                 else
395                         --idx;
396         }
397
398         /* Do the search if necessary */
399         if (kd->values == NULL) {
400                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
401         }
402
403         if (idx >= kd->value_count)
404                 return WERR_NO_MORE_ITEMS;
405
406         reg_ldb_unpack_value(mem_ctx, kd->values[idx], name, data_type, data);
407
408         return WERR_OK;
409 }
410
411 static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
412                             const char *name, uint32_t *data_type,
413                             DATA_BLOB *data)
414 {
415         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
416         struct ldb_context *c = kd->ldb;
417         struct ldb_result *res;
418         int ret;
419
420         if (name == NULL) {
421                 return WERR_INVALID_PARAM;
422         }
423
424         if (name[0] == '\0') {
425                 /* default value */
426                 return ldb_get_default_value(mem_ctx, k, NULL, data_type, data);
427         } else {
428                 /* normal value */
429                 ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_ONELEVEL,
430                                  NULL, "(value=%s)", name);
431
432                 if (ret != LDB_SUCCESS) {
433                         DEBUG(0, ("Error getting values for '%s': %s\n",
434                                 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
435                         return WERR_FOOBAR;
436                 }
437
438                 if (res->count == 0)
439                         return WERR_BADFILE;
440
441                 reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data);
442
443                 talloc_free(res);
444         }
445
446         return WERR_OK;
447 }
448
449 static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
450                            const char *name, struct hive_key **key)
451 {
452         struct ldb_result *res;
453         struct ldb_dn *ldap_path;
454         int ret;
455         struct ldb_key_data *newkd;
456         struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);
457         struct ldb_context *c = kd->ldb;
458
459         ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
460         W_ERROR_HAVE_NO_MEMORY(ldap_path);
461
462         ret = ldb_search(c, mem_ctx, &res, ldap_path, LDB_SCOPE_BASE, NULL, "(key=*)");
463
464         if (ret != LDB_SUCCESS) {
465                 DEBUG(3, ("Error opening key '%s': %s\n",
466                         ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
467                 return WERR_FOOBAR;
468         } else if (res->count == 0) {
469                 DEBUG(3, ("Key '%s' not found\n",
470                         ldb_dn_get_linearized(ldap_path)));
471                 talloc_free(res);
472                 return WERR_BADFILE;
473         }
474
475         newkd = talloc_zero(mem_ctx, struct ldb_key_data);
476         newkd->key.ops = &reg_backend_ldb;
477         newkd->ldb = talloc_reference(newkd, kd->ldb);
478         newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
479
480         *key = (struct hive_key *)newkd;
481
482         return WERR_OK;
483 }
484
485 WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
486                          struct auth_session_info *session_info,
487                          struct cli_credentials *credentials,
488                          struct tevent_context *ev_ctx,
489                          struct loadparm_context *lp_ctx,
490                          struct hive_key **k)
491 {
492         struct ldb_key_data *kd;
493         struct ldb_context *wrap;
494         struct ldb_message *attrs_msg;
495
496         if (location == NULL)
497                 return WERR_INVALID_PARAM;
498
499         wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx,
500                                 location, session_info, credentials, 0);
501
502         if (wrap == NULL) {
503                 DEBUG(1, (__FILE__": unable to connect\n"));
504                 return WERR_FOOBAR;
505         }
506
507         attrs_msg = ldb_msg_new(wrap);
508         W_ERROR_HAVE_NO_MEMORY(attrs_msg);
509         attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES");
510         W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn);
511         ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE");
512         ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE");
513
514         ldb_add(wrap, attrs_msg);
515
516         ldb_set_debug_stderr(wrap);
517
518         kd = talloc_zero(parent_ctx, struct ldb_key_data);
519         kd->key.ops = &reg_backend_ldb;
520         kd->ldb = talloc_reference(kd, wrap);
521         talloc_set_destructor (kd, reg_close_ldb_key);
522         kd->dn = ldb_dn_new(kd, wrap, "hive=NONE");
523
524         *k = (struct hive_key *)kd;
525
526         return WERR_OK;
527 }
528
529 static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
530                           const char *name, const char *classname,
531                           struct security_descriptor *sd,
532                           struct hive_key **newkey)
533 {
534         struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent);
535         struct ldb_message *msg;
536         struct ldb_key_data *newkd;
537         int ret;
538
539         msg = ldb_msg_new(mem_ctx);
540         W_ERROR_HAVE_NO_MEMORY(msg);
541
542         msg->dn = reg_path_to_ldb(msg, parent, name, NULL);
543         W_ERROR_HAVE_NO_MEMORY(msg->dn);
544
545         ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name));
546         if (classname != NULL)
547                 ldb_msg_add_string(msg, "classname",
548                                    talloc_strdup(mem_ctx, classname));
549
550         ret = ldb_add(parentkd->ldb, msg);
551         if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
552                 return WERR_ALREADY_EXISTS;
553         }
554
555         if (ret != LDB_SUCCESS) {
556                 DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb)));
557                 return WERR_FOOBAR;
558         }
559
560         DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn)));
561
562         newkd = talloc_zero(mem_ctx, struct ldb_key_data);
563         W_ERROR_HAVE_NO_MEMORY(newkd);
564         newkd->ldb = talloc_reference(newkd, parentkd->ldb);
565         newkd->key.ops = &reg_backend_ldb;
566         newkd->dn = talloc_steal(newkd, msg->dn);
567
568         *newkey = (struct hive_key *)newkd;
569
570         /* reset cache */
571         talloc_free(parentkd->subkeys);
572         parentkd->subkeys = NULL;
573
574         return WERR_OK;
575 }
576
577 static WERROR ldb_del_value (struct hive_key *key, const char *child)
578 {
579         int ret;
580         struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
581         TALLOC_CTX *mem_ctx;
582         struct ldb_message *msg;
583         struct ldb_dn *childdn;
584
585         if ((child == NULL) || (child[0] == '\0')) {
586                 /* default value */
587                 mem_ctx = talloc_init("ldb_del_value");
588
589                 msg = talloc_zero(mem_ctx, struct ldb_message);
590                 W_ERROR_HAVE_NO_MEMORY(msg);
591                 msg->dn = ldb_dn_copy(msg, kd->dn);
592                 W_ERROR_HAVE_NO_MEMORY(msg->dn);
593                 ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
594                 ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_DELETE, NULL);
595
596                 ret = ldb_modify(kd->ldb, msg);
597                 if (ret != LDB_SUCCESS) {
598                         DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
599                         talloc_free(mem_ctx);
600                         return WERR_FOOBAR;
601                 }
602
603                 talloc_free(mem_ctx);
604         } else {
605                 /* normal value */
606                 childdn = ldb_dn_copy(kd->ldb, kd->dn);
607                 if (!ldb_dn_add_child_fmt(childdn, "value=%s",
608                                   reg_ldb_escape(childdn, child)))
609                 {
610                         talloc_free(childdn);
611                         return WERR_FOOBAR;
612                 }
613
614                 ret = ldb_delete(kd->ldb, childdn);
615
616                 talloc_free(childdn);
617
618                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
619                         return WERR_BADFILE;
620                 } else if (ret != LDB_SUCCESS) {
621                         DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
622                         return WERR_FOOBAR;
623                 }
624         }
625
626         /* reset cache */
627         talloc_free(kd->values);
628         kd->values = NULL;
629
630         return WERR_OK;
631 }
632
633 static WERROR ldb_del_key(const struct hive_key *key, const char *name)
634 {
635         unsigned int i;
636         int ret;
637         struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
638         struct ldb_dn *ldap_path;
639         TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key");
640         struct ldb_context *c = parentkd->ldb;
641         struct ldb_result *res_keys;
642         struct ldb_result *res_vals;
643         WERROR werr;
644         struct hive_key *hk;
645
646         /* Verify key exists by opening it */
647         werr = ldb_open_key(mem_ctx, key, name, &hk);
648         if (!W_ERROR_IS_OK(werr)) {
649                 talloc_free(mem_ctx);
650                 return werr;
651         }
652
653         ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
654         W_ERROR_HAVE_NO_MEMORY(ldap_path);
655
656         /* Search for subkeys */
657         ret = ldb_search(c, mem_ctx, &res_keys, ldap_path, LDB_SCOPE_ONELEVEL,
658                          NULL, "(key=*)");
659
660         if (ret != LDB_SUCCESS) {
661                 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
662                       ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
663                 talloc_free(mem_ctx);
664                 return WERR_FOOBAR;
665         }
666
667         /* Search for values */
668         ret = ldb_search(c, mem_ctx, &res_vals, ldap_path, LDB_SCOPE_ONELEVEL,
669                          NULL, "(value=*)");
670
671         if (ret != LDB_SUCCESS) {
672                 DEBUG(0, ("Error getting values for '%s': %s\n",
673                       ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
674                 talloc_free(mem_ctx);
675                 return WERR_FOOBAR;
676         }
677
678         /* Start an explicit transaction */
679         ret = ldb_transaction_start(c);
680
681         if (ret != LDB_SUCCESS) {
682                 DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
683                 talloc_free(mem_ctx);
684                 return WERR_FOOBAR;
685         }
686
687         if (res_keys->count || res_vals->count)
688         {
689                 /* Delete any subkeys */
690                 for (i = 0; i < res_keys->count; i++)
691                 {
692                         werr = ldb_del_key(hk, ldb_msg_find_attr_as_string(
693                                                         res_keys->msgs[i],
694                                                         "key", NULL));
695                         if (!W_ERROR_IS_OK(werr)) {
696                                 ret = ldb_transaction_cancel(c);
697                                 talloc_free(mem_ctx);
698                                 return werr;
699                         }
700                 }
701
702                 /* Delete any values */
703                 for (i = 0; i < res_vals->count; i++)
704                 {
705                         werr = ldb_del_value(hk, ldb_msg_find_attr_as_string(
706                                                         res_vals->msgs[i],
707                                                         "value", NULL));
708                         if (!W_ERROR_IS_OK(werr)) {
709                                 ret = ldb_transaction_cancel(c);
710                                 talloc_free(mem_ctx);
711                                 return werr;
712                         }
713                 }
714         }
715
716         /* Delete the key itself */
717         ret = ldb_delete(c, ldap_path);
718
719         if (ret != LDB_SUCCESS)
720         {
721                 DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
722                 ret = ldb_transaction_cancel(c);
723                 talloc_free(mem_ctx);
724                 return WERR_FOOBAR;
725         }
726
727         /* Commit the transaction */
728         ret = ldb_transaction_commit(c);
729
730         if (ret != LDB_SUCCESS)
731         {
732                 DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
733                 ret = ldb_transaction_cancel(c);
734                 talloc_free(mem_ctx);
735                 return WERR_FOOBAR;
736         }
737
738         talloc_free(mem_ctx);
739
740         /* reset cache */
741         talloc_free(parentkd->subkeys);
742         parentkd->subkeys = NULL;
743
744         return WERR_OK;
745 }
746
747 static WERROR ldb_set_value(struct hive_key *parent,
748                             const char *name, uint32_t type,
749                             const DATA_BLOB data)
750 {
751         struct ldb_message *msg;
752         struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
753         unsigned int i;
754         int ret;
755         TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
756
757         msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
758         W_ERROR_HAVE_NO_MEMORY(msg);
759
760         msg->dn = ldb_dn_copy(msg, kd->dn);
761         W_ERROR_HAVE_NO_MEMORY(msg->dn);
762
763         if ((name != NULL) && (name[0] != '\0')) {
764                 /* For a default value, we add/overwrite the attributes to/of the hive.
765                    For a normal value, we create a new child. */
766                 if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
767                                   reg_ldb_escape(mem_ctx, name)))
768                 {
769                         talloc_free(mem_ctx);
770                         return WERR_FOOBAR;
771                 }
772         }
773
774         /* Try first a "modify" and if this doesn't work do try an "add" */
775         for (i = 0; i < msg->num_elements; i++) {
776                 if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) {
777                         msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
778                 }
779         }
780         ret = ldb_modify(kd->ldb, msg);
781         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
782                 i = 0;
783                 while (i < msg->num_elements) {
784                         if (msg->elements[i].flags == LDB_FLAG_MOD_DELETE) {
785                                 ldb_msg_remove_element(msg, &msg->elements[i]);
786                         } else {
787                                 ++i;
788                         }
789                 }
790                 ret = ldb_add(kd->ldb, msg);
791         }
792         if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
793                 /* ignore this -> the value didn't exist and also now doesn't */
794                 ret = LDB_SUCCESS;
795         }
796
797         if (ret != LDB_SUCCESS) {
798                 DEBUG(1, ("ldb_set_value: %s\n", ldb_errstring(kd->ldb)));
799                 talloc_free(mem_ctx);
800                 return WERR_FOOBAR;
801         }
802
803         /* reset cache */
804         talloc_free(kd->values);
805         kd->values = NULL;
806
807         talloc_free(mem_ctx);
808         return WERR_OK;
809 }
810
811 static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
812                                const struct hive_key *key,
813                                const char **classname,
814                                uint32_t *num_subkeys,
815                                uint32_t *num_values,
816                                NTTIME *last_change_time,
817                                uint32_t *max_subkeynamelen,
818                                uint32_t *max_valnamelen,
819                                uint32_t *max_valbufsize)
820 {
821         struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
822
823         /* Initialization */
824         if (classname != NULL)
825                 *classname = NULL;
826         if (num_subkeys != NULL)
827                 *num_subkeys = 0;
828         if (num_values != NULL)
829                 *num_values = 0;
830         if (last_change_time != NULL)
831                 *last_change_time = 0;
832         if (max_subkeynamelen != NULL)
833                 *max_subkeynamelen = 0;
834         if (max_valnamelen != NULL)
835                 *max_valnamelen = 0;
836         if (max_valbufsize != NULL)
837                 *max_valbufsize = 0;
838
839         if (kd->subkeys == NULL) {
840                 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
841         }
842
843         if (kd->values == NULL) {
844                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
845         }
846
847         if (num_subkeys != NULL) {
848                 *num_subkeys = kd->subkey_count;
849         }
850         if (num_values != NULL) {
851                 *num_values = kd->value_count;
852         }
853
854
855         if (max_subkeynamelen != NULL) {
856                 unsigned int i;
857                 struct ldb_message_element *el;
858
859                 *max_subkeynamelen = 0;
860
861                 for (i = 0; i < kd->subkey_count; i++) {
862                         el = ldb_msg_find_element(kd->subkeys[i], "key");
863                         *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length);
864                 }
865         }
866
867         if (max_valnamelen != NULL || max_valbufsize != NULL) {
868                 unsigned int i;
869                 struct ldb_message_element *el;
870                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
871
872                 if (max_valbufsize != NULL)
873                         *max_valbufsize = 0;
874
875                 if (max_valnamelen != NULL)
876                         *max_valnamelen = 0;
877
878                 for (i = 0; i < kd->value_count; i++) {
879                         if (max_valnamelen != NULL) {
880                                 el = ldb_msg_find_element(kd->values[i], "value");
881                                 *max_valnamelen = MAX(*max_valnamelen, el->values[0].length);
882                         }
883
884                         if (max_valbufsize != NULL) {
885                                 uint32_t data_type;
886                                 DATA_BLOB data;
887                                 reg_ldb_unpack_value(mem_ctx,
888                                                      kd->values[i], NULL,
889                                                      &data_type, &data);
890                                 *max_valbufsize = MAX(*max_valbufsize, data.length);
891                                 talloc_free(data.data);
892                         }
893                 }
894         }
895
896         return WERR_OK;
897 }
898
899 static struct hive_operations reg_backend_ldb = {
900         .name = "ldb",
901         .add_key = ldb_add_key,
902         .del_key = ldb_del_key,
903         .get_key_by_name = ldb_open_key,
904         .enum_value = ldb_get_value_by_id,
905         .enum_key = ldb_get_subkey_by_id,
906         .set_value = ldb_set_value,
907         .get_value_by_name = ldb_get_value,
908         .delete_value = ldb_del_value,
909         .get_key_info = ldb_get_key_info,
910 };