reg_ldb_unpack_value: Change "CH_UTF8" in "CH_UNIX"
[Samba/gbeck.git] / source4 / lib / registry / ldb.c
blob18054ac89b6cd19f39c4fe7351927f26923c798e
1 /*
2 Unix SMB/CIFS implementation.
3 Registry interface
4 Copyright (C) Jelmer Vernooij 2004-2007.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "registry.h"
22 #include "lib/ldb/include/ldb.h"
23 #include "lib/ldb/include/ldb_errors.h"
24 #include "ldb_wrap.h"
25 #include "librpc/gen_ndr/winreg.h"
26 #include "param/param.h"
28 static struct hive_operations reg_backend_ldb;
30 struct ldb_key_data
32 struct hive_key key;
33 struct ldb_context *ldb;
34 struct ldb_dn *dn;
35 struct ldb_message **subkeys, **values;
36 int subkey_count, value_count;
39 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
40 struct smb_iconv_convenience *iconv_convenience,
41 struct ldb_message *msg,
42 const char **name, uint32_t *type,
43 DATA_BLOB *data)
45 const struct ldb_val *val;
46 uint32_t value_type;
48 if (name != NULL)
49 *name = talloc_strdup(mem_ctx,
50 ldb_msg_find_attr_as_string(msg, "value",
51 NULL));
53 value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
54 if (type != NULL)
55 *type = value_type;
56 val = ldb_msg_find_ldb_val(msg, "data");
58 switch (value_type)
60 case REG_SZ:
61 case REG_EXPAND_SZ:
62 data->length = convert_string_talloc(mem_ctx, iconv_convenience, CH_UNIX, CH_UTF16,
63 val->data, val->length,
64 (void **)&data->data);
65 break;
67 case REG_BINARY:
68 if (val)
69 *data = strhex_to_data_blob((char *)val->data);
70 else {
71 data->data = NULL;
72 data->length = 0;
74 break;
76 case REG_DWORD: {
77 uint32_t tmp = strtoul((char *)val->data, NULL, 0);
78 *data = data_blob_talloc(mem_ctx, &tmp, 4);
80 break;
82 default:
83 *data = data_blob_talloc(mem_ctx, val->data, val->length);
84 break;
88 static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
89 TALLOC_CTX *mem_ctx,
90 const char *name,
91 uint32_t type, DATA_BLOB data)
93 struct ldb_val val;
94 struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message);
95 char *type_s;
97 ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name));
99 switch (type) {
100 case REG_SZ:
101 case REG_EXPAND_SZ:
102 val.length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX,
103 (void *)data.data,
104 data.length,
105 (void **)&val.data);
106 ldb_msg_add_value(msg, "data", &val, NULL);
107 break;
109 case REG_BINARY:
110 ldb_msg_add_string(msg, "data",
111 data_blob_hex_string(mem_ctx, &data));
112 break;
114 case REG_DWORD:
115 ldb_msg_add_string(msg, "data",
116 talloc_asprintf(mem_ctx, "0x%x",
117 IVAL(data.data, 0)));
118 break;
119 default:
120 ldb_msg_add_value(msg, "data", &data, NULL);
124 type_s = talloc_asprintf(mem_ctx, "%u", type);
125 ldb_msg_add_string(msg, "type", type_s);
127 return msg;
130 static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value)
132 struct ldb_val val;
134 val.data = discard_const_p(uint8_t, value);
135 val.length = strlen(value);
137 return ldb_dn_escape_value(mem_ctx, val);
140 static int reg_close_ldb_key(struct ldb_key_data *key)
142 if (key->subkeys != NULL) {
143 talloc_free(key->subkeys);
144 key->subkeys = NULL;
147 if (key->values != NULL) {
148 talloc_free(key->values);
149 key->values = NULL;
151 return 0;
154 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
155 const struct hive_key *from,
156 const char *path, const char *add)
158 TALLOC_CTX *local_ctx;
159 struct ldb_dn *ret;
160 char *mypath = talloc_strdup(mem_ctx, path);
161 char *begin;
162 struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
163 struct ldb_context *ldb = kd->ldb;
165 local_ctx = talloc_new(mem_ctx);
167 if (add) {
168 ret = ldb_dn_new(mem_ctx, ldb, add);
169 } else {
170 ret = ldb_dn_new(mem_ctx, ldb, NULL);
172 if (!ldb_dn_validate(ret)) {
173 talloc_free(ret);
174 talloc_free(local_ctx);
175 return NULL;
178 while (mypath) {
179 char *keyname;
181 begin = strrchr(mypath, '\\');
183 if (begin) keyname = begin + 1;
184 else keyname = mypath;
186 if(strlen(keyname)) {
187 if (!ldb_dn_add_base_fmt(ret, "key=%s",
188 reg_ldb_escape(local_ctx,
189 keyname)))
191 talloc_free(local_ctx);
192 return NULL;
196 if(begin) {
197 *begin = '\0';
198 } else {
199 break;
203 ldb_dn_add_base(ret, kd->dn);
205 talloc_free(local_ctx);
207 return ret;
210 static WERROR cache_subkeys(struct ldb_key_data *kd)
212 struct ldb_context *c = kd->ldb;
213 struct ldb_result *res;
214 int ret;
216 ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res);
218 if (ret != LDB_SUCCESS) {
219 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
220 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
221 return WERR_FOOBAR;
224 kd->subkey_count = res->count;
225 kd->subkeys = talloc_steal(kd, res->msgs);
226 talloc_free(res);
228 return WERR_OK;
231 static WERROR cache_values(struct ldb_key_data *kd)
233 struct ldb_context *c = kd->ldb;
234 struct ldb_result *res;
235 int ret;
237 ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL,
238 "(value=*)", NULL, &res);
240 if (ret != LDB_SUCCESS) {
241 DEBUG(0, ("Error getting values for '%s': %s\n",
242 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
243 return WERR_FOOBAR;
245 kd->value_count = res->count;
246 kd->values = talloc_steal(kd, res->msgs);
247 talloc_free(res);
248 return WERR_OK;
252 static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
253 const struct hive_key *k, uint32_t idx,
254 const char **name,
255 const char **classname,
256 NTTIME *last_mod_time)
258 struct ldb_message_element *el;
259 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
261 /* Do a search if necessary */
262 if (kd->subkeys == NULL) {
263 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
266 if (idx >= kd->subkey_count)
267 return WERR_NO_MORE_ITEMS;
269 el = ldb_msg_find_element(kd->subkeys[idx], "key");
270 SMB_ASSERT(el != NULL);
271 SMB_ASSERT(el->num_values != 0);
273 if (name != NULL)
274 *name = talloc_strdup(mem_ctx, (char *)el->values[0].data);
276 if (classname != NULL)
277 *classname = NULL; /* TODO: Store properly */
279 if (last_mod_time != NULL)
280 *last_mod_time = 0; /* TODO: we need to add this to the
281 ldb backend properly */
283 return WERR_OK;
286 static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
287 const char** name, uint32_t *data_type,
288 DATA_BLOB *data)
290 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
291 struct ldb_context *c = kd->ldb;
292 const char* attrs[] = { "data", "type", NULL };
293 struct ldb_result *res;
294 int ret;
296 ret = ldb_search(c, kd->dn, LDB_SCOPE_BASE, "", attrs, &res);
298 if (ret != LDB_SUCCESS) {
299 DEBUG(0, ("Error getting default value for '%s': %s\n",
300 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
301 return WERR_FOOBAR;
304 if (res->count == 0 || res->msgs[0]->num_elements == 0)
305 return WERR_BADFILE;
307 reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm),
308 res->msgs[0], name, data_type, data);
310 talloc_free(res);
312 return WERR_OK;
315 static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
316 int idx, const char **name,
317 uint32_t *data_type, DATA_BLOB *data)
319 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
321 if (idx == 0) {
322 /* default value */
323 return ldb_get_default_value(mem_ctx, k, name, data_type, data);
324 } else {
325 /* normal value */
327 /* Do the search if necessary */
328 if (kd->values == NULL) {
329 W_ERROR_NOT_OK_RETURN(cache_values(kd));
332 if (idx >= kd->value_count)
333 return WERR_NO_MORE_ITEMS;
335 reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm),
336 kd->values[idx], name, data_type, data);
339 return WERR_OK;
342 static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
343 const char *name, uint32_t *data_type,
344 DATA_BLOB *data)
346 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
347 struct ldb_context *c = kd->ldb;
348 struct ldb_result *res;
349 int ret;
350 char *query;
352 if (strlen(name) == 0) {
353 /* default value */
354 return ldb_get_default_value(mem_ctx, k, NULL, data_type, data);
355 } else {
356 /* normal value */
357 query = talloc_asprintf(mem_ctx, "(value=%s)", name);
358 ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res);
359 talloc_free(query);
361 if (ret != LDB_SUCCESS) {
362 DEBUG(0, ("Error getting values for '%s': %s\n",
363 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
364 return WERR_FOOBAR;
367 if (res->count == 0)
368 return WERR_BADFILE;
370 reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm),
371 res->msgs[0], NULL, data_type, data);
373 talloc_free(res);
376 return WERR_OK;
379 static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
380 const char *name, struct hive_key **key)
382 struct ldb_result *res;
383 struct ldb_dn *ldap_path;
384 int ret;
385 struct ldb_key_data *newkd;
386 struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);
387 struct ldb_context *c = kd->ldb;
389 ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
391 ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res);
393 if (ret != LDB_SUCCESS) {
394 DEBUG(3, ("Error opening key '%s': %s\n",
395 ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
396 return WERR_FOOBAR;
397 } else if (res->count == 0) {
398 DEBUG(3, ("Key '%s' not found\n",
399 ldb_dn_get_linearized(ldap_path)));
400 talloc_free(res);
401 return WERR_BADFILE;
404 newkd = talloc_zero(mem_ctx, struct ldb_key_data);
405 newkd->key.ops = &reg_backend_ldb;
406 newkd->ldb = talloc_reference(newkd, kd->ldb);
407 newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
409 *key = (struct hive_key *)newkd;
411 return WERR_OK;
414 WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
415 struct auth_session_info *session_info,
416 struct cli_credentials *credentials,
417 struct event_context *ev_ctx,
418 struct loadparm_context *lp_ctx,
419 struct hive_key **k)
421 struct ldb_key_data *kd;
422 struct ldb_context *wrap;
423 struct ldb_message *attrs_msg;
425 if (location == NULL)
426 return WERR_INVALID_PARAM;
428 wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx,
429 location, session_info, credentials, 0, NULL);
431 if (wrap == NULL) {
432 DEBUG(1, (__FILE__": unable to connect\n"));
433 return WERR_FOOBAR;
436 attrs_msg = ldb_msg_new(wrap);
437 W_ERROR_HAVE_NO_MEMORY(attrs_msg);
438 attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES");
439 W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn);
440 ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE");
441 ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE");
443 ldb_add(wrap, attrs_msg);
445 ldb_set_debug_stderr(wrap);
447 kd = talloc_zero(parent_ctx, struct ldb_key_data);
448 kd->key.ops = &reg_backend_ldb;
449 kd->ldb = talloc_reference(kd, wrap);
450 talloc_set_destructor (kd, reg_close_ldb_key);
451 kd->dn = ldb_dn_new(kd, wrap, "hive=NONE");
453 *k = (struct hive_key *)kd;
455 return WERR_OK;
458 static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
459 const char *name, const char *classname,
460 struct security_descriptor *sd,
461 struct hive_key **newkey)
463 struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent);
464 struct ldb_message *msg;
465 struct ldb_key_data *newkd;
466 int ret;
468 msg = ldb_msg_new(mem_ctx);
470 msg->dn = reg_path_to_ldb(msg, parent, name, NULL);
472 ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name));
473 if (classname != NULL)
474 ldb_msg_add_string(msg, "classname",
475 talloc_strdup(mem_ctx, classname));
477 ret = ldb_add(parentkd->ldb, msg);
478 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
479 return WERR_ALREADY_EXISTS;
482 if (ret != LDB_SUCCESS) {
483 DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb)));
484 return WERR_FOOBAR;
487 DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn)));
489 newkd = talloc_zero(mem_ctx, struct ldb_key_data);
490 newkd->ldb = talloc_reference(newkd, parentkd->ldb);
491 newkd->key.ops = &reg_backend_ldb;
492 newkd->dn = talloc_steal(newkd, msg->dn);
494 *newkey = (struct hive_key *)newkd;
496 /* reset cache */
497 talloc_free(parentkd->subkeys);
498 parentkd->subkeys = NULL;
500 return WERR_OK;
503 static WERROR ldb_del_value (struct hive_key *key, const char *child)
505 int ret;
506 struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
507 TALLOC_CTX *mem_ctx;
508 struct ldb_message *msg;
509 struct ldb_dn *childdn;
511 if (strlen(child) == 0) {
512 /* default value */
513 mem_ctx = talloc_init("ldb_del_value");
515 msg = talloc_zero(mem_ctx, struct ldb_message);
516 msg->dn = ldb_dn_copy(msg, kd->dn);
517 ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
518 ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_DELETE, NULL);
520 ret = ldb_modify(kd->ldb, msg);
521 if (ret != LDB_SUCCESS) {
522 DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
523 talloc_free(mem_ctx);
524 return WERR_FOOBAR;
527 talloc_free(mem_ctx);
528 } else {
529 /* normal value */
530 childdn = ldb_dn_copy(kd->ldb, kd->dn);
531 if (!ldb_dn_add_child_fmt(childdn, "value=%s",
532 reg_ldb_escape(childdn, child)))
534 talloc_free(childdn);
535 return WERR_FOOBAR;
538 ret = ldb_delete(kd->ldb, childdn);
540 talloc_free(childdn);
542 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
543 return WERR_BADFILE;
544 } else if (ret != LDB_SUCCESS) {
545 DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
546 return WERR_FOOBAR;
550 /* reset cache */
551 talloc_free(kd->values);
552 kd->values = NULL;
554 return WERR_OK;
557 static WERROR ldb_del_key(const struct hive_key *key, const char *name)
559 int i, ret;
560 struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
561 struct ldb_dn *ldap_path;
562 TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key");
563 struct ldb_context *c = parentkd->ldb;
564 struct ldb_result *res_keys;
565 struct ldb_result *res_vals;
566 WERROR werr;
567 struct hive_key *hk;
569 /* Verify key exists by opening it */
570 werr = ldb_open_key(mem_ctx, key, name, &hk);
571 if (!W_ERROR_IS_OK(werr)) {
572 talloc_free(mem_ctx);
573 return werr;
576 ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
577 if (!ldap_path) {
578 talloc_free(mem_ctx);
579 return WERR_FOOBAR;
582 /* Search for subkeys */
583 ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL,
584 "(key=*)", NULL, &res_keys);
586 if (ret != LDB_SUCCESS) {
587 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
588 ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
589 talloc_free(mem_ctx);
590 return WERR_FOOBAR;
593 /* Search for values */
594 ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL,
595 "(value=*)", NULL, &res_vals);
597 if (ret != LDB_SUCCESS) {
598 DEBUG(0, ("Error getting values for '%s': %s\n",
599 ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
600 talloc_free(mem_ctx);
601 return WERR_FOOBAR;
604 /* Start an explicit transaction */
605 ret = ldb_transaction_start(c);
607 if (ret != LDB_SUCCESS) {
608 DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
609 talloc_free(mem_ctx);
610 return WERR_FOOBAR;
613 if (res_keys->count || res_vals->count)
615 /* Delete any subkeys */
616 for (i = 0; i < res_keys->count; i++)
618 werr = ldb_del_key(hk, ldb_msg_find_attr_as_string(
619 res_keys->msgs[i],
620 "key", NULL));
621 if (!W_ERROR_IS_OK(werr)) {
622 ret = ldb_transaction_cancel(c);
623 talloc_free(mem_ctx);
624 return werr;
628 /* Delete any values */
629 for (i = 0; i < res_vals->count; i++)
631 werr = ldb_del_value(hk, ldb_msg_find_attr_as_string(
632 res_vals->msgs[i],
633 "value", NULL));
634 if (!W_ERROR_IS_OK(werr)) {
635 ret = ldb_transaction_cancel(c);
636 talloc_free(mem_ctx);
637 return werr;
642 /* Delete the key itself */
643 ret = ldb_delete(c, ldap_path);
645 if (ret != LDB_SUCCESS)
647 DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
648 ret = ldb_transaction_cancel(c);
649 talloc_free(mem_ctx);
650 return WERR_FOOBAR;
653 /* Commit the transaction */
654 ret = ldb_transaction_commit(c);
656 if (ret != LDB_SUCCESS)
658 DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
659 ret = ldb_transaction_cancel(c);
660 talloc_free(mem_ctx);
661 return WERR_FOOBAR;
664 talloc_free(mem_ctx);
666 /* reset cache */
667 talloc_free(parentkd->subkeys);
668 parentkd->subkeys = NULL;
670 return WERR_OK;
673 static WERROR ldb_set_value(struct hive_key *parent,
674 const char *name, uint32_t type,
675 const DATA_BLOB data)
677 struct ldb_message *msg;
678 struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
679 int ret;
680 TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
682 msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
683 msg->dn = ldb_dn_copy(msg, kd->dn);
685 if (strlen(name) > 0) {
686 /* For a default value, we add/overwrite the attributes to/of the hive.
687 For a normal value, we create new childs. */
688 if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
689 reg_ldb_escape(mem_ctx, name)))
691 talloc_free(mem_ctx);
692 return WERR_FOOBAR;
696 ret = ldb_add(kd->ldb, msg);
697 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
698 int i;
699 for (i = 0; i < msg->num_elements; i++) {
700 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
702 ret = ldb_modify(kd->ldb, msg);
705 if (ret != LDB_SUCCESS) {
706 DEBUG(1, ("ldb_set_value: %s\n", ldb_errstring(kd->ldb)));
707 talloc_free(mem_ctx);
708 return WERR_FOOBAR;
711 /* reset cache */
712 talloc_free(kd->values);
713 kd->values = NULL;
715 talloc_free(mem_ctx);
716 return WERR_OK;
719 static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
720 const struct hive_key *key,
721 const char **classname,
722 uint32_t *num_subkeys,
723 uint32_t *num_values,
724 NTTIME *last_change_time,
725 uint32_t *max_subkeynamelen,
726 uint32_t *max_valnamelen,
727 uint32_t *max_valbufsize)
729 struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
731 if (kd->subkeys == NULL) {
732 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
735 if (kd->values == NULL) {
736 W_ERROR_NOT_OK_RETURN(cache_values(kd));
739 /* FIXME */
740 if (classname != NULL)
741 *classname = NULL;
743 if (num_subkeys != NULL) {
744 *num_subkeys = kd->subkey_count;
747 if (num_values != NULL) {
748 *num_values = kd->value_count;
751 if (last_change_time != NULL)
752 *last_change_time = 0;
754 if (max_subkeynamelen != NULL) {
755 int i;
756 struct ldb_message_element *el;
758 *max_subkeynamelen = 0;
760 for (i = 0; i < kd->subkey_count; i++) {
761 el = ldb_msg_find_element(kd->subkeys[i], "key");
762 *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length);
766 if (max_valnamelen != NULL || max_valbufsize != NULL) {
767 int i;
768 struct ldb_message_element *el;
769 W_ERROR_NOT_OK_RETURN(cache_values(kd));
771 if (max_valbufsize != NULL)
772 *max_valbufsize = 0;
774 if (max_valnamelen != NULL)
775 *max_valnamelen = 0;
777 for (i = 0; i < kd->value_count; i++) {
778 if (max_valnamelen != NULL) {
779 el = ldb_msg_find_element(kd->values[i], "value");
780 *max_valnamelen = MAX(*max_valnamelen, el->values[0].length);
783 if (max_valbufsize != NULL) {
784 DATA_BLOB data;
785 reg_ldb_unpack_value(mem_ctx,
786 lp_iconv_convenience(global_loadparm),
787 kd->values[i], NULL,
788 NULL, &data);
789 *max_valbufsize = MAX(*max_valbufsize, data.length);
790 talloc_free(data.data);
795 return WERR_OK;
798 static struct hive_operations reg_backend_ldb = {
799 .name = "ldb",
800 .add_key = ldb_add_key,
801 .del_key = ldb_del_key,
802 .get_key_by_name = ldb_open_key,
803 .enum_value = ldb_get_value_by_id,
804 .enum_key = ldb_get_subkey_by_id,
805 .set_value = ldb_set_value,
806 .get_value_by_name = ldb_get_value,
807 .delete_value = ldb_del_value,
808 .get_key_info = ldb_get_key_info,