r19991: Sorry for this 2000-liner...
[tprouty/samba.git] / source3 / utils / net_rpc_registry.c
index 4c740be44dcf88c8f58b350510c3be6fd0199652..3634b0a4f239d5e396af0e0023c49c6299b33c24 100644 (file)
@@ -208,121 +208,6 @@ static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
        return status;
 }
 
-static NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx,
-                                   struct registry_value **pvalue,
-                                   enum winreg_Type type, uint8 *data,
-                                   uint32 size, uint32 length)
-{
-       struct registry_value *value;
-       NTSTATUS status;
-
-       if (!(value = TALLOC_ZERO_P(mem_ctx, struct registry_value))) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       value->type = type;
-
-       switch (type) {
-       case REG_DWORD:
-               if ((size != 4) || (length != 4)) {
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto error;
-               }
-               value->v.dword = IVAL(data, 0);
-               break;
-       case REG_SZ:
-       case REG_EXPAND_SZ:
-       {
-               /*
-                * Make sure we get a NULL terminated string for
-                * convert_string_talloc().
-                */
-
-               smb_ucs2_t *tmp;
-               uint32 num_ucs2 = length / 2;
-
-               if ((length % 2) != 0) {
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto error;
-               }
-
-               if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, num_ucs2+1))) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto error;
-               }
-
-               memcpy((void *)tmp, (const void *)data, length);
-               tmp[num_ucs2] = 0;
-
-               value->v.sz.len = convert_string_talloc(
-                       value, CH_UTF16LE, CH_UNIX, tmp, length+2,
-                       &value->v.sz.str, False);
-
-               SAFE_FREE(tmp);
-
-               if (value->v.sz.len == (size_t)-1) {
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto error;
-               }
-               break;
-       }
-       case REG_MULTI_SZ:
-               status = reg_pull_multi_sz(value, (void *)data, length,
-                                          &value->v.multi_sz.num_strings,
-                                          &value->v.multi_sz.strings);
-               if (!(NT_STATUS_IS_OK(status))) {
-                       goto error;
-               }
-               break;
-       case REG_BINARY:
-               value->v.binary.data = talloc_move(value, &data);
-               value->v.binary.length = length;
-               break;
-       default:
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto error;
-       }
-
-       *pvalue = value;
-       return NT_STATUS_OK;
-
- error:
-       TALLOC_FREE(value);
-       return status;
-}
-
-static NTSTATUS registry_push_value(TALLOC_CTX *mem_ctx,
-                                   const struct registry_value *value,
-                                   DATA_BLOB *presult)
-{
-       switch (value->type) {
-       case REG_DWORD: {
-               char buf[4];
-               SIVAL(buf, 0, value->v.dword);
-               *presult = data_blob_talloc(mem_ctx, (void *)buf, 4);
-               if (presult->data == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               break;
-       }
-       case REG_SZ:
-       case REG_EXPAND_SZ: {
-               presult->length = convert_string_talloc(
-                       mem_ctx, CH_UNIX, CH_UTF16LE, value->v.sz.str,
-                       MIN(value->v.sz.len, strlen(value->v.sz.str)+1),
-                       (void *)&(presult->data), False);
-               if (presult->length == (size_t)-1) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               break;
-       }
-       default:
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
                                    struct rpc_pipe_client *pipe_hnd,
                                    struct policy_handle *key_hnd,
@@ -380,7 +265,8 @@ static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
                uint32 *pvalue_length = &value_length;
 
                char n;
-               struct winreg_StringBuf name_buf;
+               struct winreg_ValNameBuf name_buf;
+               WERROR err;
 
                n = '\0';
                name_buf.name = &n;
@@ -416,9 +302,10 @@ static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
                        goto error;
                }
 
-               status = registry_pull_value(values, &values[i], *ptype, data,
-                                            *pdata_size, *pvalue_length);
-               if (!(NT_STATUS_IS_OK(status))) {
+               err = registry_pull_value(values, &values[i], *ptype, data,
+                                         *pdata_size, *pvalue_length);
+               if (!W_ERROR_IS_OK(err)) {
+                       status = werror_to_ntstatus(err);
                        goto error;
                }
        }
@@ -448,10 +335,11 @@ static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
        struct winreg_String name_string;
        DATA_BLOB blob;
        NTSTATUS result;
+       WERROR err;
 
-       result = registry_push_value(mem_ctx, value, &blob);
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
+       err = registry_push_value(mem_ctx, value, &blob);
+       if (!W_ERROR_IS_OK(err)) {
+               return werror_to_ntstatus(err);
        }
 
        name_string.name = name;
@@ -529,6 +417,169 @@ static int rpc_registry_setvalue( int argc, const char **argv )
                rpc_registry_setvalue_internal, argc, argv );
 }
 
