root/source4/lib/registry/ldb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_ldb_unpack_value
  2. reg_ldb_pack_value
  3. reg_ldb_escape
  4. reg_close_ldb_key
  5. reg_path_to_ldb
  6. cache_subkeys
  7. cache_values
  8. ldb_get_subkey_by_id
  9. ldb_get_default_value
  10. ldb_get_value_by_id
  11. ldb_get_value
  12. ldb_open_key
  13. reg_open_ldb_file
  14. ldb_add_key
  15. ldb_del_value
  16. ldb_del_key
  17. ldb_set_value
  18. ldb_get_key_info

   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 
  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         int subkey_count, value_count;
  38 };
  39 
  40 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  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 
  93 static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  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 
 141 static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 151 static int reg_close_ldb_key(struct ldb_key_data *key)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 165 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 221 static WERROR cache_subkeys(struct ldb_key_data *kd)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 242 static WERROR cache_values(struct ldb_key_data *kd)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 265 static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 301 static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 330 static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 358 static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 394 static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 429 WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 473 static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 518 static WERROR ldb_del_value (struct hive_key *key, const char *child)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 572 static WERROR ldb_del_key(const struct hive_key *key, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 688 static WERROR ldb_set_value(struct hive_key *parent,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 735 static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 823 static 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 };

/* [<][>][^][v][top][bottom][index][help] */