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