diff options
author | Andrew Kroeger <andrew@sprocks.gotdns.com> | 2008-02-16 15:19:00 -0600 |
---|---|---|
committer | Andrew Kroeger <andrew@sprocks.gotdns.com> | 2008-02-26 19:27:14 -0600 |
commit | 79eea32976d2991319c9d0ad32a150f34b029f99 (patch) | |
tree | 0415ab3273f55cff504114a817403c14b2aa2110 /source4/lib | |
parent | 2bbd319cafe64935682799240b9c0aa9ff4d7e7a (diff) | |
download | samba-79eea32976d2991319c9d0ad32a150f34b029f99.tar.gz samba-79eea32976d2991319c9d0ad32a150f34b029f99.tar.bz2 samba-79eea32976d2991319c9d0ad32a150f34b029f99.zip |
registry: Implement recursive deletes for regf-backed registry.
When deleting a registry key that contains subkeys or values, Windows performs a
recursive deletion that removes any subkeys or values. This update makes
deletes for an regf-backed registry consistent with Windows.
The regf-backed registry does not have transactional integrity when performing
multiple operations. Therefore, if an error occurs during the recursive
deletion, the regf-backed registry may be left in an inconsistent state.
(This used to be commit b0321bad290d1a9399b4aba140a622e3af6d7575)
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/registry/regf.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 15b60745f0..6a35799a7e 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1618,10 +1618,55 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) return WERR_BADFILE; } - if (key->nk->subkeys_offset != -1 || - key->nk->values_offset != -1) { - DEBUG(0, ("Key '%s' is not empty.\n", name)); - return WERR_FILE_EXISTS; + if (key->nk->subkeys_offset != -1) { + char *sk_name; + struct hive_key *sk = (struct hive_key *)key; + int i = key->nk->num_subkeys; + while (i--) { + /* Get subkey information. */ + error = regf_get_subkey_by_index(parent_nk, sk, 0, + (const char **)&sk_name, + NULL, NULL); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve subkey by index.\n")); + return error; + } + + /* Delete subkey. */ + error = regf_del_key(sk, sk_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete key '%s'.\n", sk_name)); + return error; + } + + talloc_free(sk_name); + } + } + + if (key->nk->values_offset != -1) { + char *val_name; + struct hive_key *sk = (struct hive_key *)key; + DATA_BLOB data; + int i = key->nk->num_values; + while (i--) { + /* Get value information. */ + error = regf_get_value(parent_nk, sk, 0, + (const char **)&val_name, + NULL, &data); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve value by index.\n")); + return error; + } + + /* Delete value. */ + error = regf_del_value(sk, val_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete value '%s'.\n", val_name)); + return error; + } + + talloc_free(val_name); + } } /* Delete it from the subkey list. */ |