Changeset 223 for branches/samba-3.3.x/source/registry
- Timestamp:
- May 24, 2009, 7:51:24 AM (16 years ago)
- Location:
- branches/samba-3.3.x/source/registry
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.3.x/source/registry/reg_api.c
r206 r223 95 95 static WERROR fill_subkey_cache(struct registry_key *key) 96 96 { 97 WERROR werr; 98 97 99 if (key->subkeys != NULL) { 98 100 if (!reg_subkeys_need_update(key->key, key->subkeys)) { … … 101 103 } 102 104 103 if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) { 104 return WERR_NOMEM; 105 } 105 werr = regsubkey_ctr_init(key, &(key->subkeys)); 106 W_ERROR_NOT_OK_RETURN(werr); 106 107 107 108 if (fetch_reg_keys(key->key, key->subkeys) == -1) { … … 128 129 struct registry_key *regkey; 129 130 REGISTRY_KEY *key; 130 REGSUBKEY_CTR*subkeys = NULL;131 struct regsubkey_ctr *subkeys = NULL; 131 132 132 133 DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name)); … … 194 195 /* if the subkey count failed, bail out */ 195 196 196 if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {197 result = WERR_NOMEM;197 result = regsubkey_ctr_init(key, &subkeys); 198 if (!W_ERROR_IS_OK(result)) { 198 199 goto done; 199 200 } … … 309 310 } 310 311 311 if (idx >= key->subkeys->num_subkeys) {312 if (idx >= regsubkey_ctr_numkeys(key->subkeys)) { 312 313 return WERR_NO_MORE_ITEMS; 313 314 } 314 315 315 if (!(*name = talloc_strdup(mem_ctx, key->subkeys->subkeys[idx]))) { 316 if (!(*name = talloc_strdup(mem_ctx, 317 regsubkey_ctr_specific_key(key->subkeys, idx)))) 318 { 316 319 return WERR_NOMEM; 317 320 } … … 407 410 408 411 max_len = 0; 409 for (i=0; i<key->subkeys->num_subkeys; i++) { 410 max_len = MAX(max_len, strlen(key->subkeys->subkeys[i])); 411 } 412 413 *num_subkeys = key->subkeys->num_subkeys; 412 for (i=0; i< regsubkey_ctr_numkeys(key->subkeys); i++) { 413 max_len = MAX(max_len, 414 strlen(regsubkey_ctr_specific_key(key->subkeys, i))); 415 } 416 417 *num_subkeys = regsubkey_ctr_numkeys(key->subkeys); 414 418 *max_subkeylen = max_len; 415 419 *max_subkeysize = 0; /* Class length? */ … … 521 525 if (!W_ERROR_IS_OK(err)) goto done; 522 526 523 err = regsubkey_ctr_addkey(create_parent->subkeys, path); 524 if (!W_ERROR_IS_OK(err)) goto done; 525 526 if (!store_reg_keys(create_parent->key, create_parent->subkeys)) { 527 TALLOC_FREE(create_parent->subkeys); 528 err = WERR_REG_IO_FAILURE; 529 goto done; 530 } 527 err = create_reg_subkey(key->key, path); 528 W_ERROR_NOT_OK_GOTO_DONE(err); 531 529 532 530 /* … … 547 545 { 548 546 WERROR err; 549 TALLOC_CTX *mem_ctx;550 547 char *name, *end; 551 int num_subkeys;552 548 struct registry_key *tmp_key, *key; 553 554 if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM; 555 556 if ( !(name = talloc_strdup(mem_ctx, path))) {549 TALLOC_CTX *mem_ctx = talloc_stackframe(); 550 551 name = talloc_strdup(mem_ctx, path); 552 if (name == NULL) { 557 553 err = WERR_NOMEM; 558 goto error;554 goto done; 559 555 } 560 556 561 557 /* check if the key has subkeys */ 562 558 err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key); 563 if (!W_ERROR_IS_OK(err)) { 564 goto error; 565 } 566 if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) { 567 goto error; 568 } 569 if (key->subkeys->num_subkeys > 0) { 559 W_ERROR_NOT_OK_GOTO_DONE(err); 560 561 err = fill_subkey_cache(key); 562 W_ERROR_NOT_OK_GOTO_DONE(err); 563 564 if (regsubkey_ctr_numkeys(key->subkeys) > 0) { 570 565 err = WERR_ACCESS_DENIED; 571 goto error;566 goto done; 572 567 } 573 568 574 569 /* no subkeys - proceed with delete */ 575 if ((end = strrchr(name, '\\')) != NULL) { 570 end = strrchr(name, '\\'); 571 if (end != NULL) { 576 572 *end = '\0'; 577 573 578 574 err = reg_openkey(mem_ctx, parent, name, 579 575 SEC_RIGHTS_CREATE_SUBKEY, &tmp_key); 580 if (!W_ERROR_IS_OK(err)) { 581 goto error; 582 } 576 W_ERROR_NOT_OK_GOTO_DONE(err); 583 577 584 578 parent = tmp_key; … … 588 582 if (name[0] == '\0') { 589 583 err = WERR_INVALID_PARAM; 590 goto error; 591 } 592 593 if (!W_ERROR_IS_OK(err = fill_subkey_cache(parent))) { 594 goto error; 595 } 596 597 num_subkeys = parent->subkeys->num_subkeys; 598 599 if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) { 600 err = WERR_BADFILE; 601 goto error; 602 } 603 604 if (!store_reg_keys(parent->key, parent->subkeys)) { 605 TALLOC_FREE(parent->subkeys); 606 err = WERR_REG_IO_FAILURE; 607 goto error; 608 } 609 610 regkey_set_secdesc(key->key, NULL); 611 612 err = WERR_OK; 613 614 error: 584 goto done; 585 } 586 587 err = delete_reg_subkey(parent->key, name); 588 589 done: 615 590 TALLOC_FREE(mem_ctx); 616 591 return err; … … 727 702 REGISTRY_KEY registry_key; 728 703 REGVAL_CTR *values; 729 REGSUBKEY_CTR*subkeys;704 struct regsubkey_ctr *subkeys; 730 705 int i; 731 706 char *path = NULL; … … 749 724 /* now start parsing the values and subkeys */ 750 725 751 subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); 752 if (subkeys == NULL) { 753 return WERR_NOMEM; 754 } 726 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); 727 W_ERROR_NOT_OK_RETURN(result); 755 728 756 729 values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); … … 768 741 } 769 742 770 /* copy subkeys into the REGSUBKEY_CTR*/743 /* copy subkeys into the struct regsubkey_ctr */ 771 744 772 745 key->subkey_index = 0; … … 862 835 REGF_NK_REC *key; 863 836 REGVAL_CTR *values; 864 REGSUBKEY_CTR*subkeys;837 struct regsubkey_ctr *subkeys; 865 838 int i, num_subkeys; 866 839 char *key_tmp = NULL; … … 910 883 /* lookup the values and subkeys */ 911 884 912 subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); 913 if (subkeys == NULL) { 914 return WERR_NOMEM; 915 } 885 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); 886 W_ERROR_NOT_OK_RETURN(result); 916 887 917 888 values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); … … 1092 1063 struct registry_key *key; 1093 1064 char *subkey_name = NULL; 1065 uint32 i; 1094 1066 1095 1067 mem_ctx = talloc_new(ctx); … … 1105 1077 } 1106 1078 1107 while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0, 1108 &subkey_name, NULL))) 1109 { 1079 werr = fill_subkey_cache(key); 1080 W_ERROR_NOT_OK_GOTO_DONE(werr); 1081 1082 /* 1083 * loop from top to bottom for perfomance: 1084 * this way, we need to rehash the regsubkey containers less 1085 */ 1086 for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) { 1087 subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1); 1110 1088 werr = reg_deletekey_recursive_internal(mem_ctx, key, 1111 subkey_name, 1112 true); 1113 if (!W_ERROR_IS_OK(werr)) { 1114 goto done; 1115 } 1116 } 1117 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { 1118 DEBUG(1, ("reg_deletekey_recursive_internal: " 1119 "Error enumerating subkeys: %s\n", 1120 dos_errstr(werr))); 1121 goto done; 1122 } 1123 1124 werr = WERR_OK; 1089 subkey_name, 1090 true); 1091 W_ERROR_NOT_OK_GOTO_DONE(werr); 1092 } 1125 1093 1126 1094 if (del_key) { … … 1134 1102 } 1135 1103 1104 static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx, 1105 struct registry_key *parent, 1106 const char *path, 1107 bool del_key) 1108 { 1109 WERROR werr; 1110 1111 werr = regdb_transaction_start(); 1112 if (!W_ERROR_IS_OK(werr)) { 1113 DEBUG(0, ("reg_deletekey_recursive_trans: " 1114 "error starting transaction: %s\n", 1115 dos_errstr(werr))); 1116 return werr; 1117 } 1118 1119 werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key); 1120 1121 if (!W_ERROR_IS_OK(werr)) { 1122 DEBUG(1, (__location__ " failed to delete key '%s' from key " 1123 "'%s': %s\n", path, parent->key->name, 1124 dos_errstr(werr))); 1125 werr = regdb_transaction_cancel(); 1126 if (!W_ERROR_IS_OK(werr)) { 1127 DEBUG(0, ("reg_deletekey_recursive_trans: " 1128 "error cancelling transaction: %s\n", 1129 dos_errstr(werr))); 1130 } 1131 } else { 1132 werr = regdb_transaction_commit(); 1133 if (!W_ERROR_IS_OK(werr)) { 1134 DEBUG(0, ("reg_deletekey_recursive_trans: " 1135 "error committing transaction: %s\n", 1136 dos_errstr(werr))); 1137 } 1138 } 1139 1140 return werr; 1141 } 1142 1136 1143 WERROR reg_deletekey_recursive(TALLOC_CTX *ctx, 1137 1144 struct registry_key *parent, 1138 1145 const char *path) 1139 1146 { 1140 return reg_deletekey_recursive_ internal(ctx, parent, path, true);1147 return reg_deletekey_recursive_trans(ctx, parent, path, true); 1141 1148 } 1142 1149 … … 1145 1152 const char *path) 1146 1153 { 1147 return reg_deletekey_recursive_ internal(ctx, parent, path, false);1154 return reg_deletekey_recursive_trans(ctx, parent, path, false); 1148 1155 } 1149 1156 -
branches/samba-3.3.x/source/registry/reg_backend_current_version.c
r206 r223 71 71 72 72 static int current_version_fetch_subkeys(const char *key, 73 REGSUBKEY_CTR*subkey_ctr)73 struct regsubkey_ctr *subkey_ctr) 74 74 { 75 75 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_backend_db.c
r221 r223 104 104 char *keyname; 105 105 char *subkeyname; 106 REGSUBKEY_CTR*subkeys;106 struct regsubkey_ctr *subkeys; 107 107 const char *p, *p2; 108 108 … … 168 168 * We just want any subkeys already present */ 169 169 170 if (!(subkeys = TALLOC_ZERO_P(frame, REGSUBKEY_CTR))) { 170 werr = regsubkey_ctr_init(frame, &subkeys); 171 if (!W_ERROR_IS_OK(werr)) { 171 172 DEBUG(0,("talloc() failure!\n")); 172 werr = WERR_NOMEM;173 173 goto fail; 174 174 } … … 483 483 } 484 484 485 WERROR regdb_transaction_start(void) 486 { 487 return (regdb->transaction_start(regdb) == 0) ? 488 WERR_OK : WERR_REG_IO_FAILURE; 489 } 490 491 WERROR regdb_transaction_commit(void) 492 { 493 return (regdb->transaction_commit(regdb) == 0) ? 494 WERR_OK : WERR_REG_IO_FAILURE; 495 } 496 497 WERROR regdb_transaction_cancel(void) 498 { 499 return (regdb->transaction_cancel(regdb) == 0) ? 500 WERR_OK : WERR_REG_IO_FAILURE; 501 } 502 485 503 /*********************************************************************** 486 504 return the tdb sequence number of the registry tdb. … … 493 511 } 494 512 513 514 static WERROR regdb_delete_key_with_prefix(const char *keyname, 515 const char *prefix) 516 { 517 char *path; 518 WERROR werr = WERR_NOMEM; 519 TALLOC_CTX *mem_ctx = talloc_stackframe(); 520 521 if (keyname == NULL) { 522 werr = WERR_INVALID_PARAM; 523 goto done; 524 } 525 526 if (prefix == NULL) { 527 path = discard_const_p(char, keyname); 528 } else { 529 path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname); 530 if (path == NULL) { 531 goto done; 532 } 533 } 534 535 path = normalize_reg_path(mem_ctx, path); 536 if (path == NULL) { 537 goto done; 538 } 539 540 werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path)); 541 542 /* treat "not" found" as ok */ 543 if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { 544 werr = WERR_OK; 545 } 546 547 done: 548 talloc_free(mem_ctx); 549 return werr; 550 } 551 552 553 static WERROR regdb_delete_values(const char *keyname) 554 { 555 return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX); 556 } 557 558 static WERROR regdb_delete_secdesc(const char *keyname) 559 { 560 return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX); 561 } 562 563 static WERROR regdb_delete_subkeylist(const char *keyname) 564 { 565 return regdb_delete_key_with_prefix(keyname, NULL); 566 } 567 568 static WERROR regdb_delete_key_lists(const char *keyname) 569 { 570 WERROR werr; 571 572 werr = regdb_delete_values(keyname); 573 if (!W_ERROR_IS_OK(werr)) { 574 DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", 575 REG_VALUE_PREFIX, keyname, dos_errstr(werr))); 576 goto done; 577 } 578 579 werr = regdb_delete_secdesc(keyname); 580 if (!W_ERROR_IS_OK(werr)) { 581 DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", 582 REG_SECDESC_PREFIX, keyname, dos_errstr(werr))); 583 goto done; 584 } 585 586 werr = regdb_delete_subkeylist(keyname); 587 if (!W_ERROR_IS_OK(werr)) { 588 DEBUG(1, (__location__ " Deleting %s failed: %s\n", 589 keyname, dos_errstr(werr))); 590 goto done; 591 } 592 593 done: 594 return werr; 595 } 596 495 597 /*********************************************************************** 496 598 Add subkey strings to the registry tdb under a defined key … … 499 601 ***********************************************************************/ 500 602 501 static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR*ctr)603 static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr) 502 604 { 503 605 TDB_DATA dbuf; … … 579 681 } 580 682 683 /* 684 * Delete a sorted subkey cache for regdb_key_exists, will be 685 * recreated automatically 686 */ 687 keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, 688 keyname); 689 if (keyname != NULL) { 690 dbwrap_delete_bystring(regdb, keyname); 691 } 692 581 693 done: 582 694 TALLOC_FREE(ctx); … … 590 702 ***********************************************************************/ 591 703 592 bool regdb_store_keys(const char *key, REGSUBKEY_CTR*ctr)593 { 594 int num_subkeys, i;704 bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) 705 { 706 int num_subkeys, old_num_subkeys, i; 595 707 char *path = NULL; 596 REGSUBKEY_CTR*subkeys = NULL, *old_subkeys = NULL;708 struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; 597 709 char *oldkeyname = NULL; 598 710 TALLOC_CTX *ctx = talloc_stackframe(); 599 NTSTATUS status;711 WERROR werr; 600 712 601 713 if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { … … 608 720 */ 609 721 610 if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { 722 werr = regsubkey_ctr_init(ctx, &old_subkeys); 723 if (!W_ERROR_IS_OK(werr)) { 611 724 DEBUG(0,("regdb_store_keys: talloc() failure!\n")); 612 725 return false; … … 615 728 regdb_fetch_keys(key, old_subkeys); 616 729 617 if ((ctr->num_subkeys && old_subkeys->num_subkeys) && 618 (ctr->num_subkeys == old_subkeys->num_subkeys)) { 619 620 for (i = 0; i<ctr->num_subkeys; i++) { 621 if (strcmp(ctr->subkeys[i], 622 old_subkeys->subkeys[i]) != 0) { 730 num_subkeys = regsubkey_ctr_numkeys(ctr); 731 old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); 732 if ((num_subkeys && old_num_subkeys) && 733 (num_subkeys == old_num_subkeys)) { 734 735 for (i = 0; i < num_subkeys; i++) { 736 if (strcmp(regsubkey_ctr_specific_key(ctr, i), 737 regsubkey_ctr_specific_key(old_subkeys, i)) 738 != 0) 739 { 623 740 break; 624 741 } 625 742 } 626 if (i == ctr->num_subkeys) {743 if (i == num_subkeys) { 627 744 /* 628 745 * Nothing changed, no point to even start a tdb … … 645 762 */ 646 763 647 if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { 764 werr = regsubkey_ctr_init(ctx, &old_subkeys); 765 if (!W_ERROR_IS_OK(werr)) { 648 766 DEBUG(0,("regdb_store_keys: talloc() failure!\n")); 649 767 goto cancel; … … 687 805 } 688 806 689 /* (a) Delete the value list for this key */690 691 path = talloc_asprintf(ctx, "%s/%s/%s",692 REG_VALUE_PREFIX,693 key,694 oldkeyname );695 if (!path) {696 goto cancel;697 }698 path = normalize_reg_path(ctx, path);699 if (!path) {700 goto cancel;701 }702 /* Ignore errors here, we might have no values around */703 dbwrap_delete_bystring(regdb, path);704 TALLOC_FREE(path);705 706 /* (b) Delete the secdesc for this key */707 708 path = talloc_asprintf(ctx, "%s/%s/%s",709 REG_SECDESC_PREFIX,710 key,711 oldkeyname );712 if (!path) {713 goto cancel;714 }715 path = normalize_reg_path(ctx, path);716 if (!path) {717 goto cancel;718 }719 status = dbwrap_delete_bystring(regdb, path);720 /* Don't fail if there are no values around. */721 if (!NT_STATUS_IS_OK(status) &&722 !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))723 {724 DEBUG(1, ("Deleting %s failed: %s\n", path,725 nt_errstr(status)));726 goto cancel;727 }728 TALLOC_FREE(path);729 730 /* (c) Delete the list of subkeys of this key */731 732 807 path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); 733 808 if (!path) { 734 809 goto cancel; 735 810 } 736 path = normalize_reg_path(ctx, path); 737 if (!path) { 738 goto cancel; 739 } 740 status = dbwrap_delete_bystring(regdb, path); 741 /* Don't fail if the subkey record was not found. */ 742 if (!NT_STATUS_IS_OK(status) && 743 !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) 744 { 745 DEBUG(1, ("Deleting %s failed: %s\n", path, 746 nt_errstr(status))); 747 goto cancel; 748 } 811 812 werr = regdb_delete_key_lists(path); 813 W_ERROR_NOT_OK_GOTO(werr, cancel); 814 749 815 TALLOC_FREE(path); 750 816 } … … 765 831 766 832 if (num_subkeys == 0) { 767 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { 833 werr = regsubkey_ctr_init(ctx, &subkeys); 834 if (!W_ERROR_IS_OK(werr)) { 768 835 DEBUG(0,("regdb_store_keys: talloc() failure!\n")); 769 836 goto cancel; … … 786 853 goto cancel; 787 854 } 788 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { 855 werr = regsubkey_ctr_init(ctx, &subkeys); 856 if (!W_ERROR_IS_OK(werr)) { 789 857 DEBUG(0,("regdb_store_keys: talloc() failure!\n")); 790 858 goto cancel; … … 823 891 } 824 892 893 static WERROR regdb_create_subkey(const char *key, const char *subkey) 894 { 895 WERROR werr; 896 struct regsubkey_ctr *subkeys; 897 TALLOC_CTX *mem_ctx = talloc_stackframe(); 898 899 if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { 900 werr = WERR_NOT_FOUND; 901 goto done; 902 } 903 904 werr = regsubkey_ctr_init(mem_ctx, &subkeys); 905 W_ERROR_NOT_OK_GOTO_DONE(werr); 906 907 if (regdb_fetch_keys(key, subkeys) < 0) { 908 werr = WERR_REG_IO_FAILURE; 909 goto done; 910 } 911 912 if (regsubkey_ctr_key_exists(subkeys, subkey)) { 913 werr = WERR_OK; 914 goto done; 915 } 916 917 talloc_free(subkeys); 918 919 werr = regdb_transaction_start(); 920 W_ERROR_NOT_OK_GOTO_DONE(werr); 921 922 werr = regsubkey_ctr_init(mem_ctx, &subkeys); 923 W_ERROR_NOT_OK_GOTO(werr, cancel); 924 925 if (regdb_fetch_keys(key, subkeys) < 0) { 926 werr = WERR_REG_IO_FAILURE; 927 goto cancel; 928 } 929 930 werr = regsubkey_ctr_addkey(subkeys, subkey); 931 W_ERROR_NOT_OK_GOTO(werr, cancel); 932 933 if (!regdb_store_keys_internal(key, subkeys)) { 934 DEBUG(0, (__location__ " failed to store new subkey list for " 935 "parent key %s\n", key)); 936 werr = WERR_REG_IO_FAILURE; 937 goto cancel; 938 } 939 940 werr = regdb_transaction_commit(); 941 if (!W_ERROR_IS_OK(werr)) { 942 DEBUG(0, (__location__ " failed to commit transaction: %s\n", 943 dos_errstr(werr))); 944 } 945 946 goto done; 947 948 cancel: 949 werr = regdb_transaction_cancel(); 950 if (!W_ERROR_IS_OK(werr)) { 951 DEBUG(0, (__location__ " failed to cancel transaction: %s\n", 952 dos_errstr(werr))); 953 } 954 955 done: 956 talloc_free(mem_ctx); 957 return werr; 958 } 959 960 static WERROR regdb_delete_subkey(const char *key, const char *subkey) 961 { 962 WERROR werr, werr2; 963 struct regsubkey_ctr *subkeys; 964 char *path; 965 TALLOC_CTX *mem_ctx = talloc_stackframe(); 966 967 if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { 968 werr = WERR_NOT_FOUND; 969 goto done; 970 } 971 972 path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey); 973 if (path == NULL) { 974 werr = WERR_NOMEM; 975 goto done; 976 } 977 978 if (!regdb_key_exists(path)) { 979 werr = WERR_OK; 980 goto done; 981 } 982 983 werr = regdb_transaction_start(); 984 W_ERROR_NOT_OK_GOTO_DONE(werr); 985 986 werr = regdb_delete_key_lists(path); 987 W_ERROR_NOT_OK_GOTO(werr, cancel); 988 989 werr = regsubkey_ctr_init(mem_ctx, &subkeys); 990 W_ERROR_NOT_OK_GOTO(werr, cancel); 991 992 if (regdb_fetch_keys(key, subkeys) < 0) { 993 werr = WERR_REG_IO_FAILURE; 994 goto cancel; 995 } 996 997 werr = regsubkey_ctr_delkey(subkeys, subkey); 998 W_ERROR_NOT_OK_GOTO(werr, cancel); 999 1000 if (!regdb_store_keys_internal(key, subkeys)) { 1001 DEBUG(0, (__location__ " failed to store new subkey_list for " 1002 "parent key %s\n", key)); 1003 werr = WERR_REG_IO_FAILURE; 1004 goto cancel; 1005 } 1006 1007 werr = regdb_transaction_commit(); 1008 if (!W_ERROR_IS_OK(werr)) { 1009 DEBUG(0, (__location__ " failed to commit transaction: %s\n", 1010 dos_errstr(werr))); 1011 } 1012 1013 goto done; 1014 1015 cancel: 1016 werr2 = regdb_transaction_cancel(); 1017 if (!W_ERROR_IS_OK(werr2)) { 1018 DEBUG(0, (__location__ " failed to cancel transaction: %s\n", 1019 dos_errstr(werr2))); 1020 } 1021 1022 done: 1023 talloc_free(mem_ctx); 1024 return werr; 1025 } 825 1026 826 1027 static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) … … 872 1073 } 873 1074 1075 /* 1076 * regdb_key_exists() is a very frequent operation. It can be quite 1077 * time-consuming to fully fetch the parent's subkey list, talloc_strdup all 1078 * subkeys and then compare the keyname linearly to all the parent's subkeys. 1079 * 1080 * The following code tries to make this operation as efficient as possible: 1081 * Per registry key we create a list of subkeys that is very efficient to 1082 * search for existence of a subkey. Its format is: 1083 * 1084 * 4 bytes num_subkeys 1085 * 4*num_subkey bytes offset into the string array 1086 * then follows a sorted list of subkeys in uppercase 1087 * 1088 * This record is created by create_sorted_subkeys() on demand if it does not 1089 * exist. scan_parent_subkeys() uses regdb->parse_record to search the sorted 1090 * list, the parsing code and the binary search can be found in 1091 * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of 1092 * the potentially large subkey record. 1093 * 1094 * The sorted subkey record is deleted in regdb_store_keys_internal and 1095 * recreated on demand. 1096 */ 1097 1098 static int cmp_keynames(const void *p1, const void *p2) 1099 { 1100 return StrCaseCmp(*((char **)p1), *((char **)p2)); 1101 } 1102 1103 static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) 1104 { 1105 char **sorted_subkeys; 1106 struct regsubkey_ctr *ctr; 1107 bool result = false; 1108 NTSTATUS status; 1109 char *buf; 1110 char *p; 1111 int i, res; 1112 size_t len; 1113 int num_subkeys; 1114 WERROR werr; 1115 1116 if (regdb->transaction_start(regdb) != 0) { 1117 DEBUG(0, ("create_sorted_subkeys: transaction_start " 1118 "failed\n")); 1119 return false; 1120 } 1121 1122 werr = regsubkey_ctr_init(talloc_tos(), &ctr); 1123 if (!W_ERROR_IS_OK(werr)) { 1124 goto fail; 1125 } 1126 1127 res = regdb_fetch_keys(key, ctr); 1128 if (res == -1) { 1129 goto fail; 1130 } 1131 1132 num_subkeys = regsubkey_ctr_numkeys(ctr); 1133 sorted_subkeys = talloc_array(ctr, char *, num_subkeys); 1134 if (sorted_subkeys == NULL) { 1135 goto fail; 1136 } 1137 1138 len = 4 + 4*num_subkeys; 1139 1140 for (i = 0; i < num_subkeys; i++) { 1141 sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, 1142 regsubkey_ctr_specific_key(ctr, i)); 1143 if (sorted_subkeys[i] == NULL) { 1144 goto fail; 1145 } 1146 len += strlen(sorted_subkeys[i])+1; 1147 } 1148 1149 qsort(sorted_subkeys, num_subkeys, sizeof(char *), cmp_keynames); 1150 1151 buf = talloc_array(ctr, char, len); 1152 if (buf == NULL) { 1153 goto fail; 1154 } 1155 p = buf + 4 + 4*num_subkeys; 1156 1157 SIVAL(buf, 0, num_subkeys); 1158 1159 for (i=0; i < num_subkeys; i++) { 1160 ptrdiff_t offset = p - buf; 1161 SIVAL(buf, 4 + 4*i, offset); 1162 strlcpy(p, sorted_subkeys[i], len-offset); 1163 p += strlen(sorted_subkeys[i]) + 1; 1164 } 1165 1166 status = dbwrap_store_bystring( 1167 regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), 1168 TDB_REPLACE); 1169 if (!NT_STATUS_IS_OK(status)) { 1170 /* 1171 * Don't use a "goto fail;" here, this would commit the broken 1172 * transaction. See below for an explanation. 1173 */ 1174 if (regdb->transaction_cancel(regdb) == -1) { 1175 DEBUG(0, ("create_sorted_subkeys: transaction_cancel " 1176 "failed\n")); 1177 } 1178 TALLOC_FREE(ctr); 1179 return false; 1180 } 1181 1182 result = true; 1183 fail: 1184 /* 1185 * We only get here via the "goto fail" when we did not write anything 1186 * yet. Using transaction_commit even in a failure case is necessary 1187 * because this (disposable) call might be nested in other 1188 * transactions. Doing a cancel here would destroy the possibility of 1189 * a transaction_commit for transactions that we might be wrapped in. 1190 */ 1191 if (regdb->transaction_commit(regdb) == -1) { 1192 DEBUG(0, ("create_sorted_subkeys: transaction_start " 1193 "failed\n")); 1194 goto fail; 1195 } 1196 1197 TALLOC_FREE(ctr); 1198 return result; 1199 } 1200 1201 struct scan_subkey_state { 1202 char *name; 1203 bool scanned; 1204 bool found; 1205 }; 1206 1207 static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data, 1208 void *private_data) 1209 { 1210 struct scan_subkey_state *state = 1211 (struct scan_subkey_state *)private_data; 1212 uint32_t num_subkeys; 1213 uint32_t l, u; 1214 1215 if (data.dsize < sizeof(uint32_t)) { 1216 return -1; 1217 } 1218 1219 state->scanned = true; 1220 state->found = false; 1221 1222 tdb_unpack(data.dptr, data.dsize, "d", &num_subkeys); 1223 1224 l = 0; 1225 u = num_subkeys; 1226 1227 while (l < u) { 1228 uint32_t idx = (l+u)/2; 1229 char *s = (char *)data.dptr + IVAL(data.dptr, 4 + 4*idx); 1230 int comparison = strcmp(state->name, s); 1231 1232 if (comparison < 0) { 1233 u = idx; 1234 } else if (comparison > 0) { 1235 l = idx + 1; 1236 } else { 1237 state->found = true; 1238 return 0; 1239 } 1240 } 1241 return 0; 1242 } 1243 1244 static bool scan_parent_subkeys(const char *parent, const char *name) 1245 { 1246 char *path = NULL; 1247 char *key = NULL; 1248 struct scan_subkey_state state = { 0, }; 1249 bool result = false; 1250 int res; 1251 1252 state.name = NULL; 1253 1254 path = normalize_reg_path(talloc_tos(), parent); 1255 if (path == NULL) { 1256 goto fail; 1257 } 1258 1259 key = talloc_asprintf(talloc_tos(), "%s/%s", 1260 REG_SORTED_SUBKEYS_PREFIX, path); 1261 if (key == NULL) { 1262 goto fail; 1263 } 1264 1265 state.name = talloc_strdup_upper(talloc_tos(), name); 1266 if (state.name == NULL) { 1267 goto fail; 1268 } 1269 state.scanned = false; 1270 1271 res = regdb->parse_record(regdb, string_term_tdb_data(key), 1272 parent_subkey_scanner, &state); 1273 1274 if (state.scanned) { 1275 result = state.found; 1276 } else { 1277 if (!create_sorted_subkeys(path, key)) { 1278 goto fail; 1279 } 1280 res = regdb->parse_record(regdb, string_term_tdb_data(key), 1281 parent_subkey_scanner, &state); 1282 if ((res == 0) && (state.scanned)) { 1283 result = state.found; 1284 } 1285 } 1286 1287 fail: 1288 TALLOC_FREE(path); 1289 TALLOC_FREE(state.name); 1290 return result; 1291 } 874 1292 875 1293 /** … … 908 1326 ret = (value.dptr != NULL); 909 1327 } else { 910 /* get the list of subkeys of the parent key */911 uint32 num_items, len, i;912 fstring subkeyname;913 914 1328 *p = '\0'; 915 p++; 916 value = regdb_fetch_key_internal(mem_ctx, path); 917 if (value.dptr == NULL) { 918 goto done; 919 } 920 921 len = tdb_unpack(value.dptr, value.dsize, "d", &num_items); 922 for (i = 0; i < num_items; i++) { 923 len += tdb_unpack(value.dptr +len, value.dsize -len, 924 "f", &subkeyname); 925 if (strequal(subkeyname, p)) { 926 ret = true; 927 goto done; 928 } 929 } 1329 ret = scan_parent_subkeys(path, p+1); 930 1330 } 931 1331 … … 941 1341 ***********************************************************************/ 942 1342 943 int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) 944 { 1343 int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) 1344 { 1345 WERROR werr; 945 1346 uint32 num_items; 946 1347 uint8 *buf; … … 958 1359 } 959 1360 960 ctr->seqnum = regdb_get_seqnum(); 1361 werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum()); 1362 if (!W_ERROR_IS_OK(werr)) { 1363 goto done; 1364 } 961 1365 962 1366 value = regdb_fetch_key_internal(frame, key); … … 973 1377 len = tdb_unpack( buf, buflen, "d", &num_items); 974 1378 975 /*976 * The following code breaks the abstraction that reg_objects.c sets977 * up with regsubkey_ctr_addkey(). But if we use that with the current978 * data structure of ctr->subkeys being an unsorted array, we end up979 * with an O(n^2) algorithm for retrieving keys from the tdb980 * file. This is pretty pointless, as we have to trust the data981 * structure on disk not to have duplicates anyway. The alternative to982 * breaking this abstraction would be to set up a more sophisticated983 * data structure in REGSUBKEY_CTR.984 *985 * This makes "net conf list" for a registry with >1000 shares986 * actually usable :-)987 */988 989 ctr->subkeys = talloc_array(ctr, char *, num_items);990 if (ctr->subkeys == NULL) {991 DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n"));992 goto done;993 }994 ctr->num_subkeys = num_items;995 996 1379 for (i=0; i<num_items; i++) { 997 1380 len += tdb_unpack(buf+len, buflen-len, "f", subkeyname); 998 ctr->subkeys[i] = talloc_strdup(ctr->subkeys, subkeyname); 999 if (ctr->subkeys[i] == NULL) { 1000 DEBUG(5, ("regdb_fetch_keys: could not allocate " 1001 "subkeyname\n")); 1002 TALLOC_FREE(ctr->subkeys); 1003 ctr->num_subkeys = 0; 1381 werr = regsubkey_ctr_addkey(ctr, subkeyname); 1382 if (!W_ERROR_IS_OK(werr)) { 1383 DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " 1384 "failed: %s\n", dos_errstr(werr))); 1004 1385 goto done; 1005 1386 } … … 1239 1620 TALLOC_CTX *mem_ctx = talloc_stackframe(); 1240 1621 char *tdbkey; 1241 NTSTATUS status;1242 1622 WERROR err = WERR_NOMEM; 1243 1623 TDB_DATA tdbdata; … … 1256 1636 if (secdesc == NULL) { 1257 1637 /* assuming a delete */ 1258 status = dbwrap_trans_delete_bystring(regdb, tdbkey); 1259 if (NT_STATUS_IS_OK(status)) { 1260 err = WERR_OK; 1261 } else { 1262 err = ntstatus_to_werror(status); 1263 } 1638 err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb, 1639 tdbkey)); 1264 1640 goto done; 1265 1641 } … … 1268 1644 &tdbdata.dptr, 1269 1645 &tdbdata.dsize)); 1270 if (!W_ERROR_IS_OK(err)) { 1271 goto done; 1272 } 1273 1274 status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0); 1275 if (!NT_STATUS_IS_OK(status)) { 1276 err = ntstatus_to_werror(status); 1277 goto done; 1278 } 1646 W_ERROR_NOT_OK_GOTO_DONE(err); 1647 1648 err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey, 1649 tdbdata, 0)); 1279 1650 1280 1651 done: … … 1283 1654 } 1284 1655 1285 bool regdb_subkeys_need_update( REGSUBKEY_CTR*subkeys)1286 { 1287 return (regdb_get_seqnum() != subkeys->seqnum);1656 bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys) 1657 { 1658 return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys)); 1288 1659 } 1289 1660 … … 1302 1673 .store_subkeys = regdb_store_keys, 1303 1674 .store_values = regdb_store_values, 1675 .create_subkey = regdb_create_subkey, 1676 .delete_subkey = regdb_delete_subkey, 1304 1677 .get_secdesc = regdb_get_secdesc, 1305 1678 .set_secdesc = regdb_set_secdesc, -
branches/samba-3.3.x/source/registry/reg_backend_hkpt_params.c
r206 r223 60 60 61 61 static int hkpt_params_fetch_subkeys(const char *key, 62 REGSUBKEY_CTR*subkey_ctr)62 struct regsubkey_ctr *subkey_ctr) 63 63 { 64 64 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_backend_netlogon_params.c
r206 r223 47 47 48 48 static int netlogon_params_fetch_subkeys(const char *key, 49 REGSUBKEY_CTR*subkey_ctr)49 struct regsubkey_ctr *subkey_ctr) 50 50 { 51 51 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_backend_perflib.c
r206 r223 96 96 97 97 static int perflib_fetch_subkeys(const char *key, 98 REGSUBKEY_CTR*subkey_ctr)98 struct regsubkey_ctr *subkey_ctr) 99 99 { 100 100 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_backend_printing.c
r206 r223 43 43 44 44 /* callbscks for fetch/store operations */ 45 int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR*subkeys );46 bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR*subkeys );45 int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); 46 bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); 47 47 int (*fetch_values) ( const char *path, REGVAL_CTR *values ); 48 48 bool (*store_values) ( const char *path, REGVAL_CTR *values ); … … 78 78 *********************************************************************/ 79 79 80 static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR*subkeys)80 static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys) 81 81 { 82 82 char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); … … 197 197 *********************************************************************/ 198 198 199 static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR*subkeys )199 static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) 200 200 { 201 201 int n_services = lp_numservices(); … … 276 276 *********************************************************************/ 277 277 278 static bool add_printers_by_registry( REGSUBKEY_CTR*subkeys )278 static bool add_printers_by_registry( struct regsubkey_ctr *subkeys ) 279 279 { 280 280 int i, num_keys, snum; … … 311 311 *********************************************************************/ 312 312 313 static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR*subkeys )313 static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys ) 314 314 { 315 315 char *printers_key; … … 739 739 *********************************************************************/ 740 740 741 static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR*subkeys )741 static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) 742 742 { 743 743 const char *environments[] = { … … 1086 1086 *********************************************************************/ 1087 1087 1088 static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR*subkeys )1088 static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) 1089 1089 { 1090 1090 int key_len = strlen(key); … … 1193 1193 **********************************************************************/ 1194 1194 1195 static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR*subkeys )1195 static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) 1196 1196 { 1197 1197 int i = match_registry_path( key ); … … 1209 1209 *********************************************************************/ 1210 1210 1211 static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR*subkeys )1211 static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) 1212 1212 { 1213 1213 int i = match_registry_path( key ); -
branches/samba-3.3.x/source/registry/reg_backend_prod_options.c
r206 r223 60 60 61 61 static int prod_options_fetch_subkeys(const char *key, 62 REGSUBKEY_CTR*subkey_ctr)62 struct regsubkey_ctr *subkey_ctr) 63 63 { 64 64 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_backend_shares.c
r206 r223 67 67 *********************************************************************/ 68 68 69 static int shares_subkey_info( const char *key, REGSUBKEY_CTR*subkey_ctr )69 static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr ) 70 70 { 71 71 char *path; … … 135 135 *********************************************************************/ 136 136 137 static bool shares_store_subkey( const char *key, REGSUBKEY_CTR*subkeys )137 static bool shares_store_subkey( const char *key, struct regsubkey_ctr *subkeys ) 138 138 { 139 139 return False; -
branches/samba-3.3.x/source/registry/reg_backend_smbconf.c
r206 r223 26 26 extern REGISTRY_OPS regdb_ops; /* these are the default */ 27 27 28 static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR*subkey_ctr )28 static int smbconf_fetch_keys( const char *key, struct regsubkey_ctr *subkey_ctr ) 29 29 { 30 30 return regdb_ops.fetch_subkeys(key, subkey_ctr); 31 31 } 32 32 33 static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR*subkeys )33 static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys ) 34 34 { 35 35 return regdb_ops.store_subkeys(key, subkeys); 36 } 37 38 static WERROR smbconf_create_subkey(const char *key, const char *subkey) 39 { 40 return regdb_ops.create_subkey(key, subkey); 41 } 42 43 static WERROR smbconf_delete_subkey(const char *key, const char *subkey) 44 { 45 return regdb_ops.delete_subkey(key, subkey); 36 46 } 37 47 … … 80 90 .store_subkeys = smbconf_store_keys, 81 91 .store_values = smbconf_store_values, 92 .create_subkey = smbconf_create_subkey, 93 .delete_subkey = smbconf_delete_subkey, 82 94 .reg_access_check = smbconf_reg_access_check, 83 95 .get_secdesc = smbconf_get_secdesc, -
branches/samba-3.3.x/source/registry/reg_backend_tcpip_params.c
r206 r223 57 57 58 58 static int tcpip_params_fetch_subkeys(const char *key, 59 REGSUBKEY_CTR*subkey_ctr)59 struct regsubkey_ctr *subkey_ctr) 60 60 { 61 61 return regdb_ops.fetch_subkeys(key, subkey_ctr); -
branches/samba-3.3.x/source/registry/reg_dispatcher.c
r221 r223 81 81 ***********************************************************************/ 82 82 83 bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR*subkeys )83 bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ) 84 84 { 85 85 if (key->ops && key->ops->store_subkeys) … … 101 101 } 102 102 103 WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey) 104 { 105 if (key->ops && key->ops->create_subkey) { 106 return key->ops->create_subkey(key->name, subkey); 107 } 108 109 return WERR_NOT_SUPPORTED; 110 } 111 112 WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey) 113 { 114 if (key->ops && key->ops->delete_subkey) { 115 return key->ops->delete_subkey(key->name, subkey); 116 } 117 118 return WERR_NOT_SUPPORTED; 119 } 120 103 121 /*********************************************************************** 104 122 High level wrapper function for enumerating registry subkeys … … 106 124 ***********************************************************************/ 107 125 108 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR*subkey_ctr )126 int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ) 109 127 { 110 128 int result = -1; … … 217 235 * registry key needs update from disk. 218 236 */ 219 bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR*subkeys)237 bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys) 220 238 { 221 239 if (key->ops && key->ops->subkeys_need_update) -
branches/samba-3.3.x/source/registry/reg_eventlog.c
r206 r223 36 36 char *evtlogpath = NULL; 37 37 char *evtfilepath = NULL; 38 REGSUBKEY_CTR*subkeys;38 struct regsubkey_ctr *subkeys; 39 39 REGVAL_CTR *values; 40 40 uint32 uiMaxSize; … … 43 43 UNISTR2 data; 44 44 TALLOC_CTX *ctx = talloc_tos(); 45 WERROR werr; 45 46 46 47 while (elogs && *elogs) { 47 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { 48 werr = regsubkey_ctr_init(ctx, &subkeys); 49 if (!W_ERROR_IS_OK(werr)) { 48 50 DEBUG( 0, ( "talloc() failure!\n" ) ); 49 51 return False; … … 71 73 ( "Adding key of [%s] to path of [%s]\n", *elogs, 72 74 evtlogpath ) ); 73 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { 75 werr = regsubkey_ctr_init(ctx, &subkeys); 76 if (!W_ERROR_IS_OK(werr)) { 74 77 DEBUG( 0, ( "talloc() failure!\n" ) ); 75 78 return False; … … 198 201 char **wrklist, **wp; 199 202 char *evtlogpath = NULL; 200 REGSUBKEY_CTR*subkeys;203 struct regsubkey_ctr *subkeys; 201 204 REGVAL_CTR *values; 202 205 REGISTRY_VALUE *rval; … … 208 211 int numsources; 209 212 TALLOC_CTX *ctx = talloc_tos(); 213 WERROR werr; 210 214 211 215 if (!elogs) { … … 316 320 TALLOC_FREE(wrklist); /* */ 317 321 318 if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { 322 werr = regsubkey_ctr_init(ctx, &subkeys); 323 if (!W_ERROR_IS_OK(werr)) { 319 324 DEBUG( 0, ( "talloc() failure!\n" ) ); 320 325 return False; … … 343 348 /* now allocate room for the source's subkeys */ 344 349 345 if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { 350 werr = regsubkey_ctr_init(ctx, &subkeys); 351 if (!W_ERROR_IS_OK(werr)) { 346 352 DEBUG( 0, ( "talloc() failure!\n" ) ); 347 353 return False; -
branches/samba-3.3.x/source/registry/reg_objects.c
r206 r223 25 25 #define DBGC_CLASS DBGC_REGISTRY 26 26 27 struct regsubkey_ctr { 28 uint32_t num_subkeys; 29 char **subkeys; 30 struct db_context *subkeys_hash; 31 int seqnum; 32 }; 33 27 34 /********************************************************************** 28 35 29 Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d30 since the methods use the object pointer as the talloc context for31 internal private data.32 33 There is no longer a reg XXX_ctr_intit() and regXXX_ctr_destroy()36 Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be 37 talloc()'d since the methods use the object pointer as the talloc 38 context for internal private data. 39 40 There is no longer a regval_ctr_intit() and regval_ctr_destroy() 34 41 pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the 35 42 object. … … 37 44 **********************************************************************/ 38 45 46 WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) 47 { 48 if (ctr == NULL) { 49 return WERR_INVALID_PARAM; 50 } 51 52 *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr); 53 if (*ctr == NULL) { 54 return WERR_NOMEM; 55 } 56 57 (*ctr)->subkeys_hash = db_open_rbt(*ctr); 58 if ((*ctr)->subkeys_hash == NULL) { 59 talloc_free(*ctr); 60 return WERR_NOMEM; 61 } 62 63 return WERR_OK; 64 } 65 66 WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) 67 { 68 if (ctr == NULL) { 69 return WERR_INVALID_PARAM; 70 } 71 72 ctr->seqnum = seqnum; 73 74 return WERR_OK; 75 } 76 77 int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) 78 { 79 if (ctr == NULL) { 80 return -1; 81 } 82 83 return ctr->seqnum; 84 } 85 86 static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, 87 const char *keyname, 88 uint32 idx) 89 { 90 WERROR werr; 91 92 werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, 93 keyname, 94 make_tdb_data((uint8 *)&idx, 95 sizeof(idx)), 96 TDB_REPLACE)); 97 if (!W_ERROR_IS_OK(werr)) { 98 DEBUG(1, ("error hashing new key '%s' in container: %s\n", 99 keyname, dos_errstr(werr))); 100 } 101 102 return werr; 103 } 104 105 static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, 106 const char *keyname) 107 { 108 WERROR werr; 109 110 werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, 111 keyname)); 112 if (!W_ERROR_IS_OK(werr)) { 113 DEBUG(1, ("error unhashing key '%s' in container: %s\n", 114 keyname, dos_errstr(werr))); 115 } 116 117 return werr; 118 } 119 120 static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, 121 const char *keyname, 122 uint32 *idx) 123 { 124 TDB_DATA data; 125 126 if ((ctr == NULL) || (keyname == NULL)) { 127 return WERR_INVALID_PARAM; 128 } 129 130 data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); 131 if (data.dptr == NULL) { 132 return WERR_NOT_FOUND; 133 } 134 135 if (data.dsize != sizeof(*idx)) { 136 talloc_free(data.dptr); 137 return WERR_INVALID_DATATYPE; 138 } 139 140 if (idx != NULL) { 141 *idx = *(uint32 *)data.dptr; 142 } 143 144 talloc_free(data.dptr); 145 return WERR_OK; 146 } 147 39 148 /*********************************************************************** 40 149 Add a new key to the array 41 150 **********************************************************************/ 42 151 43 WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR*ctr, const char *keyname )152 WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) 44 153 { 45 154 char **newkeys; 155 WERROR werr; 46 156 47 157 if ( !keyname ) { … … 69 179 return WERR_NOMEM; 70 180 } 181 182 werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys); 183 W_ERROR_NOT_OK_RETURN(werr); 184 71 185 ctr->num_subkeys++; 72 186 … … 78 192 **********************************************************************/ 79 193 80 int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) 81 { 82 int i; 83 84 if ( !keyname ) 85 return ctr->num_subkeys; 194 WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) 195 { 196 WERROR werr; 197 uint32 idx, j; 198 199 if (keyname == NULL) { 200 return WERR_INVALID_PARAM; 201 } 86 202 87 203 /* make sure the keyname is actually already there */ 88 204 89 for ( i=0; i<ctr->num_subkeys; i++ ) { 90 if ( strequal( ctr->subkeys[i], keyname ) ) 91 break; 92 } 93 94 if ( i == ctr->num_subkeys ) 95 return ctr->num_subkeys; 205 werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx); 206 W_ERROR_NOT_OK_RETURN(werr); 207 208 werr = regsubkey_ctr_unhash_keyname(ctr, keyname); 209 W_ERROR_NOT_OK_RETURN(werr); 96 210 97 211 /* update if we have any keys left */ 98 212 ctr->num_subkeys--; 99 if ( i < ctr->num_subkeys ) 100 memmove(&ctr->subkeys[i], &ctr->subkeys[i+1], 101 sizeof(char*) * (ctr->num_subkeys-i)); 102 103 return ctr->num_subkeys; 213 if (idx < ctr->num_subkeys) { 214 memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1], 215 sizeof(char *) * (ctr->num_subkeys - idx)); 216 217 /* we have to re-hash rest of the array... :-( */ 218 for (j = idx; j < ctr->num_subkeys; j++) { 219 werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j); 220 W_ERROR_NOT_OK_RETURN(werr); 221 } 222 } 223 224 return WERR_OK; 104 225 } 105 226 … … 108 229 **********************************************************************/ 109 230 110 bool regsubkey_ctr_key_exists( REGSUBKEY_CTR*ctr, const char *keyname )111 { 112 int i;231 bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) 232 { 233 WERROR werr; 113 234 114 235 if (!ctr->subkeys) { … … 116 237 } 117 238 118 for ( i=0; i<ctr->num_subkeys; i++ ) {119 if ( strequal( ctr->subkeys[i],keyname ) )120 return True;121 } 122 123 return False;239 werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL); 240 if (!W_ERROR_IS_OK(werr)) { 241 return false; 242 } 243 244 return true; 124 245 } 125 246 … … 128 249 **********************************************************************/ 129 250 130 int regsubkey_ctr_numkeys( REGSUBKEY_CTR*ctr )251 int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) 131 252 { 132 253 return ctr->num_subkeys; … … 137 258 **********************************************************************/ 138 259 139 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32key_index )260 char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index ) 140 261 { 141 262 if ( ! (key_index < ctr->num_subkeys) ) -
branches/samba-3.3.x/source/registry/regfio.c
r206 r223 1694 1694 1695 1695 REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name, 1696 REGVAL_CTR *values, REGSUBKEY_CTR *subkeys,1696 REGVAL_CTR *values, struct regsubkey_ctr *subkeys, 1697 1697 SEC_DESC *sec_desc, REGF_NK_REC *parent ) 1698 1698 {
Note:
See TracChangeset
for help on using the changeset viewer.