summaryrefslogtreecommitdiff
path: root/source4/lib/registry
diff options
context:
space:
mode:
authorAndrew Kroeger <andrew@sprocks.gotdns.com>2008-02-16 15:19:00 -0600
committerAndrew Kroeger <andrew@sprocks.gotdns.com>2008-02-26 19:27:14 -0600
commit79eea32976d2991319c9d0ad32a150f34b029f99 (patch)
tree0415ab3273f55cff504114a817403c14b2aa2110 /source4/lib/registry
parent2bbd319cafe64935682799240b9c0aa9ff4d7e7a (diff)
downloadsamba-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/registry')
-rw-r--r--source4/lib/registry/regf.c53
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. */