source: branches/samba-3.5.x/source4/lib/registry/ldb.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

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