summaryrefslogtreecommitdiff
path: root/source3/registry/reg_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/registry/reg_api.c')
-rw-r--r--source3/registry/reg_api.c110
1 files changed, 70 insertions, 40 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 55e364feae..c263174bc2 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -111,6 +111,7 @@ static WERROR fill_subkey_cache(struct registry_key *key)
}
}
+ TALLOC_FREE(key->subkeys);
werr = regsubkey_ctr_init(key, &(key->subkeys));
W_ERROR_NOT_OK_RETURN(werr);
@@ -142,9 +143,9 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
SMB_ASSERT(strchr(name, '\\') == NULL);
- if (!(regkey = TALLOC_ZERO_P(mem_ctx, struct registry_key)) ||
+ if (!(regkey = talloc_zero(mem_ctx, struct registry_key)) ||
!(regkey->token = dup_nt_token(regkey, token)) ||
- !(regkey->key = TALLOC_ZERO_P(regkey, struct registry_key_handle)))
+ !(regkey->key = talloc_zero(regkey, struct registry_key_handle)))
{
result = WERR_NOMEM;
goto done;
@@ -189,7 +190,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
/* Tag this as a Performance Counter Key */
- if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
+ if( strncasecmp_m(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
key->type = REG_KEY_HKPD;
/* Look up the table of registry I/O operations */
@@ -305,7 +306,8 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
return WERR_ACCESS_DENIED;
}
- if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) {
+ err = fill_subkey_cache(key);
+ if (!W_ERROR_IS_OK(err)) {
return err;
}
@@ -337,7 +339,8 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
return WERR_ACCESS_DENIED;
}
- if (!(W_ERROR_IS_OK(err = fill_value_cache(key)))) {
+ err = fill_value_cache(key);
+ if (!(W_ERROR_IS_OK(err))) {
return err;
}
@@ -553,7 +556,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
enum winreg_CreateAction *paction)
{
struct registry_key *key = parent;
- struct registry_key *create_parent;
TALLOC_CTX *mem_ctx;
char *path, *end;
WERROR err;
@@ -665,21 +667,51 @@ trans_done:
return err;
}
-WERROR reg_deletekey(struct registry_key *parent, const char *path)
+static WERROR reg_deletekey_internal(TALLOC_CTX *mem_ctx,
+ struct registry_key *parent,
+ const char *path, bool lazy)
{
WERROR err;
char *name, *end;
- struct registry_key *tmp_key, *key;
- TALLOC_CTX *mem_ctx = talloc_stackframe();
-
+ struct registry_key *key;
name = talloc_strdup(mem_ctx, path);
if (name == NULL) {
err = WERR_NOMEM;
goto done;
}
+ /* no subkeys - proceed with delete */
+ end = strrchr(name, '\\');
+ if (end != NULL) {
+ *end = '\0';
+
+ err = reg_openkey(mem_ctx, parent, name,
+ KEY_CREATE_SUB_KEY, &key);
+ W_ERROR_NOT_OK_GOTO_DONE(err);
+
+ parent = key;
+ name = end+1;
+ }
+
+ if (name[0] == '\0') {
+ err = WERR_INVALID_PARAM;
+ goto done;
+ }
+
+ err = delete_reg_subkey(parent->key, name, lazy);
+
+done:
+ return err;
+}
+
+WERROR reg_deletekey(struct registry_key *parent, const char *path)
+{
+ WERROR err;
+ struct registry_key *key;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
/* check if the key has subkeys */
- err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key);
+ err = reg_openkey(mem_ctx, parent, path, REG_KEY_READ, &key);
W_ERROR_NOT_OK_GOTO_DONE(err);
err = regdb_transaction_start();
@@ -690,32 +722,15 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path)
}
err = fill_subkey_cache(key);
- W_ERROR_NOT_OK_GOTO(err, trans_done);
-
- if (regsubkey_ctr_numkeys(key->subkeys) > 0) {
- err = WERR_ACCESS_DENIED;
+ if (!W_ERROR_IS_OK(err)) {
goto trans_done;
}
- /* no subkeys - proceed with delete */
- end = strrchr(name, '\\');
- if (end != NULL) {
- *end = '\0';
-
- err = reg_openkey(mem_ctx, parent, name,
- KEY_CREATE_SUB_KEY, &tmp_key);
- W_ERROR_NOT_OK_GOTO(err, trans_done);
-
- parent = tmp_key;
- name = end+1;
- }
-
- if (name[0] == '\0') {
- err = WERR_INVALID_PARAM;
+ if (regsubkey_ctr_numkeys(key->subkeys) > 0) {
+ err = WERR_ACCESS_DENIED;
goto trans_done;
}
-
- err = delete_reg_subkey(parent->key, name);
+ err = reg_deletekey_internal(mem_ctx, parent, path, false);
trans_done:
if (W_ERROR_IS_OK(err)) {
@@ -735,6 +750,7 @@ done:
return err;
}
+
WERROR reg_setvalue(struct registry_key *key, const char *name,
const struct registry_value *val)
{
@@ -931,7 +947,7 @@ WERROR reg_deleteallvalues(struct registry_key *key)
*/
static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
const char *path,
- bool del_key)
+ bool del_key, bool lazy)
{
WERROR werr = WERR_OK;
struct registry_key *key;
@@ -939,9 +955,15 @@ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
uint32 i;
TALLOC_CTX *mem_ctx = talloc_stackframe();
+ DEBUG(5, ("reg_deletekey_recursive_internal: deleting '%s' from '%s'\n",
+ path, parent->key->name));
+
/* recurse through subkeys first */
werr = reg_openkey(mem_ctx, parent, path, REG_KEY_ALL, &key);
if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(3, ("reg_deletekey_recursive_internal: error opening "
+ "subkey '%s' of '%s': '%s'\n",
+ path, parent->key->name, win_errstr(werr)));
goto done;
}
@@ -954,16 +976,20 @@ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
*/
for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) {
subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1);
- werr = reg_deletekey_recursive_internal(key, subkey_name, true);
+ werr = reg_deletekey_recursive_internal(key, subkey_name, true, del_key);
W_ERROR_NOT_OK_GOTO_DONE(werr);
}
if (del_key) {
/* now delete the actual key */
- werr = reg_deletekey(parent, path);
+ werr = reg_deletekey_internal(mem_ctx, parent, path, lazy);
}
done:
+
+ DEBUG(5, ("reg_deletekey_recursive_internal: done deleting '%s' from "
+ "'%s': %s\n",
+ path, parent->key->name, win_errstr(werr)));
TALLOC_FREE(mem_ctx);
return werr;
}
@@ -982,14 +1008,14 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
return werr;
}
- werr = reg_deletekey_recursive_internal(parent, path, del_key);
+ werr = reg_deletekey_recursive_internal(parent, path, del_key, false);
if (!W_ERROR_IS_OK(werr)) {
WERROR werr2;
-
- DEBUG(1, (__location__ " failed to delete key '%s' from key "
- "'%s': %s\n", path, parent->key->name,
- win_errstr(werr)));
+ DEBUG(W_ERROR_EQUAL(werr, WERR_BADFILE) ? 5 : 1,
+ (__location__ ": failed to delete key '%s' from key "
+ "'%s': %s\n", path, parent->key->name,
+ win_errstr(werr)));
werr2 = regdb_transaction_cancel();
if (!W_ERROR_IS_OK(werr2)) {
@@ -1007,6 +1033,10 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
DEBUG(0, ("reg_deletekey_recursive_trans: "
"error committing transaction: %s\n",
win_errstr(werr)));
+ } else {
+ DEBUG(5, ("reg_reletekey_recursive_trans: deleted key '%s' from '%s'\n",
+ path, parent->key->name));
+
}
}