diff options
-rw-r--r-- | source3/rpc_client/cli_winreg.c | 101 | ||||
-rw-r--r-- | source3/rpc_client/cli_winreg.h | 30 |
2 files changed, 131 insertions, 0 deletions
diff --git a/source3/rpc_client/cli_winreg.c b/source3/rpc_client/cli_winreg.c index 821efe4e21..9fa2d3171e 100644 --- a/source3/rpc_client/cli_winreg.c +++ b/source3/rpc_client/cli_winreg.c @@ -881,4 +881,105 @@ NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx, return status; } + +NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *h, + struct policy_handle *hive_handle, + uint32_t access_mask, + const char *key, + WERROR *pwerr) +{ + const char **subkeys = NULL; + uint32_t num_subkeys = 0; + struct policy_handle key_hnd; + struct winreg_String wkey = { 0, }; + WERROR result = WERR_OK; + NTSTATUS status = NT_STATUS_OK; + uint32_t i; + + ZERO_STRUCT(key_hnd); + wkey.name = key; + + DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key)); + /* open the key */ + status = dcerpc_winreg_OpenKey(h, + mem_ctx, + hive_handle, + wkey, + 0, + access_mask, + &key_hnd, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n", + wkey.name, nt_errstr(status))); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n", + wkey.name, win_errstr(result))); + *pwerr = result; + goto done; + } + + status = dcerpc_winreg_enum_keys(mem_ctx, + h, + &key_hnd, + &num_subkeys, + &subkeys, + &result); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + for (i = 0; i < num_subkeys; i++) { + /* create key + subkey */ + char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]); + if (subkey == NULL) { + goto done; + } + + DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey)); + status = dcerpc_winreg_delete_subkeys_recursive(mem_ctx, + h, + hive_handle, + access_mask, + subkey, + &result); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (is_valid_policy_hnd(&key_hnd)) { + WERROR ignore; + dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore); + } + + wkey.name = key; + + status = dcerpc_winreg_DeleteKey(h, + mem_ctx, + hive_handle, + wkey, + &result); + if (!NT_STATUS_IS_OK(status)) { + *pwerr = result; + goto done; + } + +done: + if (is_valid_policy_hnd(&key_hnd)) { + WERROR ignore; + + dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore); + } + + *pwerr = result; + return status; +} + /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ diff --git a/source3/rpc_client/cli_winreg.h b/source3/rpc_client/cli_winreg.h index f4af4ce849..a5162633db 100644 --- a/source3/rpc_client/cli_winreg.h +++ b/source3/rpc_client/cli_winreg.h @@ -414,6 +414,36 @@ NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx, DATA_BLOB **pdata, WERROR *pwerr); +/** + * @internal + * + * @brief A function to delete a key and its subkeys recurively. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] winreg_handle The binding handle for the rpc connection. + * + * @param[in] hive_handle A opened hive handle to the key. + * + * @param[in] access_mask The access mask to access the key. + * + * @param[in] key The key to delete + * + * @param[out] WERR_OK on success, the corresponding DOS error + * code if something gone wrong. + * + * @return NT_STATUS_OK on success or a corresponding error if + * there was a problem on the connection. + */ + +NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *h, + struct policy_handle *hive_handle, + uint32_t access_mask, + const char *key, + WERROR *pwerr); + + #endif /* CLI_WINREG_H */ /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ |