s3-rpc_client: Added a winreg helper to enum keys.
authorAndreas Schneider <asn@samba.org>
Fri, 28 Jan 2011 11:08:58 +0000 (12:08 +0100)
committerGünther Deschner <gd@samba.org>
Mon, 7 Feb 2011 11:32:00 +0000 (12:32 +0100)
Signed-off-by: Günther Deschner <gd@samba.org>
source3/rpc_client/cli_winreg.c
source3/rpc_client/cli_winreg.h

index 41be96985b5854ae00f6a31d354b7523ff08684e..081f951b2dce24102d33f211889190c1868ecbba 100644 (file)
@@ -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: */
index 5199bf6a7cd9a1b672945e607e6a62e273fb5804..e10792e574ff673e724798be0addef2d8e22eeac 100644 (file)
@@ -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: */