s3:printing: Allow to run samba-bgqd as a standalone systemd service
[Samba.git] / source4 / lib / registry / ldb.c
blobdb383a560da4c8ae12d2946dd01b6fd6e27d5792
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
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.
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.
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/>.
21 #include "includes.h"
22 #include "registry.h"
23 #include <ldb.h>
24 #include <ldb_errors.h>
25 #include "ldb_wrap.h"
26 #include "librpc/gen_ndr/winreg.h"
27 #include "param/param.h"
28 #include "lib/util/smb_strtox.h"
30 #undef strcasecmp
32 static struct hive_operations reg_backend_ldb;
34 struct ldb_key_data
36 struct hive_key key;
37 struct ldb_context *ldb;
38 struct ldb_dn *dn;
39 struct ldb_message **subkeys, **values;
40 unsigned int subkey_count, value_count;
41 const char *classname;
44 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
45 struct ldb_message *msg,
46 const char **name, uint32_t *type,
47 DATA_BLOB *data)
49 const struct ldb_val *val;
50 uint32_t value_type;
52 if (name != NULL) {
53 *name = talloc_strdup(mem_ctx,
54 ldb_msg_find_attr_as_string(msg, "value",
55 ""));
58 value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
59 *type = value_type;
61 val = ldb_msg_find_ldb_val(msg, "data");
63 switch (value_type)
65 case REG_SZ:
66 case REG_EXPAND_SZ:
67 if (val != NULL) {
68 /* The data should be provided as UTF16 string */
69 convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16,
70 val->data, val->length,
71 (void **)&data->data, &data->length);
72 } else {
73 data->data = NULL;
74 data->length = 0;
76 break;
78 case REG_DWORD:
79 case REG_DWORD_BIG_ENDIAN:
80 if (val != NULL) {
81 int error = 0;
82 /* The data is a plain DWORD */
83 uint32_t tmp;
85 tmp = smb_strtoul((char *)val->data,
86 NULL,
88 &error,
89 SMB_STR_STANDARD);
90 if (error != 0) {
91 data->data = NULL;
92 data->length = 0;
93 break;
95 data->data = talloc_size(mem_ctx, sizeof(uint32_t));
96 if (data->data != NULL) {
97 SIVAL(data->data, 0, tmp);
99 data->length = sizeof(uint32_t);
100 } else {
101 data->data = NULL;
102 data->length = 0;
104 break;
106 case REG_QWORD:
107 if (val != NULL) {
108 int error = 0;
109 /* The data is a plain QWORD */
110 uint64_t tmp;
112 tmp = smb_strtoull((char *)val->data,
113 NULL,
115 &error,
116 SMB_STR_STANDARD);
117 if (error != 0) {
118 data->data = NULL;
119 data->length = 0;
120 break;
122 data->data = talloc_size(mem_ctx, sizeof(uint64_t));
123 if (data->data != NULL) {
124 SBVAL(data->data, 0, tmp);
126 data->length = sizeof(uint64_t);
127 } else {
128 data->data = NULL;
129 data->length = 0;
131 break;
133 case REG_BINARY:
134 default:
135 if (val != NULL) {
136 data->data = talloc_memdup(mem_ctx, val->data,
137 val->length);
138 data->length = val->length;
139 } else {
140 data->data = NULL;
141 data->length = 0;
143 break;
147 static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
148 TALLOC_CTX *mem_ctx,
149 const char *name,
150 uint32_t type, DATA_BLOB data)
152 struct ldb_message *msg;
153 char *name_dup, *type_str;
154 int ret;
156 msg = ldb_msg_new(mem_ctx);
157 if (msg == NULL) {
158 return NULL;
161 name_dup = talloc_strdup(msg, name);
162 if (name_dup == NULL) {
163 talloc_free(msg);
164 return NULL;
167 ret = ldb_msg_add_string(msg, "value", name_dup);
168 if (ret != LDB_SUCCESS) {
169 talloc_free(msg);
170 return NULL;
173 switch (type) {
174 case REG_SZ:
175 case REG_EXPAND_SZ:
176 if ((data.length > 0) && (data.data != NULL)) {
177 struct ldb_val *val;
178 bool ret2 = false;
180 val = talloc_zero(msg, struct ldb_val);
181 if (val == NULL) {
182 talloc_free(msg);
183 return NULL;
186 /* The data is provided as UTF16 string */
187 ret2 = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8,
188 (void *)data.data, data.length,
189 (void **)&val->data, &val->length);
190 if (ret2) {
191 ret = ldb_msg_add_value(msg, "data", val, NULL);
192 } else {
193 /* workaround for non-standard data */
194 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
196 } else {
197 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
199 break;
201 case REG_DWORD:
202 case REG_DWORD_BIG_ENDIAN:
203 if ((data.length > 0) && (data.data != NULL)) {
204 if (data.length == sizeof(uint32_t)) {
205 char *conv_str;
207 conv_str = talloc_asprintf(msg, "0x%8.8x",
208 IVAL(data.data, 0));
209 if (conv_str == NULL) {
210 talloc_free(msg);
211 return NULL;
213 ret = ldb_msg_add_string(msg, "data", conv_str);
214 } else {
215 /* workaround for non-standard data */
216 talloc_free(msg);
217 return NULL;
219 } else {
220 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
222 break;
224 case REG_QWORD:
225 if ((data.length > 0) && (data.data != NULL)) {
226 if (data.length == sizeof(uint64_t)) {
227 char *conv_str;
229 conv_str = talloc_asprintf(msg, "0x%16.16llx",
230 (unsigned long long)BVAL(data.data, 0));
231 if (conv_str == NULL) {
232 talloc_free(msg);
233 return NULL;
235 ret = ldb_msg_add_string(msg, "data", conv_str);
236 } else {
237 /* workaround for non-standard data */
238 talloc_free(msg);
239 return NULL;
242 } else {
243 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
245 break;
247 case REG_BINARY:
248 default:
249 if ((data.length > 0) && (data.data != NULL)) {
250 ret = ldb_msg_add_value(msg, "data", &data, NULL);
251 } else {
252 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
254 break;
257 if (ret != LDB_SUCCESS) {
258 talloc_free(msg);
259 return NULL;
262 type_str = talloc_asprintf(mem_ctx, "%u", type);
263 if (type_str == NULL) {
264 talloc_free(msg);
265 return NULL;
268 ret = ldb_msg_add_string(msg, "type", type_str);
269 if (ret != LDB_SUCCESS) {
270 talloc_free(msg);
271 return NULL;
274 return msg;
277 static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value)
279 struct ldb_val val;
281 val.data = discard_const_p(uint8_t, value);
282 val.length = strlen(value);
284 return ldb_dn_escape_value(mem_ctx, val);
287 static int reg_close_ldb_key(struct ldb_key_data *key)
289 if (key->subkeys != NULL) {
290 talloc_free(key->subkeys);
291 key->subkeys = NULL;
294 if (key->values != NULL) {
295 talloc_free(key->values);
296 key->values = NULL;
298 return 0;
301 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
302 const struct hive_key *from,
303 const char *path, const char *add)
305 struct ldb_dn *ret;
306 char *mypath;
307 char *begin;
308 struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
309 struct ldb_context *ldb = kd->ldb;
311 mypath = talloc_strdup(mem_ctx, path);
312 if (mypath == NULL) {
313 return NULL;
316 ret = ldb_dn_new(mem_ctx, ldb, add);
317 if (!ldb_dn_validate(ret)) {
318 talloc_free(ret);
319 return NULL;
322 if (!ldb_dn_add_base(ret, kd->dn)) {
323 talloc_free(ret);
324 return NULL;
327 while (mypath[0] != '\0') {
328 begin = strchr(mypath, '\\');
329 if (begin != NULL) {
330 *begin = '\0';
333 if (!ldb_dn_add_child_fmt(ret, "key=%s",
334 reg_ldb_escape(mem_ctx, mypath))) {
335 talloc_free(ret);
336 return NULL;
339 if (begin != NULL) {
340 mypath = begin + 1;
341 } else {
342 break;
346 return ret;
349 static WERROR cache_subkeys(struct ldb_key_data *kd)
351 struct ldb_context *c = kd->ldb;
352 struct ldb_result *res;
353 int ret;
355 ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
356 NULL, "(key=*)");
357 if (ret != LDB_SUCCESS) {
358 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
359 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
360 return WERR_FOOBAR;
363 kd->subkey_count = res->count;
364 kd->subkeys = talloc_steal(kd, res->msgs);
365 talloc_free(res);
367 return WERR_OK;
370 static WERROR cache_values(struct ldb_key_data *kd)
372 struct ldb_context *c = kd->ldb;
373 struct ldb_result *res;
374 int ret;
376 ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
377 NULL, "(value=*)");
378 if (ret != LDB_SUCCESS) {
379 DEBUG(0, ("Error getting values for '%s': %s\n",
380 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
381 return WERR_FOOBAR;
384 kd->value_count = res->count;
385 kd->values = talloc_steal(kd, res->msgs);
386 talloc_free(res);
388 return WERR_OK;
392 static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
393 const struct hive_key *k, uint32_t idx,
394 const char **name,
395 const char **classname,
396 NTTIME *last_mod_time)
398 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
400 /* Initialization */
401 if (name != NULL)
402 *name = NULL;
403 if (classname != NULL)
404 *classname = NULL;
405 if (last_mod_time != NULL)
406 *last_mod_time = 0; /* TODO: we need to add this to the
407 ldb backend properly */
409 /* Do a search if necessary */
410 if (kd->subkeys == NULL) {
411 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
414 if (idx >= kd->subkey_count)
415 return WERR_NO_MORE_ITEMS;
417 if (name != NULL)
418 *name = talloc_strdup(mem_ctx,
419 ldb_msg_find_attr_as_string(kd->subkeys[idx], "key", NULL));
420 if (classname != NULL)
421 *classname = talloc_strdup(mem_ctx,
422 ldb_msg_find_attr_as_string(kd->subkeys[idx], "classname", NULL));
424 return WERR_OK;
427 static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx,
428 const struct hive_key *k,
429 const char **name, uint32_t *data_type,
430 DATA_BLOB *data)
432 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
433 struct ldb_context *c = kd->ldb;
434 const char* attrs[] = { "data", "type", NULL };
435 struct ldb_result *res;
436 int ret;
438 ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs,
439 NULL);
441 if (ret != LDB_SUCCESS) {
442 DEBUG(0, ("Error getting default value for '%s': %s\n",
443 ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
444 return WERR_FOOBAR;
447 if (res->count == 0 || res->msgs[0]->num_elements == 0) {
448 talloc_free(res);
449 return WERR_FILE_NOT_FOUND;
452 if ((data_type != NULL) && (data != NULL)) {
453 reg_ldb_unpack_value(mem_ctx, res->msgs[0], name, data_type,
454 data);
457 talloc_free(res);
459 return WERR_OK;
462 static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
463 uint32_t idx, const char **name,
464 uint32_t *data_type, DATA_BLOB *data)
466 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
468 /* if the default value exists, give it back */
469 if (W_ERROR_IS_OK(ldb_get_default_value(mem_ctx, k, name, data_type,
470 data))) {
471 if (idx == 0)
472 return WERR_OK;
473 else
474 --idx;
477 /* Do the search if necessary */
478 if (kd->values == NULL) {
479 W_ERROR_NOT_OK_RETURN(cache_values(kd));
482 if (idx >= kd->value_count)
483 return WERR_NO_MORE_ITEMS;
485 reg_ldb_unpack_value(mem_ctx, kd->values[idx], name, data_type, data);
487 return WERR_OK;
490 static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
491 const char *name, uint32_t *data_type,
492 DATA_BLOB *data)
494 struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
495 const char *res_name;
496 uint32_t idx;
498 /* the default value was requested, give it back */
499 if (name[0] == '\0') {
500 return ldb_get_default_value(mem_ctx, k, NULL, data_type, data);
503 /* Do the search if necessary */
504 if (kd->values == NULL) {
505 W_ERROR_NOT_OK_RETURN(cache_values(kd));
508 for (idx = 0; idx < kd->value_count; idx++) {
509 res_name = ldb_msg_find_attr_as_string(kd->values[idx], "value",
510 "");
511 if (ldb_attr_cmp(name, res_name) == 0) {
512 reg_ldb_unpack_value(mem_ctx, kd->values[idx], NULL,
513 data_type, data);
514 return WERR_OK;
518 return WERR_FILE_NOT_FOUND;
521 static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
522 const char *name, struct hive_key **key)
524 struct ldb_result *res;
525 struct ldb_dn *ldb_path;
526 int ret;
527 struct ldb_key_data *newkd;
528 struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);
529 struct ldb_context *c = kd->ldb;
531 ldb_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
532 W_ERROR_HAVE_NO_MEMORY(ldb_path);
534 ret = ldb_search(c, mem_ctx, &res, ldb_path, LDB_SCOPE_BASE, NULL,
535 NULL);
537 if (ret != LDB_SUCCESS) {
538 DEBUG(3, ("Error opening key '%s': %s\n",
539 ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
540 return WERR_FOOBAR;
541 } else if (res->count == 0) {
542 DEBUG(3, ("Key '%s' not found\n",
543 ldb_dn_get_linearized(ldb_path)));
544 talloc_free(res);
545 return WERR_FILE_NOT_FOUND;
548 newkd = talloc_zero(mem_ctx, struct ldb_key_data);
549 W_ERROR_HAVE_NO_MEMORY(newkd);
550 newkd->key.ops = &reg_backend_ldb;
551 newkd->ldb = talloc_reference(newkd, kd->ldb);
552 newkd->dn = ldb_dn_copy(newkd, res->msgs[0]->dn);
553 newkd->classname = talloc_steal(newkd,
554 ldb_msg_find_attr_as_string(res->msgs[0], "classname", NULL));
556 talloc_free(res);
558 *key = (struct hive_key *)newkd;
560 return WERR_OK;
563 WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
564 struct auth_session_info *session_info,
565 struct cli_credentials *credentials,
566 struct tevent_context *ev_ctx,
567 struct loadparm_context *lp_ctx,
568 struct hive_key **k)
570 struct ldb_key_data *kd;
571 struct ldb_context *wrap;
572 struct ldb_message *attrs_msg;
574 if (location == NULL)
575 return WERR_INVALID_PARAMETER;
577 wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx,
578 location, session_info, credentials, 0);
580 if (wrap == NULL) {
581 DEBUG(1, (__FILE__": unable to connect\n"));
582 return WERR_FOOBAR;
585 attrs_msg = ldb_msg_new(wrap);
586 W_ERROR_HAVE_NO_MEMORY(attrs_msg);
587 attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES");
588 W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn);
589 ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE");
590 ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE");
592 ldb_add(wrap, attrs_msg);
594 ldb_set_debug_stderr(wrap);
596 kd = talloc_zero(parent_ctx, struct ldb_key_data);
597 kd->key.ops = &reg_backend_ldb;
598 kd->ldb = talloc_reference(kd, wrap);
599 talloc_set_destructor (kd, reg_close_ldb_key);
600 kd->dn = ldb_dn_new(kd, wrap, "hive=NONE");
602 *k = (struct hive_key *)kd;
604 return WERR_OK;
607 static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
608 const char *name, const char *classname,
609 struct security_descriptor *sd,
610 struct hive_key **newkey)
612 struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent);
613 struct ldb_dn *ldb_path;
614 struct ldb_message *msg;
615 struct ldb_key_data *newkd;
616 int ret;
618 ldb_path = reg_path_to_ldb(mem_ctx, parent, name, NULL);
619 W_ERROR_HAVE_NO_MEMORY(ldb_path);
621 msg = ldb_msg_new(mem_ctx);
622 W_ERROR_HAVE_NO_MEMORY(msg);
624 msg->dn = ldb_path;
626 ldb_msg_add_string(msg, "key", name);
627 if (classname != NULL) {
628 ldb_msg_add_string(msg, "classname", classname);
631 ret = ldb_add(parentkd->ldb, msg);
633 talloc_free(msg);
635 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
636 return WERR_ALREADY_EXISTS;
639 if (ret != LDB_SUCCESS) {
640 DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb)));
641 return WERR_FOOBAR;
644 DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(ldb_path)));
646 newkd = talloc_zero(mem_ctx, struct ldb_key_data);
647 W_ERROR_HAVE_NO_MEMORY(newkd);
648 newkd->ldb = talloc_reference(newkd, parentkd->ldb);
649 newkd->key.ops = &reg_backend_ldb;
650 newkd->dn = talloc_steal(newkd, ldb_path);
651 newkd->classname = talloc_steal(newkd, classname);
653 *newkey = (struct hive_key *)newkd;
655 /* reset cache */
656 talloc_free(parentkd->subkeys);
657 parentkd->subkeys = NULL;
659 return WERR_OK;
662 static WERROR ldb_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
663 const char *child)
665 int ret;
666 struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
667 struct ldb_message *msg;
668 struct ldb_dn *childdn;
670 if (child[0] == '\0') {
671 /* default value */
672 msg = ldb_msg_new(mem_ctx);
673 W_ERROR_HAVE_NO_MEMORY(msg);
674 msg->dn = ldb_dn_copy(msg, kd->dn);
675 W_ERROR_HAVE_NO_MEMORY(msg->dn);
676 ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
677 if (ret != LDB_SUCCESS) {
678 return WERR_FOOBAR;
680 ret = ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_DELETE,
681 NULL);
682 if (ret != LDB_SUCCESS) {
683 return WERR_FOOBAR;
686 ret = ldb_modify(kd->ldb, msg);
688 talloc_free(msg);
690 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
691 return WERR_FILE_NOT_FOUND;
692 } else if (ret != LDB_SUCCESS) {
693 DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
694 return WERR_FOOBAR;
696 } else {
697 /* normal value */
698 childdn = ldb_dn_copy(kd->ldb, kd->dn);
699 if (!ldb_dn_add_child_fmt(childdn, "value=%s",
700 reg_ldb_escape(childdn, child)))
702 talloc_free(childdn);
703 return WERR_FOOBAR;
706 ret = ldb_delete(kd->ldb, childdn);
708 talloc_free(childdn);
710 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
711 return WERR_FILE_NOT_FOUND;
712 } else if (ret != LDB_SUCCESS) {
713 DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
714 return WERR_FOOBAR;
718 /* reset cache */
719 talloc_free(kd->values);
720 kd->values = NULL;
722 return WERR_OK;
725 static WERROR ldb_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *key,
726 const char *name)
728 unsigned int i;
729 int ret;
730 struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
731 struct ldb_dn *ldb_path;
732 struct ldb_context *c = parentkd->ldb;
733 struct ldb_result *res_keys;
734 struct ldb_result *res_vals;
735 WERROR werr;
736 struct hive_key *hk;
738 /* Verify key exists by opening it */
739 werr = ldb_open_key(mem_ctx, key, name, &hk);
740 if (!W_ERROR_IS_OK(werr)) {
741 return werr;
744 ldb_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
745 W_ERROR_HAVE_NO_MEMORY(ldb_path);
747 /* Search for subkeys */
748 ret = ldb_search(c, mem_ctx, &res_keys, ldb_path, LDB_SCOPE_ONELEVEL,
749 NULL, "(key=*)");
751 if (ret != LDB_SUCCESS) {
752 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
753 ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
754 return WERR_FOOBAR;
757 /* Search for values */
758 ret = ldb_search(c, mem_ctx, &res_vals, ldb_path, LDB_SCOPE_ONELEVEL,
759 NULL, "(value=*)");
761 if (ret != LDB_SUCCESS) {
762 DEBUG(0, ("Error getting values for '%s': %s\n",
763 ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
764 return WERR_FOOBAR;
767 /* Start an explicit transaction */
768 ret = ldb_transaction_start(c);
770 if (ret != LDB_SUCCESS) {
771 DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
772 return WERR_FOOBAR;
775 if (res_keys->count || res_vals->count)
777 /* Delete any subkeys */
778 for (i = 0; i < res_keys->count; i++)
780 werr = ldb_del_key(mem_ctx, hk,
781 ldb_msg_find_attr_as_string(
782 res_keys->msgs[i],
783 "key", NULL));
784 if (!W_ERROR_IS_OK(werr)) {
785 ret = ldb_transaction_cancel(c);
786 return werr;
790 /* Delete any values */
791 for (i = 0; i < res_vals->count; i++)
793 werr = ldb_del_value(mem_ctx, hk,
794 ldb_msg_find_attr_as_string(
795 res_vals->msgs[i],
796 "value", NULL));
797 if (!W_ERROR_IS_OK(werr)) {
798 ret = ldb_transaction_cancel(c);
799 return werr;
803 talloc_free(res_keys);
804 talloc_free(res_vals);
806 /* Delete the key itself */
807 ret = ldb_delete(c, ldb_path);
809 if (ret != LDB_SUCCESS)
811 DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
812 ret = ldb_transaction_cancel(c);
813 return WERR_FOOBAR;
816 /* Commit the transaction */
817 ret = ldb_transaction_commit(c);
819 if (ret != LDB_SUCCESS)
821 DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
822 ret = ldb_transaction_cancel(c);
823 return WERR_FOOBAR;
826 /* reset cache */
827 talloc_free(parentkd->subkeys);
828 parentkd->subkeys = NULL;
830 return WERR_OK;
833 static WERROR ldb_set_value(struct hive_key *parent,
834 const char *name, uint32_t type,
835 const DATA_BLOB data)
837 struct ldb_message *msg;
838 struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
839 unsigned int i;
840 int ret;
841 TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
843 msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
844 W_ERROR_HAVE_NO_MEMORY(msg);
846 msg->dn = ldb_dn_copy(msg, kd->dn);
847 W_ERROR_HAVE_NO_MEMORY(msg->dn);
849 if (name[0] != '\0') {
850 /* For a default value, we add/overwrite the attributes to/of the hive.
851 For a normal value, we create a new child. */
852 if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
853 reg_ldb_escape(mem_ctx, name)))
855 talloc_free(mem_ctx);
856 return WERR_FOOBAR;
860 /* Try first a "modify" and if this doesn't work do try an "add" */
861 for (i = 0; i < msg->num_elements; i++) {
862 if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) != LDB_FLAG_MOD_DELETE) {
863 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
866 ret = ldb_modify(kd->ldb, msg);
867 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
868 i = 0;
869 while (i < msg->num_elements) {
870 if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE) {
871 ldb_msg_remove_element(msg, &msg->elements[i]);
872 } else {
873 ++i;
876 ret = ldb_add(kd->ldb, msg);
878 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
879 /* ignore this -> the value didn't exist and also now doesn't */
880 ret = LDB_SUCCESS;
883 talloc_free(msg);
885 if (ret != LDB_SUCCESS) {
886 DEBUG(1, ("ldb_set_value: %s\n", ldb_errstring(kd->ldb)));
887 talloc_free(mem_ctx);
888 return WERR_FOOBAR;
891 /* reset cache */
892 talloc_free(kd->values);
893 kd->values = NULL;
895 talloc_free(mem_ctx);
896 return WERR_OK;
899 static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
900 const struct hive_key *key,
901 const char **classname,
902 uint32_t *num_subkeys,
903 uint32_t *num_values,
904 NTTIME *last_change_time,
905 uint32_t *max_subkeynamelen,
906 uint32_t *max_valnamelen,
907 uint32_t *max_valbufsize)
909 struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
910 uint32_t default_value_type = REG_NONE;
911 DATA_BLOB default_value = { NULL, 0 };
912 WERROR werr;
914 /* Initialization */
915 if (classname != NULL)
916 *classname = NULL;
917 if (num_subkeys != NULL)
918 *num_subkeys = 0;
919 if (num_values != NULL)
920 *num_values = 0;
921 if (last_change_time != NULL)
922 *last_change_time = 0;
923 if (max_subkeynamelen != NULL)
924 *max_subkeynamelen = 0;
925 if (max_valnamelen != NULL)
926 *max_valnamelen = 0;
927 if (max_valbufsize != NULL)
928 *max_valbufsize = 0;
930 /* We need this to get the default value (if it exists) for counting
931 * the values under the key and for finding out the longest value buffer
932 * size. If no default value exists the DATA_BLOB "default_value" will
933 * remain { NULL, 0 }. */
934 werr = ldb_get_default_value(mem_ctx, key, NULL, &default_value_type,
935 &default_value);
936 if ((!W_ERROR_IS_OK(werr)) && (!W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND))) {
937 return werr;
940 if (kd->subkeys == NULL) {
941 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
943 if (kd->values == NULL) {
944 W_ERROR_NOT_OK_RETURN(cache_values(kd));
947 if (classname != NULL) {
948 *classname = kd->classname;
951 if (num_subkeys != NULL) {
952 *num_subkeys = kd->subkey_count;
954 if (num_values != NULL) {
955 *num_values = kd->value_count;
956 /* also consider the default value if it exists */
957 if (default_value.data != NULL) {
958 ++(*num_values);
963 if (max_subkeynamelen != NULL) {
964 unsigned int i;
965 struct ldb_message_element *el;
967 for (i = 0; i < kd->subkey_count; i++) {
968 el = ldb_msg_find_element(kd->subkeys[i], "key");
969 *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length);
973 if (max_valnamelen != NULL || max_valbufsize != NULL) {
974 unsigned int i;
975 struct ldb_message_element *el;
976 W_ERROR_NOT_OK_RETURN(cache_values(kd));
978 /* also consider the default value if it exists */
979 if ((max_valbufsize != NULL) && (default_value.data != NULL)) {
980 *max_valbufsize = MAX(*max_valbufsize,
981 default_value.length);
984 for (i = 0; i < kd->value_count; i++) {
985 if (max_valnamelen != NULL) {
986 el = ldb_msg_find_element(kd->values[i], "value");
987 *max_valnamelen = MAX(*max_valnamelen, el->values[0].length);
990 if (max_valbufsize != NULL) {
991 uint32_t data_type;
992 DATA_BLOB data;
993 reg_ldb_unpack_value(mem_ctx,
994 kd->values[i], NULL,
995 &data_type, &data);
996 *max_valbufsize = MAX(*max_valbufsize, data.length);
997 talloc_free(data.data);
1002 talloc_free(default_value.data);
1004 return WERR_OK;
1007 static struct hive_operations reg_backend_ldb = {
1008 .name = "ldb",
1009 .add_key = ldb_add_key,
1010 .del_key = ldb_del_key,
1011 .get_key_by_name = ldb_open_key,
1012 .enum_value = ldb_get_value_by_id,
1013 .enum_key = ldb_get_subkey_by_id,
1014 .set_value = ldb_set_value,
1015 .get_value_by_name = ldb_get_value,
1016 .delete_value = ldb_del_value,
1017 .get_key_info = ldb_get_key_info,