diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/rpc_client/cli_winreg.c | 135 | ||||
-rw-r--r-- | source3/rpc_client/cli_winreg.h | 26 |
2 files changed, 161 insertions, 0 deletions
diff --git a/source3/rpc_client/cli_winreg.c b/source3/rpc_client/cli_winreg.c index 41be96985b..081f951b2d 100644 --- a/source3/rpc_client/cli_winreg.c +++ b/source3/rpc_client/cli_winreg.c @@ -445,4 +445,139 @@ NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx, return status; } +NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *h, + struct policy_handle *key_hnd, + uint32_t *pnum_subkeys, + const char ***psubkeys, + WERROR *pwerr) +{ + const char **subkeys; + uint32_t num_subkeys, max_subkeylen, max_classlen; + uint32_t num_values, max_valnamelen, max_valbufsize; + uint32_t i; + NTTIME last_changed_time; + uint32_t secdescsize; + struct winreg_String classname; + WERROR result = WERR_OK; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCT(classname); + + status = dcerpc_winreg_QueryInfoKey(h, + tmp_ctx, + key_hnd, + &classname, + &num_subkeys, + &max_subkeylen, + &max_classlen, + &num_values, + &max_valnamelen, + &max_valbufsize, + &secdescsize, + &last_changed_time, + &result); + if (!NT_STATUS_IS_OK(status)) { + goto error; + } + if (!W_ERROR_IS_OK(result)) { + *pwerr = result; + goto error; + } + + subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2); + if (subkeys == NULL) { + *pwerr = WERR_NOMEM; + goto error; + } + + if (num_subkeys == 0) { + subkeys[0] = talloc_strdup(subkeys, ""); + if (subkeys[0] == NULL) { + *pwerr = WERR_NOMEM; + goto error; + } + *pnum_subkeys = 0; + if (psubkeys) { + *psubkeys = talloc_move(mem_ctx, &subkeys); + } + + TALLOC_FREE(tmp_ctx); + return NT_STATUS_OK; + } + + for (i = 0; i < num_subkeys; i++) { + char c = '\0'; + char n = '\0'; + char *name = NULL; + struct winreg_StringBuf class_buf; + struct winreg_StringBuf name_buf; + NTTIME modtime; + + class_buf.name = &c; + class_buf.size = max_classlen + 2; + class_buf.length = 0; + + name_buf.name = &n; + name_buf.size = max_subkeylen + 2; + name_buf.length = 0; + + ZERO_STRUCT(modtime); + + status = dcerpc_winreg_EnumKey(h, + tmp_ctx, + key_hnd, + i, + &name_buf, + &class_buf, + &modtime, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n", + nt_errstr(status))); + goto error; + } + + if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) { + *pwerr = WERR_OK; + break; + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n", + win_errstr(result))); + *pwerr = result; + goto error; + } + + if (name_buf.name == NULL) { + *pwerr = WERR_INVALID_PARAMETER; + goto error; + } + + name = talloc_strdup(subkeys, name_buf.name); + if (name == NULL) { + *pwerr = WERR_NOMEM; + goto error; + } + + subkeys[i] = name; + } + + *pnum_subkeys = num_subkeys; + if (psubkeys) { + *psubkeys = talloc_move(mem_ctx, &subkeys); + } + + error: + TALLOC_FREE(tmp_ctx); + + 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 5199bf6a7c..e10792e574 100644 --- a/source3/rpc_client/cli_winreg.h +++ b/source3/rpc_client/cli_winreg.h @@ -243,6 +243,32 @@ NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx, const char *data, WERROR *pwerr); +/** + * @brief Enumerate on the given keyhandle to get the subkey names. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] h The binding handle for the rpc connection. + * + * @param[in] key_handle A handle to a key that MUST have been opened + * previously. + * + * @param[out] pnum_subkeys A pointer to store the number of subkeys. + * + * @param[out] psubkeys A pointer to store the names of the subkeys. + * + * @param[out] pwerr A pointer to a WERROR to store result of the query. + * + * @return NT_STATUS_OK on success or a corresponding error if + * there was a problem on the connection. + */ +NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *h, + struct policy_handle *key_hnd, + uint32_t *pnum_subkeys, + const char ***psubkeys, + WERROR *pwerr); + #endif /* CLI_WINREG_H */ /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ |