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