Ignore:
Timestamp:
May 24, 2009, 7:51:24 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update Samba 3.3 branch to 3.3.3

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  
    9595static WERROR fill_subkey_cache(struct registry_key *key)
    9696{
     97        WERROR werr;
     98
    9799        if (key->subkeys != NULL) {
    98100                if (!reg_subkeys_need_update(key->key, key->subkeys)) {
     
    101103        }
    102104
    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);
    106107
    107108        if (fetch_reg_keys(key->key, key->subkeys) == -1) {
     
    128129        struct registry_key *regkey;
    129130        REGISTRY_KEY *key;
    130         REGSUBKEY_CTR   *subkeys = NULL;
     131        struct regsubkey_ctr    *subkeys = NULL;
    131132
    132133        DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
     
    194195        /* if the subkey count failed, bail out */
    195196
    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)) {
    198199                goto done;
    199200        }
     
    309310        }
    310311
    311         if (idx >= key->subkeys->num_subkeys) {
     312        if (idx >= regsubkey_ctr_numkeys(key->subkeys)) {
    312313                return WERR_NO_MORE_ITEMS;
    313314        }
    314315
    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        {
    316319                return WERR_NOMEM;
    317320        }
     
    407410
    408411        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);
    414418        *max_subkeylen = max_len;
    415419        *max_subkeysize = 0;    /* Class length? */
     
    521525        if (!W_ERROR_IS_OK(err)) goto done;
    522526
    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);
    531529
    532530        /*
     
    547545{
    548546        WERROR err;
    549         TALLOC_CTX *mem_ctx;
    550547        char *name, *end;
    551         int num_subkeys;
    552548        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) {
    557553                err = WERR_NOMEM;
    558                 goto error;
     554                goto done;
    559555        }
    560556
    561557        /* check if the key has subkeys */
    562558        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) {
    570565                err = WERR_ACCESS_DENIED;
    571                 goto error;
     566                goto done;
    572567        }
    573568
    574569        /* no subkeys - proceed with delete */
    575         if ((end = strrchr(name, '\\')) != NULL) {
     570        end = strrchr(name, '\\');
     571        if (end != NULL) {
    576572                *end = '\0';
    577573
    578574                err = reg_openkey(mem_ctx, parent, name,
    579575                                  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);
    583577
    584578                parent = tmp_key;
     
    588582        if (name[0] == '\0') {
    589583                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
     589done:
    615590        TALLOC_FREE(mem_ctx);
    616591        return err;
     
    727702        REGISTRY_KEY registry_key;
    728703        REGVAL_CTR *values;
    729         REGSUBKEY_CTR *subkeys;
     704        struct regsubkey_ctr *subkeys;
    730705        int i;
    731706        char *path = NULL;
     
    749724        /* now start parsing the values and subkeys */
    750725
    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);
    755728
    756729        values = TALLOC_ZERO_P(subkeys, REGVAL_CTR);
     
    768741        }
    769742
    770         /* copy subkeys into the REGSUBKEY_CTR */
     743        /* copy subkeys into the struct regsubkey_ctr */
    771744
    772745        key->subkey_index = 0;
     
    862835        REGF_NK_REC *key;
    863836        REGVAL_CTR *values;
    864         REGSUBKEY_CTR *subkeys;
     837        struct regsubkey_ctr *subkeys;
    865838        int i, num_subkeys;
    866839        char *key_tmp = NULL;
     
    910883        /* lookup the values and subkeys */
    911884
    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);
    916887
    917888        values = TALLOC_ZERO_P(subkeys, REGVAL_CTR);
     
    10921063        struct registry_key *key;
    10931064        char *subkey_name = NULL;
     1065        uint32 i;
    10941066
    10951067        mem_ctx = talloc_new(ctx);
     
    11051077        }
    11061078
    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);
    11101088                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        }
    11251093
    11261094        if (del_key) {
     
    11341102}
    11351103
     1104static 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
    11361143WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
    11371144                               struct registry_key *parent,
    11381145                               const char *path)
    11391146{
    1140         return reg_deletekey_recursive_internal(ctx, parent, path, true);
     1147        return reg_deletekey_recursive_trans(ctx, parent, path, true);
    11411148}
    11421149
     
    11451152                                   const char *path)
    11461153{
    1147         return reg_deletekey_recursive_internal(ctx, parent, path, false);
     1154        return reg_deletekey_recursive_trans(ctx, parent, path, false);
    11481155}
    11491156
  • branches/samba-3.3.x/source/registry/reg_backend_current_version.c

    r206 r223  
    7171
    7272static int current_version_fetch_subkeys(const char *key,
    73                                          REGSUBKEY_CTR *subkey_ctr)
     73                                         struct regsubkey_ctr *subkey_ctr)
    7474{
    7575        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_backend_db.c

    r221 r223  
    104104        char *keyname;
    105105        char *subkeyname;
    106         REGSUBKEY_CTR *subkeys;
     106        struct regsubkey_ctr *subkeys;
    107107        const char *p, *p2;
    108108
     
    168168                 * We just want any subkeys already present */
    169169
    170                 if (!(subkeys = TALLOC_ZERO_P(frame, REGSUBKEY_CTR))) {
     170                werr = regsubkey_ctr_init(frame, &subkeys);
     171                if (!W_ERROR_IS_OK(werr)) {
    171172                        DEBUG(0,("talloc() failure!\n"));
    172                         werr = WERR_NOMEM;
    173173                        goto fail;
    174174                }
     
    483483}
    484484
     485WERROR regdb_transaction_start(void)
     486{
     487        return (regdb->transaction_start(regdb) == 0) ?
     488                WERR_OK : WERR_REG_IO_FAILURE;
     489}
     490
     491WERROR regdb_transaction_commit(void)
     492{
     493        return (regdb->transaction_commit(regdb) == 0) ?
     494                WERR_OK : WERR_REG_IO_FAILURE;
     495}
     496
     497WERROR regdb_transaction_cancel(void)
     498{
     499        return (regdb->transaction_cancel(regdb) == 0) ?
     500                WERR_OK : WERR_REG_IO_FAILURE;
     501}
     502
    485503/***********************************************************************
    486504 return the tdb sequence number of the registry tdb.
     
    493511}
    494512
     513
     514static 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
     547done:
     548        talloc_free(mem_ctx);
     549        return werr;
     550}
     551
     552
     553static WERROR regdb_delete_values(const char *keyname)
     554{
     555        return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX);
     556}
     557
     558static WERROR regdb_delete_secdesc(const char *keyname)
     559{
     560        return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX);
     561}
     562
     563static WERROR regdb_delete_subkeylist(const char *keyname)
     564{
     565        return regdb_delete_key_with_prefix(keyname, NULL);
     566}
     567
     568static 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
     593done:
     594        return werr;
     595}
     596
    495597/***********************************************************************
    496598 Add subkey strings to the registry tdb under a defined key
     
    499601 ***********************************************************************/
    500602
    501 static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
     603static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
    502604{
    503605        TDB_DATA dbuf;
     
    579681        }
    580682
     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
    581693done:
    582694        TALLOC_FREE(ctx);
     
    590702 ***********************************************************************/
    591703
    592 bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
    593 {
    594         int num_subkeys, i;
     704bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
     705{
     706        int num_subkeys, old_num_subkeys, i;
    595707        char *path = NULL;
    596         REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL;
     708        struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
    597709        char *oldkeyname = NULL;
    598710        TALLOC_CTX *ctx = talloc_stackframe();
    599         NTSTATUS status;
     711        WERROR werr;
    600712
    601713        if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
     
    608720         */
    609721
    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)) {
    611724                DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
    612725                return false;
     
    615728        regdb_fetch_keys(key, old_subkeys);
    616729
    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                        {
    623740                                break;
    624741                        }
    625742                }
    626                 if (i == ctr->num_subkeys) {
     743                if (i == num_subkeys) {
    627744                        /*
    628745                         * Nothing changed, no point to even start a tdb
     
    645762         */
    646763
    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)) {
    648766                DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
    649767                goto cancel;
     
    687805                }
    688806
    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 
    732807                path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
    733808                if (!path) {
    734809                        goto cancel;
    735810                }
    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
    749815                TALLOC_FREE(path);
    750816        }
     
    765831
    766832        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)) {
    768835                        DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
    769836                        goto cancel;
     
    786853                        goto cancel;
    787854                }
    788                 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) {
     855                werr = regsubkey_ctr_init(ctx, &subkeys);
     856                if (!W_ERROR_IS_OK(werr)) {
    789857                        DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
    790858                        goto cancel;
     
    823891}
    824892
     893static 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
     948cancel:
     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
     955done:
     956        talloc_free(mem_ctx);
     957        return werr;
     958}
     959
     960static 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
     1015cancel:
     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
     1022done:
     1023        talloc_free(mem_ctx);
     1024        return werr;
     1025}
    8251026
    8261027static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
     
    8721073}
    8731074
     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
     1098static int cmp_keynames(const void *p1, const void *p2)
     1099{
     1100        return StrCaseCmp(*((char **)p1), *((char **)p2));
     1101}
     1102
     1103static 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
     1201struct scan_subkey_state {
     1202        char *name;
     1203        bool scanned;
     1204        bool found;
     1205};
     1206
     1207static 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
     1244static 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}
    8741292
    8751293/**
     
    9081326                ret = (value.dptr != NULL);
    9091327        } else {
    910                 /* get the list of subkeys of the parent key */
    911                 uint32 num_items, len, i;
    912                 fstring subkeyname;
    913 
    9141328                *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);
    9301330        }
    9311331
     
    9411341 ***********************************************************************/
    9421342
    943 int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
    944 {
     1343int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
     1344{
     1345        WERROR werr;
    9451346        uint32 num_items;
    9461347        uint8 *buf;
     
    9581359        }
    9591360
    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        }
    9611365
    9621366        value = regdb_fetch_key_internal(frame, key);
     
    9731377        len = tdb_unpack( buf, buflen, "d", &num_items);
    9741378
    975         /*
    976          * The following code breaks the abstraction that reg_objects.c sets
    977          * up with regsubkey_ctr_addkey(). But if we use that with the current
    978          * data structure of ctr->subkeys being an unsorted array, we end up
    979          * with an O(n^2) algorithm for retrieving keys from the tdb
    980          * file. This is pretty pointless, as we have to trust the data
    981          * structure on disk not to have duplicates anyway. The alternative to
    982          * breaking this abstraction would be to set up a more sophisticated
    983          * data structure in REGSUBKEY_CTR.
    984          *
    985          * This makes "net conf list" for a registry with >1000 shares
    986          * 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 
    9961379        for (i=0; i<num_items; i++) {
    9971380                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)));
    10041385                        goto done;
    10051386                }
     
    12391620        TALLOC_CTX *mem_ctx = talloc_stackframe();
    12401621        char *tdbkey;
    1241         NTSTATUS status;
    12421622        WERROR err = WERR_NOMEM;
    12431623        TDB_DATA tdbdata;
     
    12561636        if (secdesc == NULL) {
    12571637                /* 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));
    12641640                goto done;
    12651641        }
     
    12681644                                                   &tdbdata.dptr,
    12691645                                                   &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));
    12791650
    12801651 done:
     
    12831654}
    12841655
    1285 bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys)
    1286 {
    1287         return (regdb_get_seqnum() != subkeys->seqnum);
     1656bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys)
     1657{
     1658        return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys));
    12881659}
    12891660
     
    13021673        .store_subkeys = regdb_store_keys,
    13031674        .store_values = regdb_store_values,
     1675        .create_subkey = regdb_create_subkey,
     1676        .delete_subkey = regdb_delete_subkey,
    13041677        .get_secdesc = regdb_get_secdesc,
    13051678        .set_secdesc = regdb_set_secdesc,
  • branches/samba-3.3.x/source/registry/reg_backend_hkpt_params.c

    r206 r223  
    6060
    6161static int hkpt_params_fetch_subkeys(const char *key,
    62                                          REGSUBKEY_CTR *subkey_ctr)
     62                                         struct regsubkey_ctr *subkey_ctr)
    6363{
    6464        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_backend_netlogon_params.c

    r206 r223  
    4747
    4848static int netlogon_params_fetch_subkeys(const char *key,
    49                                          REGSUBKEY_CTR *subkey_ctr)
     49                                         struct regsubkey_ctr *subkey_ctr)
    5050{
    5151        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_backend_perflib.c

    r206 r223  
    9696
    9797static int perflib_fetch_subkeys(const char *key,
    98                                          REGSUBKEY_CTR *subkey_ctr)
     98                                 struct regsubkey_ctr *subkey_ctr)
    9999{
    100100        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_backend_printing.c

    r206 r223  
    4343
    4444        /* 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 );
    4747        int  (*fetch_values)  ( const char *path, REGVAL_CTR *values );
    4848        bool (*store_values)  ( const char *path, REGVAL_CTR *values );
     
    7878 *********************************************************************/
    7979
    80 static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys)
     80static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys)
    8181{
    8282        char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS));
     
    197197 *********************************************************************/
    198198
    199 static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
     199static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    200200{
    201201        int n_services = lp_numservices();
     
    276276 *********************************************************************/
    277277
    278 static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys )
     278static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
    279279{
    280280        int i, num_keys, snum;
     
    311311 *********************************************************************/
    312312
    313 static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
     313static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
    314314{
    315315        char *printers_key;
     
    739739 *********************************************************************/
    740740
    741 static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
     741static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    742742{
    743743        const char *environments[] = {
     
    10861086 *********************************************************************/
    10871087
    1088 static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
     1088static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    10891089{
    10901090        int key_len = strlen(key);
     
    11931193 **********************************************************************/
    11941194
    1195 static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
     1195static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
    11961196{
    11971197        int i = match_registry_path( key );
     
    12091209 *********************************************************************/
    12101210
    1211 static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
     1211static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
    12121212{
    12131213        int i = match_registry_path( key );
  • branches/samba-3.3.x/source/registry/reg_backend_prod_options.c

    r206 r223  
    6060
    6161static int prod_options_fetch_subkeys(const char *key,
    62                                       REGSUBKEY_CTR *subkey_ctr)
     62                                      struct regsubkey_ctr *subkey_ctr)
    6363{
    6464        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_backend_shares.c

    r206 r223  
    6767 *********************************************************************/
    6868 
    69 static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
     69static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr )
    7070{
    7171        char            *path;
     
    135135 *********************************************************************/
    136136
    137 static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
     137static bool shares_store_subkey( const char *key, struct regsubkey_ctr *subkeys )
    138138{
    139139        return False;
  • branches/samba-3.3.x/source/registry/reg_backend_smbconf.c

    r206 r223  
    2626extern REGISTRY_OPS regdb_ops;          /* these are the default */
    2727
    28 static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr )
     28static int smbconf_fetch_keys( const char *key, struct regsubkey_ctr *subkey_ctr )
    2929{
    3030        return regdb_ops.fetch_subkeys(key, subkey_ctr);
    3131}
    3232
    33 static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
     33static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys )
    3434{
    3535        return regdb_ops.store_subkeys(key, subkeys);
     36}
     37
     38static WERROR smbconf_create_subkey(const char *key, const char *subkey)
     39{
     40        return regdb_ops.create_subkey(key, subkey);
     41}
     42
     43static WERROR smbconf_delete_subkey(const char *key, const char *subkey)
     44{
     45        return regdb_ops.delete_subkey(key, subkey);
    3646}
    3747
     
    8090        .store_subkeys = smbconf_store_keys,
    8191        .store_values = smbconf_store_values,
     92        .create_subkey = smbconf_create_subkey,
     93        .delete_subkey = smbconf_delete_subkey,
    8294        .reg_access_check = smbconf_reg_access_check,
    8395        .get_secdesc = smbconf_get_secdesc,
  • branches/samba-3.3.x/source/registry/reg_backend_tcpip_params.c

    r206 r223  
    5757
    5858static int tcpip_params_fetch_subkeys(const char *key,
    59                                          REGSUBKEY_CTR *subkey_ctr)
     59                                      struct regsubkey_ctr *subkey_ctr)
    6060{
    6161        return regdb_ops.fetch_subkeys(key, subkey_ctr);
  • branches/samba-3.3.x/source/registry/reg_dispatcher.c

    r221 r223  
    8181 ***********************************************************************/
    8282
    83 bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
     83bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys )
    8484{
    8585        if (key->ops && key->ops->store_subkeys)
     
    101101}
    102102
     103WERROR 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
     112WERROR 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
    103121/***********************************************************************
    104122 High level wrapper function for enumerating registry subkeys
     
    106124 ***********************************************************************/
    107125
    108 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
     126int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr )
    109127{
    110128        int result = -1;
     
    217235 * registry key needs update from disk.
    218236 */
    219 bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
     237bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys)
    220238{
    221239        if (key->ops && key->ops->subkeys_need_update)
  • branches/samba-3.3.x/source/registry/reg_eventlog.c

    r206 r223  
    3636        char *evtlogpath = NULL;
    3737        char *evtfilepath = NULL;
    38         REGSUBKEY_CTR *subkeys;
     38        struct regsubkey_ctr *subkeys;
    3939        REGVAL_CTR *values;
    4040        uint32 uiMaxSize;
     
    4343        UNISTR2 data;
    4444        TALLOC_CTX *ctx = talloc_tos();
     45        WERROR werr;
    4546
    4647        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)) {
    4850                        DEBUG( 0, ( "talloc() failure!\n" ) );
    4951                        return False;
     
    7173                       ( "Adding key of [%s] to path of [%s]\n", *elogs,
    7274                         evtlogpath ) );
    73                 if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) {
     75                werr = regsubkey_ctr_init(ctx, &subkeys);
     76                if (!W_ERROR_IS_OK(werr)) {
    7477                        DEBUG( 0, ( "talloc() failure!\n" ) );
    7578                        return False;
     
    198201        char **wrklist, **wp;
    199202        char *evtlogpath = NULL;
    200         REGSUBKEY_CTR *subkeys;
     203        struct regsubkey_ctr *subkeys;
    201204        REGVAL_CTR *values;
    202205        REGISTRY_VALUE *rval;
     
    208211        int numsources;
    209212        TALLOC_CTX *ctx = talloc_tos();
     213        WERROR werr;
    210214
    211215        if (!elogs) {
     
    316320        TALLOC_FREE(wrklist);   /*  */
    317321
    318         if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) {
     322        werr = regsubkey_ctr_init(ctx, &subkeys);
     323        if (!W_ERROR_IS_OK(werr)) {
    319324                DEBUG( 0, ( "talloc() failure!\n" ) );
    320325                return False;
     
    343348        /* now allocate room for the source's subkeys */
    344349
    345         if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) {
     350        werr = regsubkey_ctr_init(ctx, &subkeys);
     351        if (!W_ERROR_IS_OK(werr)) {
    346352                DEBUG( 0, ( "talloc() failure!\n" ) );
    347353                return False;
  • branches/samba-3.3.x/source/registry/reg_objects.c

    r206 r223  
    2525#define DBGC_CLASS DBGC_REGISTRY
    2626
     27struct regsubkey_ctr {
     28        uint32_t        num_subkeys;
     29        char            **subkeys;
     30        struct db_context *subkeys_hash;
     31        int seqnum;
     32};
     33
    2734/**********************************************************************
    2835
    29  Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
    30  since the methods use the object pointer as the talloc context for
    31  internal private data.
    32 
    33  There is no longer a regXXX_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()
    3441 pair of functions.  Simply TALLOC_ZERO_P() and TALLOC_FREE() the
    3542 object.
     
    3744 **********************************************************************/
    3845
     46WERROR 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
     66WERROR 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
     77int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr)
     78{
     79        if (ctr == NULL) {
     80                return -1;
     81        }
     82
     83        return ctr->seqnum;
     84}
     85
     86static 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
     105static 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
     120static 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
    39148/***********************************************************************
    40149 Add a new key to the array
    41150 **********************************************************************/
    42151
    43 WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
     152WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname )
    44153{
    45154        char **newkeys;
     155        WERROR werr;
    46156
    47157        if ( !keyname ) {
     
    69179                return WERR_NOMEM;
    70180        }
     181
     182        werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys);
     183        W_ERROR_NOT_OK_RETURN(werr);
     184
    71185        ctr->num_subkeys++;
    72186
     
    78192 **********************************************************************/
    79193
    80 int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname )
    81 {
    82         int i;
    83 
    84         if ( !keyname )
    85                 return ctr->num_subkeys;
     194WERROR 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        }
    86202
    87203        /* make sure the keyname is actually already there */
    88204
    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);
    96210
    97211        /* update if we have any keys left */
    98212        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;
    104225}
    105226
     
    108229 **********************************************************************/
    109230
    110 bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
    111 {
    112         int     i;
     231bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname )
     232{
     233        WERROR werr;
    113234
    114235        if (!ctr->subkeys) {
     
    116237        }
    117238
    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;
    124245}
    125246
     
    128249 **********************************************************************/
    129250
    130 int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
     251int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr )
    131252{
    132253        return ctr->num_subkeys;
     
    137258 **********************************************************************/
    138259
    139 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
     260char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index )
    140261{
    141262        if ( ! (key_index < ctr->num_subkeys) )
  • branches/samba-3.3.x/source/registry/regfio.c

    r206 r223  
    16941694
    16951695 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,
    16971697                               SEC_DESC *sec_desc, REGF_NK_REC *parent )
    16981698{
Note: See TracChangeset for help on using the changeset viewer.