+static NTSTATUS rpc_registry_deletevalue_internal(const DOM_SID *domain_sid,
+                                                 const char *domain_name, 
+                                                 struct cli_state *cli,
+                                                 struct rpc_pipe_client *pipe_hnd,
+                                                 TALLOC_CTX *mem_ctx, 
+                                                 int argc,
+                                                 const char **argv )
+{
+       struct policy_handle hive_hnd, key_hnd;
+       NTSTATUS status;
+       struct winreg_String valuename;
+
+       status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_WRITE,
+                                 &hive_hnd, &key_hnd);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "registry_openkey failed: %s\n",
+                         nt_errstr(status));
+               return status;
+       }
+
+       valuename.name = argv[1];
+
+       status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
+                                          valuename);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "registry_deletevalue failed: %s\n",
+                         nt_errstr(status));
+       }
+
+       rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
+       rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
+
+       return NT_STATUS_OK;
+}
+
+static int rpc_registry_deletevalue( int argc, const char **argv )
+{
+       if (argc != 2) {
+               d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
+                         "<valuename>\n");
+               return -1;
+       }
+
+       return run_rpc_command( NULL, PI_WINREG, 0, 
+               rpc_registry_deletevalue_internal, argc, argv );
+}
+
+static NTSTATUS rpc_registry_createkey_internal(const DOM_SID *domain_sid,
+                                               const char *domain_name, 
+                                               struct cli_state *cli,
+                                               struct rpc_pipe_client *pipe_hnd,
+                                               TALLOC_CTX *mem_ctx, 
+                                               int argc,
+                                               const char **argv )
+{
+       uint32 hive;
+       struct policy_handle hive_hnd, key_hnd;
+       struct winreg_String key, keyclass;
+       enum winreg_CreateAction action;
+       enum winreg_CreateAction *paction = &action;
+       NTSTATUS status;
+
+       if (!reg_hive_key(argv[0], &hive, &key.name)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
+                                      REG_KEY_READ|REG_KEY_WRITE,
+                                      &hive_hnd);
+       if (!(NT_STATUS_IS_OK(status))) {
+               return status;
+       }
+
+       action = REG_ACTION_NONE;
+       keyclass.name = "";
+
+       status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
+                                        keyclass, 0, REG_KEY_READ, NULL,
+                                        &key_hnd, &paction);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "createkey returned %s\n",
+                         nt_errstr(status));
+               rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
+               return status;
+       }
+
+       if (paction) {
+               switch (*paction) {
+               case REG_ACTION_NONE:
+                       d_printf("createkey did nothing -- huh?\n");
+                       break;
+               case REG_CREATED_NEW_KEY:
+                       d_printf("createkey created %s\n", argv[0]);
+                       break;
+               case REG_OPENED_EXISTING_KEY:
+                       d_printf("createkey opened existing %s\n", argv[0]);
+                       break;
+               }
+       }
+
+       rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
+       rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
+
+       return status;
+}
+
+static int rpc_registry_createkey( int argc, const char **argv )
+{
+       if (argc != 1) {
+               d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
+               return -1;
+       }
+
+       return run_rpc_command( NULL, PI_WINREG, 0, 
+               rpc_registry_createkey_internal, argc, argv );
+}
+
+static NTSTATUS rpc_registry_deletekey_internal(const DOM_SID *domain_sid,
+                                               const char *domain_name, 
+                                               struct cli_state *cli,
+                                               struct rpc_pipe_client *pipe_hnd,
+                                               TALLOC_CTX *mem_ctx, 
+                                               int argc,
+                                               const char **argv )
+{
+       uint32 hive;
+       struct policy_handle hive_hnd;
+       struct winreg_String key;
+       NTSTATUS status;
+
+       if (!reg_hive_key(argv[0], &hive, &key.name)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, REG_KEY_WRITE,
+                                      &hive_hnd);
+       if (!(NT_STATUS_IS_OK(status))) {
+               return status;
+       }
+
+       status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key);
+       rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "deletekey returned %s\n",
+                         nt_errstr(status));
+       }
+
+       return status;
+}
+
+static int rpc_registry_deletekey( int argc, const char **argv )
+{
+       if (argc != 1) {
+               d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
+               return -1;
+       }
+
+       return run_rpc_command( NULL, PI_WINREG, 0, 
+               rpc_registry_deletekey_internal, argc, argv );
+}
+
 /********************************************************************
 ********************************************************************/
 
@@ -542,12 +593,12 @@ static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
 {
        POLICY_HND pol_hive, pol_key; 
        NTSTATUS status;
-       uint32 num_subkeys;
-       uint32 num_values;
-       char **names, **classes;
-       NTTIME **modtimes;
+       uint32 num_subkeys = 0;
+       uint32 num_values = 0;
+       char **names = NULL, **classes = NULL;
+       NTTIME **modtimes = NULL;
        uint32 i;
-       struct registry_value **values;
+       struct registry_value **values = NULL;
        
        if (argc != 1 ) {
                d_printf("Usage:    net rpc enumerate <path> [recurse]\n");
@@ -917,8 +968,14 @@ int net_rpc_registry(int argc, const char **argv)
        struct functable2 func[] = {
                { "enumerate", rpc_registry_enumerate,
                  "Enumerate registry keys and values" },
+               { "createkey",  rpc_registry_createkey,
+                 "Create a new registry key" },
+               { "deletekey",  rpc_registry_deletekey,
+                 "Delete a registry key" },
                { "setvalue",  rpc_registry_setvalue,
                  "Set a new registry value" },
+               { "deletevalue",  rpc_registry_deletevalue,
+                 "Delete a registry value" },
                { "save", rpc_registry_save,
                  "Save a registry file" },
                { "dump", rpc_registry_dump,