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/regf.c

    r414 r745  
    33   Registry backend for REGF files
    44   Copyright (C) 2005-2007 Jelmer Vernooij, jelmer@samba.org
    5    Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl
     5   Copyright (C) 2006-2010 Wilco Baan Hofman, wilco@baanhofman.nl
    66
    77   This program is free software; you can redistribute it and/or modify
     
    5050        struct hbin_block **hbins;
    5151        struct regf_hdr *header;
    52         struct smb_iconv_convenience *iconv_convenience;
     52        time_t last_write;
    5353};
    5454
    55 static WERROR regf_save_hbin(struct regf_data *data);
     55static WERROR regf_save_hbin(struct regf_data *data, bool flush);
    5656
    5757struct regf_key_data {
     
    6565                                         uint32_t offset, uint32_t *rel_offset)
    6666{
    67         int i;
     67        unsigned int i;
    6868
    6969        for (i = 0; data->hbins[i]; i++) {
     
    8787{
    8888        uint32_t checksum = 0, x;
    89         int i;
     89        unsigned int i;
    9090
    9191        for (i = 0; i < 0x01FB; i+= 4) {
     
    112112
    113113        if (hbin == NULL) {
    114                 DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset));
     114                DEBUG(1, ("Can't find HBIN at 0x%04x\n", offset));
    115115                return ret;
    116116        }
     
    135135                         TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p)
    136136{
    137         struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     137        struct tdr_pull *pull = tdr_pull_init(regf);
    138138
    139139        pull->data = hbin_get(regf, offset);
     
    160160{
    161161        DATA_BLOB ret;
    162         uint32_t rel_offset = -1; /* Relative offset ! */
     162        uint32_t rel_offset = (uint32_t) -1; /* Relative offset ! */
    163163        struct hbin_block *hbin = NULL;
    164         int i;
     164        unsigned int i;
    165165
    166166        *offset = 0;
     
    218218                DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n",
    219219                        size));
     220
     221                /* Add extra hbin block */
    220222                data->hbins = talloc_realloc(data, data->hbins,
    221223                                             struct hbin_block *, i+2);
     
    226228                data->hbins[i+1] = NULL;
    227229
     230                /* Set hbin data */
    228231                hbin->HBIN_ID = talloc_strdup(hbin, "hbin");
    229232                hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next);
    230233                hbin->offset_to_next = 0x1000;
    231234                hbin->unknown[0] = 0;
    232                 hbin->unknown[0] = 0;
     235                hbin->unknown[1] = 0;
    233236                unix_to_nt_time(&hbin->last_change, time(NULL));
    234237                hbin->block_size = hbin->offset_to_next;
    235238                hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20);
    236 
     239                /* Update the regf header */
     240                data->header->last_block += hbin->offset_to_next;
     241
     242                /* Set the next block to it's proper size and set the
     243                 * rel_offset for this block */
     244                SIVAL(hbin->data, size, hbin->block_size - size - 0x20);
    237245                rel_offset = 0x0;
    238                 SIVAL(hbin->data, size, hbin->block_size - size - 0x20);
    239246        }
    240247
     
    262269        memcpy(dest.data, blob.data, blob.length);
    263270
     271        /* Make sure that we have no tailing garbage in the block */
     272        if (dest.length > blob.length) {
     273                memset(dest.data + blob.length, 0, dest.length - blob.length);
     274        }
     275
    264276        return ret;
    265277}
     
    268280                               tdr_push_fn_t push_fn, void *p)
    269281{
    270         struct tdr_push *push = tdr_push_init(data, data->iconv_convenience);
     282        struct tdr_push *push = tdr_push_init(data);
    271283        uint32_t ret;
    272284
     
    311323
    312324        /* If the next block is free, merge into big free block */
    313         if (rel_offset + size < hbin->offset_to_next) {
     325        if (rel_offset + size < hbin->offset_to_next - 0x20) {
    314326                next_size = IVALS(hbin->data, rel_offset+size);
    315327                if (next_size > 0) {
     
    336348        int32_t needed_size;
    337349        int32_t possible_size;
    338         int i;
     350        unsigned int i;
    339351
    340352        SMB_ASSERT(orig_offset > 0);
     
    395407                                      uint32_t orig_offset, void *p)
    396408{
    397         struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience);
     409        struct tdr_push *push = tdr_push_init(regf);
    398410        uint32_t ret;
    399411
     
    451463                                                    (char*)data.data,
    452464                                                    private_data->nk->clsname_length);
     465                        W_ERROR_HAVE_NO_MEMORY(*classname);
    453466                } else
    454467                        *classname = NULL;
     
    485498        if (!hbin_get_tdr(regf, offset, nk,
    486499                          (tdr_pull_fn_t)tdr_pull_nk_block, nk)) {
    487                 DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
     500                DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n", offset));
    488501                return NULL;
    489502        }
     
    500513
    501514static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
    502                              int idx, const char **name,
     515                             uint32_t idx, const char **name,
    503516                             uint32_t *data_type, DATA_BLOB *data)
    504517{
     
    515528        tmp = hbin_get(regf, private_data->nk->values_offset);
    516529        if (!tmp.data) {
    517                 DEBUG(0, ("Unable to find value list\n"));
     530                DEBUG(0, ("Unable to find value list at 0x%x\n",
     531                                private_data->nk->values_offset));
    518532                return WERR_GENERAL_FAILURE;
    519533        }
     
    530544        if (!hbin_get_tdr(regf, vk_offset, vk,
    531545                          (tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
    532                 DEBUG(0, ("Unable to get VK block at %d\n", vk_offset));
     546                DEBUG(0, ("Unable to get VK block at 0x%x\n", vk_offset));
    533547                talloc_free(vk);
    534548                return WERR_GENERAL_FAILURE;
     
    536550
    537551        /* FIXME: name character set ?*/
    538         if (name != NULL)
     552        if (name != NULL) {
    539553                *name = talloc_strndup(ctx, vk->data_name, vk->name_length);
     554                W_ERROR_HAVE_NO_MEMORY(*name);
     555        }
    540556
    541557        if (data_type != NULL)
     
    543559
    544560        if (vk->data_length & 0x80000000) {
    545                 vk->data_length &=~0x80000000;
    546                 data->data = (uint8_t *)talloc_memdup(ctx, (uint8_t *)&vk->data_offset, vk->data_length);
    547                 data->length = vk->data_length;
     561                /* this is data of type "REG_DWORD" or "REG_DWORD_BIG_ENDIAN" */
     562                data->data = talloc_size(ctx, sizeof(uint32_t));
     563                W_ERROR_HAVE_NO_MEMORY(data->data);
     564                SIVAL(data->data, 0, vk->data_offset);
     565                data->length = sizeof(uint32_t);
    548566        } else {
    549567                *data = hbin_get(regf, vk->data_offset);
     
    563581                                     uint32_t *type, DATA_BLOB *data)
    564582{
    565         int i;
     583        unsigned int i;
    566584        const char *vname;
    567585        WERROR error;
     
    598616                return WERR_NO_MORE_ITEMS;
    599617
     618        /* Make sure that we don't crash if the key is empty */
     619        if (nk->subkeys_offset == -1) {
     620                return WERR_NO_MORE_ITEMS;
     621        }
     622
    600623        data = hbin_get(private_data->hive, nk->subkeys_offset);
    601624        if (!data.data) {
    602                 DEBUG(0, ("Unable to find subkey list\n"));
     625                DEBUG(0, ("Unable to find subkey list at 0x%x\n",
     626                        nk->subkeys_offset));
    603627                return WERR_GENERAL_FAILURE;
    604628        }
     
    606630        if (!strncmp((char *)data.data, "li", 2)) {
    607631                struct li_block li;
    608                 struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
     632                struct tdr_pull *pull = tdr_pull_init(private_data->hive);
    609633
    610634                DEBUG(10, ("Subkeys in LI list\n"));
     
    627651        } else if (!strncmp((char *)data.data, "lf", 2)) {
    628652                struct lf_block lf;
    629                 struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
     653                struct tdr_pull *pull = tdr_pull_init(private_data->hive);
    630654
    631655                DEBUG(10, ("Subkeys in LF list\n"));
     
    648672        } else if (!strncmp((char *)data.data, "lh", 2)) {
    649673                struct lh_block lh;
    650                 struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
     674                struct tdr_pull *pull = tdr_pull_init(private_data->hive);
    651675
    652676                DEBUG(10, ("Subkeys in LH list\n"));
     
    668692        } else if (!strncmp((char *)data.data, "ri", 2)) {
    669693                struct ri_block ri;
    670                 struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     694                struct tdr_pull *pull = tdr_pull_init(ctx);
    671695                uint16_t i;
    672696                uint16_t sublist_count = 0;
     
    769793                                                    (char*)db.data,
    770794                                                    ret->nk->clsname_length);
     795                        W_ERROR_HAVE_NO_MEMORY(*classname);
    771796                } else
    772797                        *classname = NULL;
     
    801826        }
    802827
    803         pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     828        pull = tdr_pull_init(ctx);
    804829
    805830        pull->data = subkey_data;
     
    836861        uint32_t key_off = 0;
    837862
     863        /* Make sure that we don't crash if the key is empty */
     864        if (nk->subkeys_offset == -1) {
     865                return WERR_BADFILE;
     866        }
     867
    838868        data = hbin_get(private_data->hive, nk->subkeys_offset);
    839869        if (!data.data) {
     
    844874        if (!strncmp((char *)data.data, "li", 2)) {
    845875                struct li_block li;
    846                 struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     876                struct tdr_pull *pull = tdr_pull_init(ctx);
    847877                uint16_t i;
    848878
     
    875905        } else if (!strncmp((char *)data.data, "lf", 2)) {
    876906                struct lf_block lf;
    877                 struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     907                struct tdr_pull *pull = tdr_pull_init(ctx);
    878908                uint16_t i;
    879909
     
    910940        } else if (!strncmp((char *)data.data, "lh", 2)) {
    911941                struct lh_block lh;
    912                 struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     942                struct tdr_pull *pull = tdr_pull_init(ctx);
    913943                uint16_t i;
    914944                uint32_t hash;
     
    947977        } else if (!strncmp((char *)data.data, "ri", 2)) {
    948978                struct ri_block ri;
    949                 struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
     979                struct tdr_pull *pull = tdr_pull_init(ctx);
    950980                uint16_t i, j;
    951981
     
    10521082
    10531083        /* Push the security descriptor to a blob */
    1054         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL,
     1084        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf,
    10551085                                                          sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {
    10561086                DEBUG(0, ("Unable to push security descriptor\n"));
     
    12051235        data.data = sk.sec_desc;
    12061236        data.length = sk.rec_size;
    1207         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, NULL, *sd,
     1237        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, *sd,
    12081238                                                  (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) {
    12091239                DEBUG(0, ("Error parsing security descriptor\n"));
     
    12891319
    12901320        if (!strncmp((char *)data.data, "li", 2)) {
    1291                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1321                struct tdr_pull *pull = tdr_pull_init(regf);
    12921322                struct li_block li;
     1323                struct nk_block sub_nk;
     1324                int32_t i, j;
    12931325
    12941326                pull->data = data;
     
    13071339                }
    13081340
     1341                /*
     1342                 * Find the position to store the pointer
     1343                 * Extensive testing reveils that at least on windows 7 subkeys
     1344                 * *MUST* be stored in alphabetical order
     1345                 */
     1346                for (i = 0; i < li.key_count; i++) {
     1347                        /* Get the nk */
     1348                        hbin_get_tdr(regf, li.nk_offset[i], regf,
     1349                                        (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
     1350                        if (strcasecmp(name, sub_nk.key_name) < 0) {
     1351                                break;
     1352                        }
     1353                }
     1354
    13091355                li.nk_offset = talloc_realloc(regf, li.nk_offset,
    13101356                                              uint32_t, li.key_count+1);
    13111357                W_ERROR_HAVE_NO_MEMORY(li.nk_offset);
    1312                 li.nk_offset[li.key_count] = key_offset;
     1358
     1359                /* Move everything behind this offset */
     1360                for (j = li.key_count - 1; j >= i; j--) {
     1361                        li.nk_offset[j+1] = li.nk_offset[j];
     1362                }
     1363                       
     1364                li.nk_offset[i] = key_offset;
    13131365                li.key_count++;
    13141366                *ret = hbin_store_tdr_resize(regf,
     
    13181370                talloc_free(li.nk_offset);
    13191371        } else if (!strncmp((char *)data.data, "lf", 2)) {
    1320                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1372                struct tdr_pull *pull = tdr_pull_init(regf);
    13211373                struct lf_block lf;
     1374                struct nk_block sub_nk;
     1375                int32_t i, j;
    13221376
    13231377                pull->data = data;
     
    13311385                SMB_ASSERT(!strncmp(lf.header, "lf", 2));
    13321386
     1387                /*
     1388                 * Find the position to store the hash record
     1389                 * Extensive testing reveils that at least on windows 7 subkeys
     1390                 * *MUST* be stored in alphabetical order
     1391                 */
     1392                for (i = 0; i < lf.key_count; i++) {
     1393                        /* Get the nk */
     1394                        hbin_get_tdr(regf, lf.hr[i].nk_offset, regf,
     1395                                        (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
     1396                        if (strcasecmp(name, sub_nk.key_name) < 0) {
     1397                                break;
     1398                        }
     1399                }
     1400
    13331401                lf.hr = talloc_realloc(regf, lf.hr, struct hash_record,
    13341402                                       lf.key_count+1);
    13351403                W_ERROR_HAVE_NO_MEMORY(lf.hr);
    1336                 lf.hr[lf.key_count].nk_offset = key_offset;
    1337                 lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4);
     1404
     1405                /* Move everything behind this hash record */
     1406                for (j = lf.key_count - 1; j >= i; j--) {
     1407                        lf.hr[j+1] = lf.hr[j];
     1408                }
     1409
     1410                lf.hr[i].nk_offset = key_offset;
     1411                lf.hr[i].hash = talloc_strndup(lf.hr, name, 4);
    13381412                W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash);
    13391413                lf.key_count++;
     
    13441418                talloc_free(lf.hr);
    13451419        } else if (!strncmp((char *)data.data, "lh", 2)) {
    1346                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1420                struct tdr_pull *pull = tdr_pull_init(regf);
    13471421                struct lh_block lh;
     1422                struct nk_block sub_nk;
     1423                int32_t i, j;
    13481424
    13491425                pull->data = data;
     
    13571433                SMB_ASSERT(!strncmp(lh.header, "lh", 2));
    13581434
     1435                /*
     1436                 * Find the position to store the hash record
     1437                 * Extensive testing reveils that at least on windows 7 subkeys
     1438                 * *MUST* be stored in alphabetical order
     1439                 */
     1440                for (i = 0; i < lh.key_count; i++) {
     1441                        /* Get the nk */
     1442                        hbin_get_tdr(regf, lh.hr[i].nk_offset, regf,
     1443                                        (tdr_pull_fn_t) tdr_pull_nk_block, &sub_nk);
     1444                        if (strcasecmp(name, sub_nk.key_name) < 0) {
     1445                                break;
     1446                        }
     1447                }
     1448
    13591449                lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash,
    13601450                                       lh.key_count+1);
    13611451                W_ERROR_HAVE_NO_MEMORY(lh.hr);
    1362                 lh.hr[lh.key_count].nk_offset = key_offset;
    1363                 lh.hr[lh.key_count].base37 = regf_create_lh_hash(name);
     1452
     1453                /* Move everything behind this hash record */
     1454                for (j = lh.key_count - 1; j >= i; j--) {
     1455                        lh.hr[j+1] = lh.hr[j];
     1456                }
     1457
     1458                lh.hr[i].nk_offset = key_offset;
     1459                lh.hr[i].base37 = regf_create_lh_hash(name);
    13641460                lh.key_count++;
    13651461                *ret = hbin_store_tdr_resize(regf,
     
    13931489        if (strncmp((char *)data.data, "li", 2) == 0) {
    13941490                struct li_block li;
    1395                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1491                struct tdr_pull *pull = tdr_pull_init(regf);
    13961492                uint16_t i;
    13971493                bool found_offset = false;
     
    14371533        } else if (strncmp((char *)data.data, "lf", 2) == 0) {
    14381534                struct lf_block lf;
    1439                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1535                struct tdr_pull *pull = tdr_pull_init(regf);
    14401536                uint16_t i;
    14411537                bool found_offset = false;
     
    14831579        } else if (strncmp((char *)data.data, "lh", 2) == 0) {
    14841580                struct lh_block lh;
    1485                 struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
     1581                struct tdr_pull *pull = tdr_pull_init(regf);
    14861582                uint16_t i;
    14871583                bool found_offset = false;
     
    15381634}
    15391635
    1540 static WERROR regf_del_value (struct hive_key *key, const char *name)
     1636static WERROR regf_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key,
     1637                             const char *name)
    15411638{
    15421639        struct regf_key_data *private_data = (struct regf_key_data *)key;
     
    15471644        bool found_offset = false;
    15481645        DATA_BLOB values;
    1549         uint32_t i;
     1646        unsigned int i;
    15501647
    15511648        if (nk->values_offset == -1) {
     
    15921689                              private_data->offset, nk);
    15931690
    1594         return regf_save_hbin(private_data->hive);
    1595 }
    1596 
    1597 
    1598 static WERROR regf_del_key(const struct hive_key *parent, const char *name)
     1691        return regf_save_hbin(private_data->hive, 0);
     1692}
     1693
     1694
     1695static WERROR regf_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
     1696                           const char *name)
    15991697{
    16001698        const struct regf_key_data *private_data =
     
    16231721                char *sk_name;
    16241722                struct hive_key *sk = (struct hive_key *)key;
    1625                 int i = key->nk->num_subkeys;
     1723                unsigned int i = key->nk->num_subkeys;
    16261724                while (i--) {
    16271725                        /* Get subkey information. */
     
    16351733
    16361734                        /* Delete subkey. */
    1637                         error = regf_del_key(sk, sk_name);
     1735                        error = regf_del_key(NULL, sk, sk_name);
    16381736                        if (!W_ERROR_IS_OK(error)) {
    16391737                                DEBUG(0, ("Can't delete key '%s'.\n", sk_name));
     
    16491747                struct hive_key *sk = (struct hive_key *)key;
    16501748                DATA_BLOB data;
    1651                 int i = key->nk->num_values;
     1749                unsigned int i = key->nk->num_values;
    16521750                while (i--) {
    16531751                        /* Get value information. */
     
    16611759
    16621760                        /* Delete value. */
    1663                         error = regf_del_value(sk, val_name);
     1761                        error = regf_del_value(NULL, sk, val_name);
    16641762                        if (!W_ERROR_IS_OK(error)) {
    16651763                                DEBUG(0, ("Can't delete value '%s'.\n", val_name));
     
    16901788        hbin_free(private_data->hive, key->offset);
    16911789
    1692         return regf_save_hbin(private_data->hive);
     1790        return regf_save_hbin(private_data->hive, 0);
    16931791}
    16941792
     
    17171815        nk.num_values = 0;
    17181816        nk.values_offset = -1;
    1719         memset(nk.unk3, 0, 5);
     1817        memset(nk.unk3, 0, sizeof(nk.unk3));
    17201818        nk.clsname_offset = -1; /* FIXME: fill in */
    17211819        nk.clsname_length = 0;
     
    17281826        if (!hbin_get_tdr(regf, regf->header->data_offset, root,
    17291827                          (tdr_pull_fn_t)tdr_pull_nk_block, root)) {
    1730                 DEBUG(0, ("Unable to find HBIN data for offset %d\n",
     1828                DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n",
    17311829                        regf->header->data_offset));
    17321830                return WERR_GENERAL_FAILURE;
     
    17531851        *ret = (struct hive_key *)regf_get_key(ctx, regf, offset);
    17541852
    1755         return regf_save_hbin(private_data->hive);
     1853        DEBUG(9, ("Storing key %s\n", name));
     1854        return regf_save_hbin(private_data->hive, 0);
    17561855}
    17571856
     
    17641863        struct vk_block vk;
    17651864        uint32_t i;
    1766         uint32_t tmp_vk_offset, vk_offset, old_vk_offset = -1;
     1865        uint32_t tmp_vk_offset, vk_offset, old_vk_offset = (uint32_t) -1;
    17671866        DATA_BLOB values;
    17681867
     
    17781877                                          (tdr_pull_fn_t)tdr_pull_vk_block,
    17791878                                          &vk)) {
    1780                                 DEBUG(0, ("Unable to get VK block at %d\n",
     1879                                DEBUG(0, ("Unable to get VK block at 0x%x\n",
    17811880                                        tmp_vk_offset));
    17821881                                return WERR_GENERAL_FAILURE;
     
    17871886                        }
    17881887                }
    1789                 /* Free data, if any */
    1790                 if (!(vk.data_length & 0x80000000)) {
    1791                         hbin_free(regf, vk.data_offset);
    1792                 }
    1793         }
     1888        }
     1889
     1890        /* If it's new, create the vk struct, if it's old, free the old data. */
    17941891        if (old_vk_offset == -1) {
    17951892                vk.header = "vk";
     
    18021899                        vk.flag = 0;
    18031900                }
    1804         }
     1901        } else {
     1902                /* Free data, if any */
     1903                if (!(vk.data_length & 0x80000000)) {
     1904                        hbin_free(regf, vk.data_offset);
     1905                }
     1906        }
     1907
    18051908        /* Set the type and data */
    18061909        vk.data_length = data.length;
    18071910        vk.data_type = type;
    1808         if (type == REG_DWORD) {
     1911        if ((type == REG_DWORD) || (type == REG_DWORD_BIG_ENDIAN)) {
     1912                if (vk.data_length != sizeof(uint32_t)) {
     1913                        DEBUG(0, ("DWORD or DWORD_BIG_ENDIAN value with size other than 4 byte!\n"));
     1914                        return WERR_NOT_SUPPORTED;
     1915                }
    18091916                vk.data_length |= 0x80000000;
    1810                 vk.data_offset = *(uint32_t *)data.data;
     1917                vk.data_offset = IVAL(data.data, 0);
    18111918        } else {
    18121919                /* Store data somewhere */
     
    18641971                              (tdr_push_fn_t) tdr_push_nk_block,
    18651972                              private_data->offset, nk);
    1866         return regf_save_hbin(private_data->hive);
    1867 }
    1868 
    1869 static WERROR regf_save_hbin(struct regf_data *regf)
    1870 {
    1871         struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience);
    1872         int i;
     1973        return regf_save_hbin(private_data->hive, 0);
     1974}
     1975
     1976static WERROR regf_save_hbin(struct regf_data *regf, bool flush)
     1977{
     1978        struct tdr_push *push = tdr_push_init(regf);
     1979        unsigned int i;
    18731980
    18741981        W_ERROR_HAVE_NO_MEMORY(push);
     1982
     1983        /* Only write once every 5 seconds, or when flush is set */
     1984        if (!flush && regf->last_write + 5 >= time(NULL)) {
     1985                return WERR_OK;
     1986        }
     1987
     1988        regf->last_write = time(NULL);
    18751989
    18761990        if (lseek(regf->fd, 0, SEEK_SET) == -1) {
     
    18872001        talloc_free(push);
    18882002
    1889         if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience,
     2003        if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd,
    18902004                                            (tdr_push_fn_t)tdr_push_regf_hdr,
    18912005                                            regf->header))) {
     
    19002014
    19012015        for (i = 0; regf->hbins[i]; i++) {
    1902                 if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience,
     2016                if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd,
    19032017                                                    (tdr_push_fn_t)tdr_push_hbin_block,
    19042018                                                    regf->hbins[i]))) {
     
    19122026
    19132027WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
    1914                             struct smb_iconv_convenience *iconv_convenience,
    19152028                            const char *location,
    19162029                            int minor_version, struct hive_key **key)
     
    19262039
    19272040        regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
    1928 
    1929         regf->iconv_convenience = iconv_convenience;
    19302041
    19312042        W_ERROR_HAVE_NO_MEMORY(regf);
     
    19632074
    19642075        nk.header = "nk";
    1965         nk.type = REG_SUB_KEY;
     2076        nk.type = REG_ROOT_KEY;
    19662077        unix_to_nt_time(&nk.last_change, time(NULL));
    19672078        nk.uk1 = 0;
     
    19972108       
    19982109        /* Push the security descriptor to a blob */
    1999         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL,
     2110        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf,
    20002111                                     sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {
    20012112                DEBUG(0, ("Unable to push security descriptor\n"));
     
    20282139                                               regf->header->data_offset);
    20292140
    2030         error = regf_save_hbin(regf);
     2141        error = regf_save_hbin(regf, 1);
    20312142        if (!W_ERROR_IS_OK(error)) {
    20322143                return error;
     
    20342145       
    20352146        /* We can drop our own reference now that *key will have created one */
    2036         talloc_free(regf);
     2147        talloc_unlink(NULL, regf);
    20372148
    20382149        return WERR_OK;
    20392150}
    20402151
     2152static WERROR regf_flush_key(struct hive_key *key)
     2153{
     2154        struct regf_key_data *private_data = (struct regf_key_data *)key;
     2155        struct regf_data *regf = private_data->hive;
     2156        WERROR error;
     2157
     2158        error = regf_save_hbin(regf, 1);
     2159        if (!W_ERROR_IS_OK(error)) {
     2160                DEBUG(0, ("Failed to flush regf to disk\n"));
     2161                return error;
     2162        }
     2163
     2164        return WERR_OK;
     2165}
     2166
     2167static int regf_destruct(struct regf_data *regf)
     2168{
     2169        WERROR error;
     2170
     2171        /* Write to disk */
     2172        error = regf_save_hbin(regf, 1);
     2173        if (!W_ERROR_IS_OK(error)) {
     2174                DEBUG(0, ("Failed to flush registry to disk\n"));
     2175                return -1;
     2176        }
     2177
     2178        /* Close file descriptor */
     2179        close(regf->fd);
     2180
     2181        return 0;
     2182}
     2183
    20412184WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
    2042                           struct smb_iconv_convenience *iconv_convenience, struct hive_key **key)
     2185                          struct hive_key **key)
    20432186{
    20442187        struct regf_data *regf;
    20452188        struct regf_hdr *regf_hdr;
    20462189        struct tdr_pull *pull;
    2047         int i;
     2190        unsigned int i;
    20482191
    20492192        regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data);
    2050 
    2051         regf->iconv_convenience = iconv_convenience;
    2052 
    20532193        W_ERROR_HAVE_NO_MEMORY(regf);
     2194
     2195        talloc_set_destructor(regf, regf_destruct);
    20542196
    20552197        DEBUG(5, ("Attempting to load registry file\n"));
     
    20652207        }
    20662208
    2067         pull = tdr_pull_init(regf, regf->iconv_convenience);
     2209        pull = tdr_pull_init(regf);
    20682210
    20692211        pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, 0, regf);
     
    21632305        .del_key = regf_del_key,
    21642306        .delete_value = regf_del_value,
     2307        .flush_key = regf_flush_key
    21652308};
Note: See TracChangeset for help on using the changeset viewer.