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