Changeset 745 for trunk/server/source4/lib/registry/regf.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/lib/registry/regf.c
r414 r745 3 3 Registry backend for REGF files 4 4 Copyright (C) 2005-2007 Jelmer Vernooij, jelmer@samba.org 5 Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl5 Copyright (C) 2006-2010 Wilco Baan Hofman, wilco@baanhofman.nl 6 6 7 7 This program is free software; you can redistribute it and/or modify … … 50 50 struct hbin_block **hbins; 51 51 struct regf_hdr *header; 52 struct smb_iconv_convenience *iconv_convenience;52 time_t last_write; 53 53 }; 54 54 55 static WERROR regf_save_hbin(struct regf_data *data );55 static WERROR regf_save_hbin(struct regf_data *data, bool flush); 56 56 57 57 struct regf_key_data { … … 65 65 uint32_t offset, uint32_t *rel_offset) 66 66 { 67 int i;67 unsigned int i; 68 68 69 69 for (i = 0; data->hbins[i]; i++) { … … 87 87 { 88 88 uint32_t checksum = 0, x; 89 int i;89 unsigned int i; 90 90 91 91 for (i = 0; i < 0x01FB; i+= 4) { … … 112 112 113 113 if (hbin == NULL) { 114 DEBUG(1, ("Can't find HBIN containing0x%04x\n", offset));114 DEBUG(1, ("Can't find HBIN at 0x%04x\n", offset)); 115 115 return ret; 116 116 } … … 135 135 TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) 136 136 { 137 struct tdr_pull *pull = tdr_pull_init(regf , regf->iconv_convenience);137 struct tdr_pull *pull = tdr_pull_init(regf); 138 138 139 139 pull->data = hbin_get(regf, offset); … … 160 160 { 161 161 DATA_BLOB ret; 162 uint32_t rel_offset = -1; /* Relative offset ! */162 uint32_t rel_offset = (uint32_t) -1; /* Relative offset ! */ 163 163 struct hbin_block *hbin = NULL; 164 int i;164 unsigned int i; 165 165 166 166 *offset = 0; … … 218 218 DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", 219 219 size)); 220 221 /* Add extra hbin block */ 220 222 data->hbins = talloc_realloc(data, data->hbins, 221 223 struct hbin_block *, i+2); … … 226 228 data->hbins[i+1] = NULL; 227 229 230 /* Set hbin data */ 228 231 hbin->HBIN_ID = talloc_strdup(hbin, "hbin"); 229 232 hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next); 230 233 hbin->offset_to_next = 0x1000; 231 234 hbin->unknown[0] = 0; 232 hbin->unknown[ 0] = 0;235 hbin->unknown[1] = 0; 233 236 unix_to_nt_time(&hbin->last_change, time(NULL)); 234 237 hbin->block_size = hbin->offset_to_next; 235 238 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); 237 245 rel_offset = 0x0; 238 SIVAL(hbin->data, size, hbin->block_size - size - 0x20);239 246 } 240 247 … … 262 269 memcpy(dest.data, blob.data, blob.length); 263 270 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 264 276 return ret; 265 277 } … … 268 280 tdr_push_fn_t push_fn, void *p) 269 281 { 270 struct tdr_push *push = tdr_push_init(data , data->iconv_convenience);282 struct tdr_push *push = tdr_push_init(data); 271 283 uint32_t ret; 272 284 … … 311 323 312 324 /* 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) { 314 326 next_size = IVALS(hbin->data, rel_offset+size); 315 327 if (next_size > 0) { … … 336 348 int32_t needed_size; 337 349 int32_t possible_size; 338 int i;350 unsigned int i; 339 351 340 352 SMB_ASSERT(orig_offset > 0); … … 395 407 uint32_t orig_offset, void *p) 396 408 { 397 struct tdr_push *push = tdr_push_init(regf , regf->iconv_convenience);409 struct tdr_push *push = tdr_push_init(regf); 398 410 uint32_t ret; 399 411 … … 451 463 (char*)data.data, 452 464 private_data->nk->clsname_length); 465 W_ERROR_HAVE_NO_MEMORY(*classname); 453 466 } else 454 467 *classname = NULL; … … 485 498 if (!hbin_get_tdr(regf, offset, nk, 486 499 (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)); 488 501 return NULL; 489 502 } … … 500 513 501 514 static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key, 502 int idx, const char **name,515 uint32_t idx, const char **name, 503 516 uint32_t *data_type, DATA_BLOB *data) 504 517 { … … 515 528 tmp = hbin_get(regf, private_data->nk->values_offset); 516 529 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)); 518 532 return WERR_GENERAL_FAILURE; 519 533 } … … 530 544 if (!hbin_get_tdr(regf, vk_offset, vk, 531 545 (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)); 533 547 talloc_free(vk); 534 548 return WERR_GENERAL_FAILURE; … … 536 550 537 551 /* FIXME: name character set ?*/ 538 if (name != NULL) 552 if (name != NULL) { 539 553 *name = talloc_strndup(ctx, vk->data_name, vk->name_length); 554 W_ERROR_HAVE_NO_MEMORY(*name); 555 } 540 556 541 557 if (data_type != NULL) … … 543 559 544 560 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); 548 566 } else { 549 567 *data = hbin_get(regf, vk->data_offset); … … 563 581 uint32_t *type, DATA_BLOB *data) 564 582 { 565 int i;583 unsigned int i; 566 584 const char *vname; 567 585 WERROR error; … … 598 616 return WERR_NO_MORE_ITEMS; 599 617 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 600 623 data = hbin_get(private_data->hive, nk->subkeys_offset); 601 624 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)); 603 627 return WERR_GENERAL_FAILURE; 604 628 } … … 606 630 if (!strncmp((char *)data.data, "li", 2)) { 607 631 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); 609 633 610 634 DEBUG(10, ("Subkeys in LI list\n")); … … 627 651 } else if (!strncmp((char *)data.data, "lf", 2)) { 628 652 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); 630 654 631 655 DEBUG(10, ("Subkeys in LF list\n")); … … 648 672 } else if (!strncmp((char *)data.data, "lh", 2)) { 649 673 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); 651 675 652 676 DEBUG(10, ("Subkeys in LH list\n")); … … 668 692 } else if (!strncmp((char *)data.data, "ri", 2)) { 669 693 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); 671 695 uint16_t i; 672 696 uint16_t sublist_count = 0; … … 769 793 (char*)db.data, 770 794 ret->nk->clsname_length); 795 W_ERROR_HAVE_NO_MEMORY(*classname); 771 796 } else 772 797 *classname = NULL; … … 801 826 } 802 827 803 pull = tdr_pull_init(ctx , private_data->hive->iconv_convenience);828 pull = tdr_pull_init(ctx); 804 829 805 830 pull->data = subkey_data; … … 836 861 uint32_t key_off = 0; 837 862 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 838 868 data = hbin_get(private_data->hive, nk->subkeys_offset); 839 869 if (!data.data) { … … 844 874 if (!strncmp((char *)data.data, "li", 2)) { 845 875 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); 847 877 uint16_t i; 848 878 … … 875 905 } else if (!strncmp((char *)data.data, "lf", 2)) { 876 906 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); 878 908 uint16_t i; 879 909 … … 910 940 } else if (!strncmp((char *)data.data, "lh", 2)) { 911 941 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); 913 943 uint16_t i; 914 944 uint32_t hash; … … 947 977 } else if (!strncmp((char *)data.data, "ri", 2)) { 948 978 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); 950 980 uint16_t i, j; 951 981 … … 1052 1082 1053 1083 /* 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, 1055 1085 sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { 1056 1086 DEBUG(0, ("Unable to push security descriptor\n")); … … 1205 1235 data.data = sk.sec_desc; 1206 1236 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, 1208 1238 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { 1209 1239 DEBUG(0, ("Error parsing security descriptor\n")); … … 1289 1319 1290 1320 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); 1292 1322 struct li_block li; 1323 struct nk_block sub_nk; 1324 int32_t i, j; 1293 1325 1294 1326 pull->data = data; … … 1307 1339 } 1308 1340 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 1309 1355 li.nk_offset = talloc_realloc(regf, li.nk_offset, 1310 1356 uint32_t, li.key_count+1); 1311 1357 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; 1313 1365 li.key_count++; 1314 1366 *ret = hbin_store_tdr_resize(regf, … … 1318 1370 talloc_free(li.nk_offset); 1319 1371 } 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); 1321 1373 struct lf_block lf; 1374 struct nk_block sub_nk; 1375 int32_t i, j; 1322 1376 1323 1377 pull->data = data; … … 1331 1385 SMB_ASSERT(!strncmp(lf.header, "lf", 2)); 1332 1386 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 1333 1401 lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, 1334 1402 lf.key_count+1); 1335 1403 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); 1338 1412 W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash); 1339 1413 lf.key_count++; … … 1344 1418 talloc_free(lf.hr); 1345 1419 } 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); 1347 1421 struct lh_block lh; 1422 struct nk_block sub_nk; 1423 int32_t i, j; 1348 1424 1349 1425 pull->data = data; … … 1357 1433 SMB_ASSERT(!strncmp(lh.header, "lh", 2)); 1358 1434 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 1359 1449 lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, 1360 1450 lh.key_count+1); 1361 1451 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); 1364 1460 lh.key_count++; 1365 1461 *ret = hbin_store_tdr_resize(regf, … … 1393 1489 if (strncmp((char *)data.data, "li", 2) == 0) { 1394 1490 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); 1396 1492 uint16_t i; 1397 1493 bool found_offset = false; … … 1437 1533 } else if (strncmp((char *)data.data, "lf", 2) == 0) { 1438 1534 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); 1440 1536 uint16_t i; 1441 1537 bool found_offset = false; … … 1483 1579 } else if (strncmp((char *)data.data, "lh", 2) == 0) { 1484 1580 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); 1486 1582 uint16_t i; 1487 1583 bool found_offset = false; … … 1538 1634 } 1539 1635 1540 static WERROR regf_del_value (struct hive_key *key, const char *name) 1636 static WERROR regf_del_value(TALLOC_CTX *mem_ctx, struct hive_key *key, 1637 const char *name) 1541 1638 { 1542 1639 struct regf_key_data *private_data = (struct regf_key_data *)key; … … 1547 1644 bool found_offset = false; 1548 1645 DATA_BLOB values; 1549 u int32_t i;1646 unsigned int i; 1550 1647 1551 1648 if (nk->values_offset == -1) { … … 1592 1689 private_data->offset, nk); 1593 1690 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 1695 static WERROR regf_del_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, 1696 const char *name) 1599 1697 { 1600 1698 const struct regf_key_data *private_data = … … 1623 1721 char *sk_name; 1624 1722 struct hive_key *sk = (struct hive_key *)key; 1625 int i = key->nk->num_subkeys;1723 unsigned int i = key->nk->num_subkeys; 1626 1724 while (i--) { 1627 1725 /* Get subkey information. */ … … 1635 1733 1636 1734 /* Delete subkey. */ 1637 error = regf_del_key( sk, sk_name);1735 error = regf_del_key(NULL, sk, sk_name); 1638 1736 if (!W_ERROR_IS_OK(error)) { 1639 1737 DEBUG(0, ("Can't delete key '%s'.\n", sk_name)); … … 1649 1747 struct hive_key *sk = (struct hive_key *)key; 1650 1748 DATA_BLOB data; 1651 int i = key->nk->num_values;1749 unsigned int i = key->nk->num_values; 1652 1750 while (i--) { 1653 1751 /* Get value information. */ … … 1661 1759 1662 1760 /* Delete value. */ 1663 error = regf_del_value( sk, val_name);1761 error = regf_del_value(NULL, sk, val_name); 1664 1762 if (!W_ERROR_IS_OK(error)) { 1665 1763 DEBUG(0, ("Can't delete value '%s'.\n", val_name)); … … 1690 1788 hbin_free(private_data->hive, key->offset); 1691 1789 1692 return regf_save_hbin(private_data->hive );1790 return regf_save_hbin(private_data->hive, 0); 1693 1791 } 1694 1792 … … 1717 1815 nk.num_values = 0; 1718 1816 nk.values_offset = -1; 1719 memset(nk.unk3, 0, 5);1817 memset(nk.unk3, 0, sizeof(nk.unk3)); 1720 1818 nk.clsname_offset = -1; /* FIXME: fill in */ 1721 1819 nk.clsname_length = 0; … … 1728 1826 if (!hbin_get_tdr(regf, regf->header->data_offset, root, 1729 1827 (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", 1731 1829 regf->header->data_offset)); 1732 1830 return WERR_GENERAL_FAILURE; … … 1753 1851 *ret = (struct hive_key *)regf_get_key(ctx, regf, offset); 1754 1852 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); 1756 1855 } 1757 1856 … … 1764 1863 struct vk_block vk; 1765 1864 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; 1767 1866 DATA_BLOB values; 1768 1867 … … 1778 1877 (tdr_pull_fn_t)tdr_pull_vk_block, 1779 1878 &vk)) { 1780 DEBUG(0, ("Unable to get VK block at %d\n",1879 DEBUG(0, ("Unable to get VK block at 0x%x\n", 1781 1880 tmp_vk_offset)); 1782 1881 return WERR_GENERAL_FAILURE; … … 1787 1886 } 1788 1887 } 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. */ 1794 1891 if (old_vk_offset == -1) { 1795 1892 vk.header = "vk"; … … 1802 1899 vk.flag = 0; 1803 1900 } 1804 } 1901 } else { 1902 /* Free data, if any */ 1903 if (!(vk.data_length & 0x80000000)) { 1904 hbin_free(regf, vk.data_offset); 1905 } 1906 } 1907 1805 1908 /* Set the type and data */ 1806 1909 vk.data_length = data.length; 1807 1910 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 } 1809 1916 vk.data_length |= 0x80000000; 1810 vk.data_offset = *(uint32_t *)data.data;1917 vk.data_offset = IVAL(data.data, 0); 1811 1918 } else { 1812 1919 /* Store data somewhere */ … … 1864 1971 (tdr_push_fn_t) tdr_push_nk_block, 1865 1972 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 1976 static WERROR regf_save_hbin(struct regf_data *regf, bool flush) 1977 { 1978 struct tdr_push *push = tdr_push_init(regf); 1979 unsigned int i; 1873 1980 1874 1981 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); 1875 1989 1876 1990 if (lseek(regf->fd, 0, SEEK_SET) == -1) { … … 1887 2001 talloc_free(push); 1888 2002 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, 1890 2004 (tdr_push_fn_t)tdr_push_regf_hdr, 1891 2005 regf->header))) { … … 1900 2014 1901 2015 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, 1903 2017 (tdr_push_fn_t)tdr_push_hbin_block, 1904 2018 regf->hbins[i]))) { … … 1912 2026 1913 2027 WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, 1914 struct smb_iconv_convenience *iconv_convenience,1915 2028 const char *location, 1916 2029 int minor_version, struct hive_key **key) … … 1926 2039 1927 2040 regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); 1928 1929 regf->iconv_convenience = iconv_convenience;1930 2041 1931 2042 W_ERROR_HAVE_NO_MEMORY(regf); … … 1963 2074 1964 2075 nk.header = "nk"; 1965 nk.type = REG_ SUB_KEY;2076 nk.type = REG_ROOT_KEY; 1966 2077 unix_to_nt_time(&nk.last_change, time(NULL)); 1967 2078 nk.uk1 = 0; … … 1997 2108 1998 2109 /* 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, 2000 2111 sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { 2001 2112 DEBUG(0, ("Unable to push security descriptor\n")); … … 2028 2139 regf->header->data_offset); 2029 2140 2030 error = regf_save_hbin(regf );2141 error = regf_save_hbin(regf, 1); 2031 2142 if (!W_ERROR_IS_OK(error)) { 2032 2143 return error; … … 2034 2145 2035 2146 /* We can drop our own reference now that *key will have created one */ 2036 talloc_ free(regf);2147 talloc_unlink(NULL, regf); 2037 2148 2038 2149 return WERR_OK; 2039 2150 } 2040 2151 2152 static 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 2167 static 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 2041 2184 WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, 2042 struct smb_iconv_convenience *iconv_convenience, structhive_key **key)2185 struct hive_key **key) 2043 2186 { 2044 2187 struct regf_data *regf; 2045 2188 struct regf_hdr *regf_hdr; 2046 2189 struct tdr_pull *pull; 2047 int i;2190 unsigned int i; 2048 2191 2049 2192 regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data); 2050 2051 regf->iconv_convenience = iconv_convenience;2052 2053 2193 W_ERROR_HAVE_NO_MEMORY(regf); 2194 2195 talloc_set_destructor(regf, regf_destruct); 2054 2196 2055 2197 DEBUG(5, ("Attempting to load registry file\n")); … … 2065 2207 } 2066 2208 2067 pull = tdr_pull_init(regf , regf->iconv_convenience);2209 pull = tdr_pull_init(regf); 2068 2210 2069 2211 pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, 0, regf); … … 2163 2305 .del_key = regf_del_key, 2164 2306 .delete_value = regf_del_value, 2307 .flush_key = regf_flush_key 2165 2308 };
Note:
See TracChangeset
for help on using the changeset viewer.