Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/lib/registry/ldb.c

    r414 r745  
    33   Registry interface
    44   Copyright (C) 2004-2007, Jelmer Vernooij, jelmer@samba.org
    5    Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
     5   Copyright (C) 2008-2010, Matthias Dieter Wallnöfer, mdw@samba.org
    66
    77   This program is free software; you can redistribute it and/or modify
     
    2121#include "includes.h"
    2222#include "registry.h"
    23 #include "lib/ldb/include/ldb.h"
    24 #include "lib/ldb/include/ldb_errors.h"
     23#include <ldb.h>
     24#include <ldb_errors.h>
    2525#include "ldb_wrap.h"
    2626#include "librpc/gen_ndr/winreg.h"
     
    3535        struct ldb_dn *dn;
    3636        struct ldb_message **subkeys, **values;
    37         int subkey_count, value_count;
     37        unsigned int subkey_count, value_count;
     38        const char *classname;
    3839};
    3940
    40 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, 
     41static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx,
    4142                                 struct ldb_message *msg,
    4243                                 const char **name, uint32_t *type,
     
    4647        uint32_t value_type;
    4748
    48         if (name != NULL)
     49        if (name != NULL) {
    4950                *name = talloc_strdup(mem_ctx,
    5051                                      ldb_msg_find_attr_as_string(msg, "value",
    51                                       NULL));
     52                                      ""));
     53        }
    5254
    5355        value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
    54         *type = value_type; 
     56        *type = value_type;
    5557
    5658        val = ldb_msg_find_ldb_val(msg, "data");
     
    6062        case REG_SZ:
    6163        case REG_EXPAND_SZ:
    62                 if (val != NULL)
     64                if (val != NULL) {
     65                        /* The data should be provided as UTF16 string */
    6366                        convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16,
    64                                                      val->data, val->length,
    65                                                      (void **)&data->data, &data->length, false);
    66                 else {
     67                                              val->data, val->length,
     68                                              (void **)&data->data, &data->length, false);
     69                } else {
    6770                        data->data = NULL;
    6871                        data->length = 0;
     
    7073                break;
    7174
    72         case REG_BINARY:
    73                 if (val != NULL)
    74                         *data = data_blob_talloc(mem_ctx, val->data, val->length);
    75                 else {
     75        case REG_DWORD:
     76        case REG_DWORD_BIG_ENDIAN:
     77                if (val != NULL) {
     78                        /* The data is a plain DWORD */
     79                        uint32_t tmp = strtoul((char *)val->data, NULL, 0);
     80                        data->data = talloc_size(mem_ctx, sizeof(uint32_t));
     81                        if (data->data != NULL) {
     82                                SIVAL(data->data, 0, tmp);
     83                        }
     84                        data->length = sizeof(uint32_t);
     85                } else {
    7686                        data->data = NULL;
    7787                        data->length = 0;
     
    7989                break;
    8090
    81         case REG_DWORD: {
    82                 uint32_t tmp = strtoul((char *)val->data, NULL, 0);
    83                 *data = data_blob_talloc(mem_ctx, &tmp, 4);
     91        case REG_QWORD:
     92                if (val != NULL) {
     93                        /* The data is a plain QWORD */
     94                        uint64_t tmp = strtoull((char *)val->data, NULL, 0);
     95                        data->data = talloc_size(mem_ctx, sizeof(uint64_t));
     96                        if (data->data != NULL) {
     97                                SBVAL(data->data, 0, tmp);
     98                        }
     99                        data->length = sizeof(uint64_t);
     100                } else {
     101                        data->data = NULL;
     102                        data->length = 0;
    84103                }
    85104                break;
    86105
     106        case REG_BINARY:
    87107        default:
    88                 *data = data_blob_talloc(mem_ctx, val->data, val->length);
     108                if (val != NULL) {
     109                        data->data = talloc_memdup(mem_ctx, val->data,
     110                                                   val->length);
     111                        data->length = val->length;
     112                } else {
     113                        data->data = NULL;
     114                        data->length = 0;
     115                }
    89116                break;
    90117        }
     
    96123                                              uint32_t type, DATA_BLOB data)
    97124{
    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));
     125        struct ldb_message *msg;
     126        char *name_dup, *type_str;
     127        int ret;
     128
     129        msg = talloc_zero(mem_ctx, struct ldb_message);
     130        if (msg == NULL) {
     131                return NULL;
     132        }
     133
     134        name_dup = talloc_strdup(msg, name);
     135        if (name_dup == NULL) {
     136                talloc_free(msg);
     137                return NULL;
     138        }
     139
     140        ret = ldb_msg_add_string(msg, "value", name_dup);
     141        if (ret != LDB_SUCCESS) {
     142                talloc_free(msg);
     143                return NULL;
     144        }
    103145
    104146        switch (type) {
    105147        case REG_SZ:
    106148        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);
     149                if ((data.length > 0) && (data.data != NULL)) {
     150                        struct ldb_val *val;
     151                        bool ret2 = false;
     152
     153                        val = talloc_zero(msg, struct ldb_val);
     154                        if (val == NULL) {
     155                                talloc_free(msg);
     156                                return NULL;
     157                        }
     158
     159                        /* The data is provided as UTF16 string */
     160                        ret2 = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8,
     161                                                     (void *)data.data, data.length,
     162                                                     (void **)&val->data, &val->length,
     163                                                     false);
     164                        if (ret2) {
     165                                ret = ldb_msg_add_value(msg, "data", val, NULL);
     166                        } else {
     167                                /* workaround for non-standard data */
     168                                ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
     169                        }
    113170                } else {
    114                         ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
     171                        ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
    115172                }
    116173                break;
    117174
     175        case REG_DWORD:
     176        case REG_DWORD_BIG_ENDIAN:
     177                if ((data.length > 0) && (data.data != NULL)) {
     178                        if (data.length == sizeof(uint32_t)) {
     179                                char *conv_str;
     180
     181                                conv_str = talloc_asprintf(msg, "0x%8.8x",
     182                                                           IVAL(data.data, 0));
     183                                if (conv_str == NULL) {
     184                                        talloc_free(msg);
     185                                        return NULL;
     186                                }
     187                                ret = ldb_msg_add_string(msg, "data", conv_str);
     188                        } else {
     189                                /* workaround for non-standard data */
     190                                talloc_free(msg);
     191                                return NULL;
     192                        }
     193                } else {
     194                        ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
     195                }
     196                break;
     197
     198        case REG_QWORD:
     199                if ((data.length > 0) && (data.data != NULL)) {
     200                        if (data.length == sizeof(uint64_t)) {
     201                                char *conv_str;
     202
     203                                conv_str = talloc_asprintf(msg, "0x%16.16llx",
     204                                                           (unsigned long long)BVAL(data.data, 0));
     205                                if (conv_str == NULL) {
     206                                        talloc_free(msg);
     207                                        return NULL;
     208                                }
     209                                ret = ldb_msg_add_string(msg, "data", conv_str);
     210                        } else {
     211                                /* workaround for non-standard data */
     212                                talloc_free(msg);
     213                                return NULL;
     214
     215                        }
     216                } else {
     217                        ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
     218                }
     219                break;
     220
    118221        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);
     222        default:
     223                if ((data.length > 0) && (data.data != NULL)) {
     224                        ret = ldb_msg_add_value(msg, "data", &data, NULL);
     225                } else {
     226                        ret = ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
     227                }
    123228                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);
     229        }
     230
     231        if (ret != LDB_SUCCESS) {
     232                talloc_free(msg);
     233                return NULL;
     234        }
     235
     236        type_str = talloc_asprintf(mem_ctx, "%u", type);
     237        if (type_str == NULL) {
     238                talloc_free(msg);
     239                return NULL;
     240        }
     241
     242        ret = ldb_msg_add_string(msg, "type", type_str);
     243        if (ret != LDB_SUCCESS) {
     244                talloc_free(msg);
     245                return NULL;
     246        }
    137247
    138248        return msg;
     
    167277                                      const char *path, const char *add)
    168278{
    169         TALLOC_CTX *local_ctx;
    170279        struct ldb_dn *ret;
    171         char *mypath = talloc_strdup(mem_ctx, path);
     280        char *mypath;
    172281        char *begin;
    173282        struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
    174283        struct ldb_context *ldb = kd->ldb;
    175284
    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         }
     285        mypath = talloc_strdup(mem_ctx, path);
     286        if (mypath == NULL) {
     287                return NULL;
     288        }
     289
     290        ret = ldb_dn_new(mem_ctx, ldb, add);
    183291        if (!ldb_dn_validate(ret)) {
    184292                talloc_free(ret);
    185                 talloc_free(local_ctx);
    186293                return NULL;
    187294        }
    188295
    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) {
     296        if (!ldb_dn_add_base(ret, kd->dn)) {
     297                talloc_free(ret);
     298                return NULL;
     299        }
     300
     301        while (mypath[0] != '\0') {
     302                begin = strchr(mypath, '\\');
     303                if (begin != NULL) {
    208304                        *begin = '\0';
     305                }
     306
     307                if (!ldb_dn_add_child_fmt(ret, "key=%s",
     308                                          reg_ldb_escape(mem_ctx, mypath))) {
     309                        talloc_free(ret);
     310                        return NULL;
     311                }
     312
     313                if (begin != NULL) {
     314                        mypath = begin + 1;
    209315                } else {
    210316                        break;
    211317                }
    212318        }
    213 
    214         ldb_dn_add_base(ret, kd->dn);
    215 
    216         talloc_free(local_ctx);
    217319
    218320        return ret;
     
    225327        int ret;
    226328
    227         ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL, NULL, "(key=*)");
    228 
     329        ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
     330                         NULL, "(key=*)");
    229331        if (ret != LDB_SUCCESS) {
    230332                DEBUG(0, ("Error getting subkeys for '%s': %s\n",
     
    248350        ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL,
    249351                         NULL, "(value=*)");
    250 
    251352        if (ret != LDB_SUCCESS) {
    252353                DEBUG(0, ("Error getting values for '%s': %s\n",
     
    269370                                   NTTIME *last_mod_time)
    270371{
    271         struct ldb_message_element *el;
    272372        struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
    273        
     373
    274374        /* Initialization */
    275375        if (name != NULL)
    276376                *name = NULL;
    277377        if (classname != NULL)
    278                 *classname = NULL; /* TODO: Store properly */
     378                *classname = NULL;
    279379        if (last_mod_time != NULL)
    280380                *last_mod_time = 0; /* TODO: we need to add this to the
     
    289389                return WERR_NO_MORE_ITEMS;
    290390
    291         el = ldb_msg_find_element(kd->subkeys[idx], "key");
    292         SMB_ASSERT(el != NULL);
    293         SMB_ASSERT(el->num_values != 0);
    294 
    295391        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,
    302                                   const char **name, uint32_t *data_type,
    303                                    DATA_BLOB *data)
     392                *name = talloc_strdup(mem_ctx,
     393                                      ldb_msg_find_attr_as_string(kd->subkeys[idx], "key", NULL));
     394        if (classname != NULL)
     395                *classname = talloc_strdup(mem_ctx,
     396                                           ldb_msg_find_attr_as_string(kd->subkeys[idx], "classname", NULL));
     397
     398        return WERR_OK;
     399}
     400
     401static WERROR ldb_get_default_value(TALLOC_CTX *mem_ctx,
     402                                    const struct hive_key *k,
     403                                    const char **name, uint32_t *data_type,
     404                                    DATA_BLOB *data)
    304405{
    305406        struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
     
    309410        int ret;
    310411
    311         ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs, "%s", "");
     412        ret = ldb_search(c, mem_ctx, &res, kd->dn, LDB_SCOPE_BASE, attrs, "(dn=*)");
    312413
    313414        if (ret != LDB_SUCCESS) {
     
    317418        }
    318419
    319         if (res->count == 0 || res->msgs[0]->num_elements == 0)
     420        if (res->count == 0 || res->msgs[0]->num_elements == 0) {
     421                talloc_free(res);
    320422                return WERR_BADFILE;
    321 
    322         reg_ldb_unpack_value(mem_ctx,
    323                  res->msgs[0], name, data_type, data);
     423        }
     424
     425        if ((data_type != NULL) && (data != NULL)) {
     426                reg_ldb_unpack_value(mem_ctx, res->msgs[0], name, data_type,
     427                                     data);
     428        }
    324429
    325430        talloc_free(res);
     
    329434
    330435static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
    331                                   int idx, const char **name,
     436                                  uint32_t idx, const char **name,
    332437                                  uint32_t *data_type, DATA_BLOB *data)
    333438{
    334439        struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
    335440
    336         /* if default value exists, give it back */
     441        /* if the default value exists, give it back */
    337442        if (W_ERROR_IS_OK(ldb_get_default_value(mem_ctx, k, name, data_type,
    338443                data))) {
     
    361466{
    362467        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 */
     468        const char *res_name;
     469        uint32_t idx;
     470
     471        /* the default value was requested, give it back */
     472        if (name[0] == '\0') {
    370473                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;
     474        }
     475
     476        /* Do the search if necessary */
     477        if (kd->values == NULL) {
     478                W_ERROR_NOT_OK_RETURN(cache_values(kd));
     479        }
     480
     481        for (idx = 0; idx < kd->value_count; idx++) {
     482                res_name = ldb_msg_find_attr_as_string(kd->values[idx], "value",
     483                                                       "");
     484                if (ldb_attr_cmp(name, res_name) == 0) {
     485                        reg_ldb_unpack_value(mem_ctx, kd->values[idx], NULL,
     486                                             data_type, data);
     487                        return WERR_OK;
     488                }
     489        }
     490
     491        return WERR_BADFILE;
    392492}
    393493
     
    396496{
    397497        struct ldb_result *res;
    398         struct ldb_dn *ldap_path;
     498        struct ldb_dn *ldb_path;
    399499        int ret;
    400500        struct ldb_key_data *newkd;
     
    402502        struct ldb_context *c = kd->ldb;
    403503
    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=*)");
     504        ldb_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
     505        W_ERROR_HAVE_NO_MEMORY(ldb_path);
     506
     507        ret = ldb_search(c, mem_ctx, &res, ldb_path, LDB_SCOPE_BASE, NULL, "(key=*)");
    407508
    408509        if (ret != LDB_SUCCESS) {
    409510                DEBUG(3, ("Error opening key '%s': %s\n",
    410                         ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
     511                        ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
    411512                return WERR_FOOBAR;
    412513        } else if (res->count == 0) {
    413514                DEBUG(3, ("Key '%s' not found\n",
    414                         ldb_dn_get_linearized(ldap_path)));
     515                        ldb_dn_get_linearized(ldb_path)));
    415516                talloc_free(res);
    416517                return WERR_BADFILE;
     
    418519
    419520        newkd = talloc_zero(mem_ctx, struct ldb_key_data);
     521        W_ERROR_HAVE_NO_MEMORY(newkd);
    420522        newkd->key.ops = &reg_backend_ldb;
    421523        newkd->ldb = talloc_reference(newkd, kd->ldb);
    422         newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
     524        newkd->dn = ldb_dn_copy(newkd, res->msgs[0]->dn);
     525        newkd->classname = talloc_steal(newkd,
     526                                        ldb_msg_find_attr_as_string(res->msgs[0], "classname", NULL));
     527
     528        talloc_free(res);
    423529
    424530        *key = (struct hive_key *)newkd;
     
    442548
    443549        wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx,
    444                                 location, session_info, credentials, 0, NULL);
     550                                location, session_info, credentials, 0);
    445551
    446552        if (wrap == NULL) {
     
    477583{
    478584        struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent);
     585        struct ldb_dn *ldb_path;
    479586        struct ldb_message *msg;
    480587        struct ldb_key_data *newkd;
    481588        int ret;
    482589
     590        ldb_path = reg_path_to_ldb(mem_ctx, parent, name, NULL);
     591        W_ERROR_HAVE_NO_MEMORY(ldb_path);
     592
    483593        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));
     594        W_ERROR_HAVE_NO_MEMORY(msg);
     595
     596        msg->dn = ldb_path;
     597
     598        ldb_msg_add_string(msg, "key", name);
     599        if (classname != NULL) {
     600                ldb_msg_add_string(msg, "classname", classname);
     601        }
    491602
    492603        ret = ldb_add(parentkd->ldb, msg);
     604
     605        talloc_free(msg);
     606
    493607        if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
    494608                return WERR_ALREADY_EXISTS;
     
    500614        }
    501615
    502         DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn)));
     616        DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(ldb_path)));
    503617
    504618        newkd = talloc_zero(mem_ctx, struct ldb_key_data);
     619        W_ERROR_HAVE_NO_MEMORY(newkd);
    505620        newkd->ldb = talloc_reference(newkd, parentkd->ldb);
    506621        newkd->key.ops = &reg_backend_ldb;
    507         newkd->dn = talloc_steal(newkd, msg->dn);
     622        newkd->dn = talloc_steal(newkd, ldb_path);
     623        newkd->classname = talloc_steal(newkd, classname);
    508624
    509625        *newkey = (struct hive_key *)newkd;
     
    516632}
    517633
    518 static WERROR ldb_del_value (struct hive_key *key, const char *child)
     634static WERROR ldb_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
     635                            const char *child)
    519636{
    520637        int ret;
    521638        struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
    522         TALLOC_CTX *mem_ctx;
    523639        struct ldb_message *msg;
    524640        struct ldb_dn *childdn;
    525641
    526         if (strlen(child) == 0) {
     642        if (child[0] == '\0') {
    527643                /* default value */
    528                 mem_ctx = talloc_init("ldb_del_value");
    529 
    530644                msg = talloc_zero(mem_ctx, struct ldb_message);
     645                W_ERROR_HAVE_NO_MEMORY(msg);
    531646                msg->dn = ldb_dn_copy(msg, kd->dn);
     647                W_ERROR_HAVE_NO_MEMORY(msg->dn);
    532648                ldb_msg_add_empty(msg, "data", LDB_FLAG_MOD_DELETE, NULL);
    533649                ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_DELETE, NULL);
    534650
    535651                ret = ldb_modify(kd->ldb, msg);
     652
     653                talloc_free(msg);
     654
    536655                if (ret != LDB_SUCCESS) {
    537656                        DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
    538                         talloc_free(mem_ctx);
    539657                        return WERR_FOOBAR;
    540658                }
    541 
    542                 talloc_free(mem_ctx);
    543659        } else {
    544660                /* normal value */
     
    570686}
    571687
    572 static WERROR ldb_del_key(const struct hive_key *key, const char *name)
    573 {
    574         int i, ret;
     688static WERROR ldb_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *key,
     689                          const char *name)
     690{
     691        unsigned int i;
     692        int ret;
    575693        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");
     694        struct ldb_dn *ldb_path;
    578695        struct ldb_context *c = parentkd->ldb;
    579696        struct ldb_result *res_keys;
     
    585702        werr = ldb_open_key(mem_ctx, key, name, &hk);
    586703        if (!W_ERROR_IS_OK(werr)) {
    587                 talloc_free(mem_ctx);
    588704                return werr;
    589705        }
    590706
    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         }
     707        ldb_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
     708        W_ERROR_HAVE_NO_MEMORY(ldb_path);
    596709
    597710        /* Search for subkeys */
    598         ret = ldb_search(c, mem_ctx, &res_keys, ldap_path, LDB_SCOPE_ONELEVEL,
     711        ret = ldb_search(c, mem_ctx, &res_keys, ldb_path, LDB_SCOPE_ONELEVEL,
    599712                         NULL, "(key=*)");
    600713
    601714        if (ret != LDB_SUCCESS) {
    602715                DEBUG(0, ("Error getting subkeys for '%s': %s\n",
    603                       ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
    604                 talloc_free(mem_ctx);
     716                      ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
    605717                return WERR_FOOBAR;
    606718        }
    607719
    608720        /* Search for values */
    609         ret = ldb_search(c, mem_ctx, &res_vals, ldap_path, LDB_SCOPE_ONELEVEL,
     721        ret = ldb_search(c, mem_ctx, &res_vals, ldb_path, LDB_SCOPE_ONELEVEL,
    610722                         NULL, "(value=*)");
    611723
    612724        if (ret != LDB_SUCCESS) {
    613725                DEBUG(0, ("Error getting values for '%s': %s\n",
    614                       ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
    615                 talloc_free(mem_ctx);
     726                      ldb_dn_get_linearized(ldb_path), ldb_errstring(c)));
    616727                return WERR_FOOBAR;
    617728        }
     
    622733        if (ret != LDB_SUCCESS) {
    623734                DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
    624                 talloc_free(mem_ctx);
    625735                return WERR_FOOBAR;
    626736        }
     
    631741                for (i = 0; i < res_keys->count; i++)
    632742                {
    633                         werr = ldb_del_key(hk, ldb_msg_find_attr_as_string(
     743                        werr = ldb_del_key(mem_ctx, hk,
     744                                           ldb_msg_find_attr_as_string(
    634745                                                        res_keys->msgs[i],
    635746                                                        "key", NULL));
    636747                        if (!W_ERROR_IS_OK(werr)) {
    637748                                ret = ldb_transaction_cancel(c);
    638                                 talloc_free(mem_ctx);
    639749                                return werr;
    640750                        }
     
    644754                for (i = 0; i < res_vals->count; i++)
    645755                {
    646                         werr = ldb_del_value(hk, ldb_msg_find_attr_as_string(
     756                        werr = ldb_del_value(mem_ctx, hk,
     757                                             ldb_msg_find_attr_as_string(
    647758                                                        res_vals->msgs[i],
    648759                                                        "value", NULL));
    649760                        if (!W_ERROR_IS_OK(werr)) {
    650761                                ret = ldb_transaction_cancel(c);
    651                                 talloc_free(mem_ctx);
    652762                                return werr;
    653763                        }
    654764                }
    655765        }
     766        talloc_free(res_keys);
     767        talloc_free(res_vals);
    656768
    657769        /* Delete the key itself */
    658         ret = ldb_delete(c, ldap_path);
     770        ret = ldb_delete(c, ldb_path);
    659771
    660772        if (ret != LDB_SUCCESS)
     
    662774                DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
    663775                ret = ldb_transaction_cancel(c);
    664                 talloc_free(mem_ctx);
    665776                return WERR_FOOBAR;
    666777        }
     
    673784                DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
    674785                ret = ldb_transaction_cancel(c);
    675                 talloc_free(mem_ctx);
    676                 return WERR_FOOBAR;
    677         }
    678 
    679         talloc_free(mem_ctx);
     786                return WERR_FOOBAR;
     787        }
    680788
    681789        /* reset cache */
     
    692800        struct ldb_message *msg;
    693801        struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
     802        unsigned int i;
    694803        int ret;
    695804        TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
    696805
    697806        msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
     807        W_ERROR_HAVE_NO_MEMORY(msg);
     808
    698809        msg->dn = ldb_dn_copy(msg, kd->dn);
    699        
    700         if (strlen(name) > 0) {
     810        W_ERROR_HAVE_NO_MEMORY(msg->dn);
     811
     812        if (name[0] != '\0') {
    701813                /* For a default value, we add/overwrite the attributes to/of the hive.
    702                    For a normal value, we create new childs. */
     814                   For a normal value, we create a new child. */
    703815                if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
    704816                                  reg_ldb_escape(mem_ctx, name)))
     
    709821        }
    710822
    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         }
     823        /* Try first a "modify" and if this doesn't work do try an "add" */
     824        for (i = 0; i < msg->num_elements; i++) {
     825                if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) {
     826                        msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
     827                }
     828        }
     829        ret = ldb_modify(kd->ldb, msg);
     830        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     831                i = 0;
     832                while (i < msg->num_elements) {
     833                        if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE) {
     834                                ldb_msg_remove_element(msg, &msg->elements[i]);
     835                        } else {
     836                                ++i;
     837                        }
     838                }
     839                ret = ldb_add(kd->ldb, msg);
     840        }
     841        if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
     842                /* ignore this -> the value didn't exist and also now doesn't */
     843                ret = LDB_SUCCESS;
     844        }
     845
     846        talloc_free(msg);
    720847
    721848        if (ret != LDB_SUCCESS) {
     
    744871{
    745872        struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
     873        uint32_t default_value_type = REG_NONE;
     874        DATA_BLOB default_value = { NULL, 0 };
     875        WERROR werr;
    746876
    747877        /* Initialization */
     
    761891                *max_valbufsize = 0;
    762892
     893        /* We need this to get the default value (if it exists) for counting
     894         * the values under the key and for finding out the longest value buffer
     895         * size. If no default value exists the DATA_BLOB "default_value" will
     896         * remain { NULL, 0 }. */
     897        werr = ldb_get_default_value(mem_ctx, key, NULL, &default_value_type,
     898                                     &default_value);
     899        if ((!W_ERROR_IS_OK(werr)) && (!W_ERROR_EQUAL(werr, WERR_BADFILE))) {
     900                return werr;
     901        }
     902
    763903        if (kd->subkeys == NULL) {
    764904                W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
    765905        }
    766 
    767906        if (kd->values == NULL) {
    768907                W_ERROR_NOT_OK_RETURN(cache_values(kd));
    769908        }
    770909
     910        if (classname != NULL) {
     911                *classname = kd->classname;
     912        }
     913
    771914        if (num_subkeys != NULL) {
    772915                *num_subkeys = kd->subkey_count;
     
    774917        if (num_values != NULL) {
    775918                *num_values = kd->value_count;
     919                /* also consider the default value if it exists */
     920                if (default_value.data != NULL) {
     921                        ++(*num_values);
     922                }
    776923        }
    777924
    778925
    779926        if (max_subkeynamelen != NULL) {
    780                 int i;
     927                unsigned int i;
    781928                struct ldb_message_element *el;
    782 
    783                 *max_subkeynamelen = 0;
    784929
    785930                for (i = 0; i < kd->subkey_count; i++) {
     
    790935
    791936        if (max_valnamelen != NULL || max_valbufsize != NULL) {
    792                 int i;
     937                unsigned int i;
    793938                struct ldb_message_element *el;
    794939                W_ERROR_NOT_OK_RETURN(cache_values(kd));
    795940
    796                 if (max_valbufsize != NULL)
    797                         *max_valbufsize = 0;
    798 
    799                 if (max_valnamelen != NULL)
    800                         *max_valnamelen = 0;
     941                /* also consider the default value if it exists */
     942                if ((max_valbufsize != NULL) && (default_value.data != NULL)) {
     943                                *max_valbufsize = MAX(*max_valbufsize,
     944                                                      default_value.length);
     945                }
    801946
    802947                for (i = 0; i < kd->value_count; i++) {
     
    809954                                uint32_t data_type;
    810955                                DATA_BLOB data;
    811                                 reg_ldb_unpack_value(mem_ctx, 
    812                                                      kd->values[i], NULL, 
     956                                reg_ldb_unpack_value(mem_ctx,
     957                                                     kd->values[i], NULL,
    813958                                                     &data_type, &data);
    814959                                *max_valbufsize = MAX(*max_valbufsize, data.length);
     
    817962                }
    818963        }
     964
     965        talloc_free(default_value.data);
    819966
    820967        return WERR_OK;
Note: See TracChangeset for help on using the changeset viewer.