diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
commit | 5209a846a9157e649fcdcb561f7eaf19c8c0e465 (patch) | |
tree | b0a7e52b5646c8eec182dbc391e7934b6804488c /source4/lib/registry | |
parent | 625359b2e266105022309df8985720108ecd6f67 (diff) | |
parent | 2ee8d29d22bcb1c350ab59d71b0aee548489bc9c (diff) | |
download | samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.gz samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.bz2 samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
Conflicts:
source4/lib/registry/ldb.c
source4/rpc_server/winreg/rpc_winreg.c
Diffstat (limited to 'source4/lib/registry')
-rw-r--r-- | source4/lib/registry/dir.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/interface.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/ldb.c | 19 | ||||
-rw-r--r-- | source4/lib/registry/local.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/patchfile.c | 146 | ||||
-rw-r--r-- | source4/lib/registry/regf.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/registry.h | 16 | ||||
-rw-r--r-- | source4/lib/registry/registry.i | 2 | ||||
-rw-r--r-- | source4/lib/registry/rpc.c | 268 | ||||
-rw-r--r-- | source4/lib/registry/tests/generic.c | 6 | ||||
-rw-r--r-- | source4/lib/registry/tools/regdiff.c | 2 | ||||
-rw-r--r-- | source4/lib/registry/tools/regshell.c | 28 | ||||
-rw-r--r-- | source4/lib/registry/tools/regtree.c | 23 | ||||
-rw-r--r-- | source4/lib/registry/util.c | 3 |
14 files changed, 307 insertions, 214 deletions
diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 449ee0f6ee..42946bceec 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -327,7 +327,7 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, size_t size; char *contents; - contents = file_load(path, &size, mem_ctx); + contents = file_load(path, &size, 0, mem_ctx); talloc_free(path); if (contents == NULL) return WERR_BADFILE; diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index c9b3b06447..81ca2c39bc 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -18,7 +18,7 @@ */ #include "includes.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "lib/registry/registry.h" #include "system/filesys.h" diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 87d066e2de..9c1f59c4df 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -225,7 +225,7 @@ static WERROR cache_subkeys(struct ldb_key_data *kd) struct ldb_result *res; int ret; - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); + ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL, NULL, "(key=*)"); if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting subkeys for '%s': %s\n", @@ -246,8 +246,8 @@ static WERROR cache_values(struct ldb_key_data *kd) struct ldb_result *res; int ret; - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, - "(value=*)", NULL, &res); + ret = ldb_search(c, c, &res, kd->dn, LDB_SCOPE_ONELEVEL, + NULL, "(value=*)"); if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting values for '%s': %s\n", @@ -373,7 +373,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, } else { /* normal value */ query = talloc_asprintf(mem_ctx, "(value=%s)", name); - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res); + ret = ldb_search(c, kd->dn, &res, LDB_SCOPE_ONELEVEL, query, NULL, "%s", query); talloc_free(query); if (ret != LDB_SUCCESS) { @@ -391,6 +391,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, talloc_free(res); } + talloc_free(res); return WERR_OK; } @@ -406,7 +407,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL); - ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); + ret = ldb_search(c, mem_ctx, &res, ldap_path, LDB_SCOPE_BASE, NULL, "(key=*)"); if (ret != LDB_SUCCESS) { DEBUG(3, ("Error opening key '%s': %s\n", @@ -598,8 +599,8 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name) } /* Search for subkeys */ - ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, - "(key=*)", NULL, &res_keys); + ret = ldb_search(c, mem_ctx, &res_keys, ldap_path, LDB_SCOPE_ONELEVEL, + NULL, "(key=*)"); if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting subkeys for '%s': %s\n", @@ -609,8 +610,8 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name) } /* Search for values */ - ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, - "(value=*)", NULL, &res_vals); + ret = ldb_search(c, mem_ctx, &res_vals, ldap_path, LDB_SCOPE_ONELEVEL, + NULL, "(value=*)"); if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting values for '%s': %s\n", diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 4af95e2dd6..a3aee06b13 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "lib/registry/registry.h" #include "system/filesys.h" diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 0ede3106f0..a6f947ee78 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -4,6 +4,7 @@ Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 + Copyright (C) Matthias Dieter Wallnöfer 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -58,8 +59,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, &old_num_subkeys, &old_num_values, NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", + DEBUG(0, ("Error occurred while getting key info: %s\n", win_errstr(error))); + talloc_free(mem_ctx); return error; } } else { @@ -67,37 +69,46 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, old_num_values = 0; } - /* Subkeys that were deleted */ + /* Subkeys that were changed or deleted */ for (i = 0; i < old_num_subkeys; i++) { error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, - &keyname1, - NULL, NULL); + &keyname1, NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occurred while getting subkey by index: %s\n", + win_errstr(error1))); continue; } if (newkey != NULL) { error2 = reg_open_key(mem_ctx, newkey, keyname1, &t2); - - if (W_ERROR_IS_OK(error2)) - continue; } else { error2 = WERR_BADFILE; t2 = NULL; } - if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { + if (!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } - /* newkey didn't have such a subkey, add del diff */ + /* if "error2" is going to be "WERR_BADFILE", then newkey */ + /* didn't have such a subkey and therefore add a del diff */ tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); - callbacks->del_key(callback_data, tmppath); + if (!W_ERROR_IS_OK(error2)) + callbacks->del_key(callback_data, tmppath); + + /* perform here also the recursive invocation */ + error1 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error1))); + talloc_free(mem_ctx); + return error1; + } + reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); + talloc_free(tmppath); } @@ -106,8 +117,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, &new_num_subkeys, &new_num_values, NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", + DEBUG(0, ("Error occurred while getting key info: %s\n", win_errstr(error))); + talloc_free(mem_ctx); return error; } } else { @@ -117,11 +129,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Subkeys that were added */ for(i = 0; i < new_num_subkeys; i++) { - error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, - i, &keyname1, - NULL, NULL); + error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, + &keyname1, NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", + DEBUG(0, ("Error occurred while getting subkey by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; @@ -133,12 +144,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (W_ERROR_IS_OK(error2)) continue; } else { + error2 = WERR_BADFILE; t1 = NULL; - error2 = WERR_BADFILE; } if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { - DEBUG(0, ("Error occured while getting subkey by name: %s\n", + DEBUG(0, ("Error occurred while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; @@ -148,15 +159,20 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); callbacks->add_key(callback_data, tmppath); - W_ERROR_NOT_OK_RETURN( - reg_open_key(mem_ctx, newkey, keyname1, &t2)); + /* perform here also the recursive invocation */ + error1 = reg_open_key(mem_ctx, newkey, keyname1, &t2); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error1))); + talloc_free(mem_ctx); + return error1; + } + reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); - reg_generate_diff_key(t1, t2, tmppath, - callbacks, callback_data); talloc_free(tmppath); } - /* Values that were changed */ + /* Values that were added or changed */ for(i = 0; i < new_num_values; i++) { const char *name; uint32_t type1, type2; @@ -165,7 +181,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &name, &type1, &contents1); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Unable to get key by index: %s\n", + DEBUG(0, ("Unable to get value by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; @@ -178,16 +194,17 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } else error2 = WERR_BADFILE; - if(!W_ERROR_IS_OK(error2) && - !W_ERROR_EQUAL(error2, WERR_BADFILE)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", + if (!W_ERROR_IS_OK(error2) + && !W_ERROR_EQUAL(error2, WERR_BADFILE)) { + DEBUG(0, ("Error occurred while getting value by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } - if (W_ERROR_IS_OK(error2) && - data_blob_cmp(&contents1, &contents2) == 0) + if (W_ERROR_IS_OK(error2) + && (data_blob_cmp(&contents1, &contents2) == 0) + && (type1 == type2)) continue; callbacks->set_value(callback_data, path, name, @@ -197,24 +214,31 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Values that were deleted */ for (i = 0; i < old_num_values; i++) { const char *name; + uint32_t type; + DATA_BLOB contents; + error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, - NULL, NULL); + &type, &contents); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error ocurred getting value by index: %s\n", + DEBUG(0, ("Unable to get value by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } - error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, - NULL); + if (newkey != NULL) + error2 = reg_key_get_value_by_name(mem_ctx, newkey, + name, &type, &contents); + else + error2 = WERR_BADFILE; if (W_ERROR_IS_OK(error2)) continue; if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", + DEBUG(0, ("Error occurred while getting value by name: %s\n", win_errstr(error2))); + talloc_free(mem_ctx); return error2; } @@ -236,27 +260,30 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, int i; WERROR error; - for(i = HKEY_FIRST; i <= HKEY_LAST; i++) { + for (i = 0; reg_predefined_keys[i].name; i++) { struct registry_key *r1 = NULL, *r2 = NULL; - error = reg_get_predefined_key(ctx1, i, &r1); + + error = reg_get_predefined_key(ctx1, + reg_predefined_keys[i].handle, &r1); if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 1\n", - reg_get_predef_name(i))); + reg_predefined_keys[i].name)); + continue; } - error = reg_get_predefined_key(ctx2, i, &r2); + error = reg_get_predefined_key(ctx2, + reg_predefined_keys[i].handle, &r2); if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 2\n", - reg_get_predef_name(i))); - } - - if (r1 == NULL && r2 == NULL) + reg_predefined_keys[i].name)); continue; + } - error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), - callbacks, callback_data); + error = reg_generate_diff_key(r1, r2, + reg_predefined_keys[i].name, callbacks, + callback_data); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Unable to determine diff: %s\n", win_errstr(error))); @@ -357,14 +384,13 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) { struct registry_context *ctx = (struct registry_context *)_ctx; - WERROR error; - error = reg_key_del_abs(ctx, key_name); + /* We can't proof here for success, because a common superkey could */ + /* have been deleted before the subkey's (diff order). This removed */ + /* therefore all childs recursively and the "WERR_BADFILE" result is */ + /* expected. */ - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to delete key '%s'\n", key_name)); - return error; - } + reg_key_del_abs(ctx, key_name); return WERR_OK; } @@ -426,8 +452,7 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *key; WERROR error; - int i; - uint32_t num_values; + const char* value_name; error = reg_open_key_abs(ctx, ctx, key_name, &key); @@ -437,14 +462,15 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) } W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, NULL, - NULL, &num_values, NULL, NULL, NULL, NULL)); + NULL, NULL, NULL, NULL, NULL, NULL)); - for (i = 0; i < num_values; i++) { - const char *name; - W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, - &name, - NULL, NULL)); - W_ERROR_NOT_OK_RETURN(reg_del_value(key, name)); + while (W_ERROR_IS_OK(reg_key_get_value_by_index( + ctx, key, 0, &value_name, NULL, NULL))) { + error = reg_del_value(key, value_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error deleting value '%s'\n", value_name)); + return error; + } } return WERR_OK; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 57a895aa00..dd3ff47b78 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -2066,7 +2066,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, pull = tdr_pull_init(regf, regf->iconv_convenience); - pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf); + pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, 0, regf); if (pull->data.data == NULL) { DEBUG(0, ("Error reading data\n")); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index e134e3e532..e89d6fd55c 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -29,8 +29,8 @@ struct smb_iconv_convenience; #include "libcli/util/werror.h" #include "librpc/gen_ndr/security.h" #include "libcli/util/ntstatus.h" -#include "util/time.h" -#include "util/data_blob.h" +#include "../lib/util/time.h" +#include "../lib/util/data_blob.h" /** * The hive API. This API is generally used for @@ -508,6 +508,18 @@ WERROR reg_diff_load(const char *filename, const struct reg_diff_callbacks *callbacks, void *callback_data); +WERROR reg_dotreg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, + const struct reg_diff_callbacks *callbacks, + void *callback_data); + +WERROR reg_preg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, + const struct reg_diff_callbacks *callbacks, + void *callback_data); + +WERROR local_get_predefined_key(struct registry_context *ctx, + uint32_t key_id, struct registry_key **key); #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index c55197c3d0..fe3a81d889 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -43,7 +43,7 @@ typedef struct hive_key hive_key; } %import "stdint.i" -%import "../../lib/talloc/talloc.i" +%import "../../../lib/talloc/talloc.i" %import "../../auth/credentials/credentials.i" %import "../../param/param.i" %import "../events/events.i" diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 18b7607713..3a16ae1db5 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -2,6 +2,7 @@ Samba Unix/Linux SMB implementation RPC backend for the registry library Copyright (C) 2003-2007 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,16 +21,23 @@ #include "registry.h" #include "librpc/gen_ndr/ndr_winreg_c.h" +#define MAX_NAMESIZE 512 +#define MAX_VALSIZE 32768 + struct rpc_key { struct registry_key key; struct policy_handle pol; struct dcerpc_pipe *pipe; - uint32_t num_values; + const char* classname; uint32_t num_subkeys; + uint32_t max_subkeylen; + uint32_t max_classlen; + uint32_t num_values; uint32_t max_valnamelen; - uint32_t max_valdatalen; - uint32_t max_subkeynamelen; + uint32_t max_valbufsize; + uint32_t secdescsize; + NTTIME last_changed_time; }; struct rpc_registry_context { @@ -43,26 +51,22 @@ static struct registry_operations reg_backend_rpc; * This is the RPC backend for the registry library. */ -static void init_winreg_String(struct winreg_String *name, const char *s) -{ - name->name = s; -} - - #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ { \ struct winreg_Open ## u r; \ NTSTATUS status; \ - \ +\ + ZERO_STRUCT(r); \ r.in.system_name = NULL; \ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ - \ +\ status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ - if (NT_STATUS_IS_ERR(status)) {\ - DEBUG(0,("Error executing open\n"));\ - return ntstatus_to_werror(status);\ - }\ +\ + if (!NT_STATUS_IS_OK(status)) { \ + DEBUG(1, ("OpenHive failed - %s\n", nt_errstr(status))); \ + return ntstatus_to_werror(status); \ + } \ \ return r.out.result;\ } @@ -90,7 +94,7 @@ static struct { { 0, NULL } }; -static WERROR rpc_query_key(const struct registry_key *k); +static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k); static WERROR rpc_get_predefined_key(struct registry_context *ctx, uint32_t hkey_type, @@ -127,15 +131,15 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) struct winreg_OpenKey r; struct rpc_key_data *mykeydata; - k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); + k->backend_data = mykeydata = talloc_zero(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; /* Then, open the handle using the hive */ - memset(&r, 0, sizeof(struct winreg_OpenKey)); + ZERO_STRUCT(r); r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); + r.in.keyname.name = k->path; r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; @@ -155,8 +159,7 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, struct winreg_OpenKey r; NTSTATUS status; - mykeydata = talloc(mem_ctx, struct rpc_key); - + mykeydata = talloc_zero(mem_ctx, struct rpc_key); mykeydata->key.context = parentkeydata->key.context; mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe); mykeydata->num_values = -1; @@ -166,14 +169,15 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, /* Then, open the handle using the hive */ ZERO_STRUCT(r); r.in.parent_handle = &parentkeydata->pol; - init_winreg_String(&r.in.keyname, name); + r.in.keyname.name = name; r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0,("Error executing openkey: %s\n", nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("OpenKey failed - %s\n", nt_errstr(status))); return ntstatus_to_werror(status); } @@ -188,47 +192,94 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, DATA_BLOB *data) { struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); - WERROR error; struct winreg_EnumValue r; - uint32_t in_type = 0; - NTSTATUS status; struct winreg_StringBuf name; + uint8_t value; + uint32_t val_size = MAX_VALSIZE; uint32_t zero = 0; - - ZERO_STRUCT(r); + WERROR error; + NTSTATUS status; if (mykeydata->num_values == -1) { - error = rpc_query_key(parent); + error = rpc_query_key(mem_ctx, parent); if(!W_ERROR_IS_OK(error)) return error; } - name.length = 0; - name.size = mykeydata->max_valnamelen * 2; - name.name = NULL; + name.name = ""; + name.size = MAX_NAMESIZE; + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &name; - r.in.type = &in_type; - r.in.value = talloc_zero_array(mem_ctx, uint8_t, 0); + r.in.type = type; + r.in.value = &value; + r.in.size = &val_size; r.in.length = &zero; - r.in.size = &mykeydata->max_valdatalen; r.out.name = &name; r.out.type = type; + r.out.value = &value; + r.out.size = &val_size; + r.out.length = &zero; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); - if(NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); - return WERR_GENERAL_FAILURE; + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("EnumValue failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); } - if(NT_STATUS_IS_OK(status) && - W_ERROR_IS_OK(r.out.result) && r.out.length) { - *value_name = talloc_strdup(mem_ctx, r.out.name->name); - *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); - return WERR_OK; + *value_name = talloc_reference(mem_ctx, r.out.name->name); + *type = *(r.out.type); + *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); + + return r.out.result; +} + +static WERROR rpc_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + const char *value_name, + uint32_t *type, + DATA_BLOB *data) +{ + struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); + struct winreg_QueryValue r; + struct winreg_String name; + uint8_t value; + uint32_t val_size = MAX_VALSIZE; + uint32_t zero = 0; + WERROR error; + NTSTATUS status; + + if (mykeydata->num_values == -1) { + error = rpc_query_key(mem_ctx, parent); + if(!W_ERROR_IS_OK(error)) return error; } + name.name = value_name; + + ZERO_STRUCT(r); + r.in.handle = &mykeydata->pol; + r.in.value_name = &name; + r.in.type = type; + r.in.data = &value; + r.in.data_size = &val_size; + r.in.data_length = &zero; + r.out.type = type; + r.out.data = &value; + r.out.data_size = &val_size; + r.out.data_length = &zero; + + status = dcerpc_winreg_QueryValue(mykeydata->pipe, mem_ctx, &r); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("QueryValue failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + *type = *(r.out.type); + *data = data_blob_talloc(mem_ctx, r.out.data, *r.out.data_length); + return r.out.result; } @@ -241,34 +292,39 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, { struct winreg_EnumKey r; struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); - NTSTATUS status; struct winreg_StringBuf namebuf, classbuf; NTTIME change_time = 0; + NTSTATUS status; - ZERO_STRUCT(r); - - namebuf.length = 0; - namebuf.size = 1024; - namebuf.name = NULL; - classbuf.length = 0; - classbuf.size = 0; - classbuf.name = NULL; + namebuf.name = ""; + namebuf.size = MAX_NAMESIZE; + classbuf.name = NULL; + classbuf.size = 0; + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &namebuf; r.in.keyclass = &classbuf; r.in.last_changed_time = &change_time; - r.out.name = &namebuf; + r.out.keyclass = &classbuf; + r.out.last_changed_time = &change_time; status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); - if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - *name = talloc_strdup(mem_ctx, r.out.name->name); - if (keyclass != NULL) - *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("EnumKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); } + if (name != NULL) + *name = talloc_reference(mem_ctx, r.out.name->name); + if (keyclass != NULL) + *keyclass = talloc_reference(mem_ctx, r.out.keyclass->name); + if (last_changed_time != NULL) + *last_changed_time = *(r.out.last_changed_time); + return r.out.result; } @@ -278,19 +334,22 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct security_descriptor *sec, struct registry_key **key) { - NTSTATUS status; struct winreg_CreateKey r; struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key); struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key); + + NTSTATUS status; - init_winreg_String(&r.in.name, name); - init_winreg_String(&r.in.keyclass, NULL); - + ZERO_STRUCT(r); r.in.handle = &parentkd->pol; - r.out.new_handle = &rpck->pol; + r.in.name.name = name; + r.in.keyclass.name = NULL; r.in.options = 0; - r.in.access_mask = SEC_STD_ALL; + r.in.access_mask = 0x02000000; r.in.secdesc = NULL; + r.in.action_taken = NULL; + r.out.new_handle = &rpck->pol; + r.out.action_taken = NULL; status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r); @@ -300,49 +359,42 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, return ntstatus_to_werror(status); } - if (W_ERROR_IS_OK(r.out.result)) { - rpck->pipe = talloc_reference(rpck, parentkd->pipe); - *key = (struct registry_key *)rpck; - } + rpck->pipe = talloc_reference(rpck, parentkd->pipe); + *key = (struct registry_key *)rpck; return r.out.result; } -static WERROR rpc_query_key(const struct registry_key *k) +static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k) { - NTSTATUS status; struct winreg_QueryInfoKey r; struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); - TALLOC_CTX *mem_ctx = talloc_init("query_key"); - uint32_t max_subkeysize; - uint32_t secdescsize; - NTTIME last_changed_time; + struct winreg_String classname; + NTSTATUS status; - ZERO_STRUCT(r.out); + classname.name = NULL; + ZERO_STRUCT(r); + r.in.handle = &mykeydata->pol; + r.in.classname = &classname; + r.out.classname = &classname; r.out.num_subkeys = &mykeydata->num_subkeys; - r.out.max_subkeylen = &mykeydata->max_subkeynamelen; - r.out.max_valnamelen = &mykeydata->max_valnamelen; - r.out.max_valbufsize = &mykeydata->max_valdatalen; - r.out.max_subkeysize = &max_subkeysize; + r.out.max_subkeylen = &mykeydata->max_subkeylen; + r.out.max_classlen = &mykeydata->max_classlen; r.out.num_values = &mykeydata->num_values; - r.out.secdescsize = &secdescsize; - r.out.last_changed_time = &last_changed_time; - - r.out.classname = r.in.classname = talloc_zero(mem_ctx, struct winreg_String); - init_winreg_String(r.in.classname, NULL); - r.in.handle = &mykeydata->pol; + r.out.max_valnamelen = &mykeydata->max_valnamelen; + r.out.max_valbufsize = &mykeydata->max_valbufsize; + r.out.secdescsize = &mykeydata->secdescsize; + r.out.last_changed_time = &mykeydata->last_changed_time; status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); - talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); return ntstatus_to_werror(status); } - if (W_ERROR_IS_OK(r.out.result)) { - } + mykeydata->classname = talloc_reference(mem_ctx, r.out.classname->name); return r.out.result; } @@ -354,22 +406,28 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) struct winreg_DeleteKey r; TALLOC_CTX *mem_ctx = talloc_init("del_key"); + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, name); + r.in.key.name = name; status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("DeleteKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + return r.out.result; } static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char **classname, - uint32_t *numsubkeys, - uint32_t *numvalue, + uint32_t *num_subkeys, + uint32_t *num_values, NTTIME *last_changed_time, - uint32_t *max_subkeynamelen, + uint32_t *max_subkeylen, uint32_t *max_valnamelen, uint32_t *max_valbufsize) { @@ -377,27 +435,30 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, WERROR error; if (mykeydata->num_values == -1) { - error = rpc_query_key(key); + error = rpc_query_key(mem_ctx, key); if(!W_ERROR_IS_OK(error)) return error; } - /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */ - /* FIXME: *last_changed_time = mykeydata->last_changed_time */ + if (classname != NULL) + *classname = mykeydata->classname; + + if (num_subkeys != NULL) + *num_subkeys = mykeydata->num_subkeys; - if (numvalue != NULL) - *numvalue = mykeydata->num_values; + if (num_values != NULL) + *num_values = mykeydata->num_values; - if (numsubkeys != NULL) - *numsubkeys = mykeydata->num_subkeys; + if (last_changed_time != NULL) + *last_changed_time = mykeydata->last_changed_time; + + if (max_subkeylen != NULL) + *max_subkeylen = mykeydata->max_subkeylen; if (max_valnamelen != NULL) *max_valnamelen = mykeydata->max_valnamelen; if (max_valbufsize != NULL) - *max_valbufsize = mykeydata->max_valdatalen; - - if (max_subkeynamelen != NULL) - *max_subkeynamelen = mykeydata->max_subkeynamelen; + *max_valbufsize = mykeydata->max_valbufsize; return WERR_OK; } @@ -408,6 +469,7 @@ static struct registry_operations reg_backend_rpc = { .get_predefined_key = rpc_get_predefined_key, .enum_key = rpc_get_subkey_by_index, .enum_value = rpc_get_value_by_index, + .get_value = rpc_get_value_by_name, .create_key = rpc_add_key, .delete_key = rpc_del_key, .get_key_info = rpc_get_info, diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 6eae26bc46..2b7eb838ba 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -53,7 +53,7 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; - db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "bla", 3, (void **)&db.data); torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db), @@ -88,7 +88,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx) static bool test_reg_val_description(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "stationary traveller", strlen("stationary traveller"), (void **)&data.data); @@ -102,7 +102,7 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "west berlin", strlen("west berlin"), (void **)&data.data); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 240c582340..fcf7c26237 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -46,7 +46,7 @@ static struct registry_context *open_backend(poptContext pc, break; case REG_REMOTE: error = reg_open_remote(&ctx, NULL, cmdline_credentials, lp_ctx, - remote_host, NULL); + remote_host, ev_ctx); break; case REG_NULL: error = reg_open_local(NULL, &ctx); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 98f7f02c38..5c308bfbda 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -207,8 +207,8 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) { int i; WERROR error; - uint32_t data_type; - DATA_BLOB data; + uint32_t valuetype; + DATA_BLOB valuedata; const char *name = NULL; for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, @@ -221,19 +221,15 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) } if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while browsing thru keys: %s\n", - win_errstr(error))); + fprintf(stderr, "Error occured while browsing thru keys: %s\n", + win_errstr(error)); + return error; } for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx, - ctx->current, - i, - &name, - &data_type, - &data)); i++) { - printf("V \"%s\" %s %s\n", name, str_regtype(data_type), - reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), data_type, data)); - } + ctx->current, i, &name, &valuetype, &valuedata)); i++) + printf("V \"%s\" %s %s\n", name, str_regtype(valuetype), + reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), valuetype, valuedata)); return WERR_OK; } @@ -250,7 +246,8 @@ static WERROR cmd_mkkey(struct regshell_context *ctx, int argc, char **argv) error = reg_key_add_name(ctx, ctx->current, argv[1], 0, NULL, &tmp); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); + fprintf(stderr, "Error adding new subkey '%s': %s\n", argv[1], + win_errstr(error)); return error; } @@ -438,7 +435,7 @@ static char **reg_complete_key(const char *text, int start, int end) len = strlen(text); for(i = 0; j < MAX_COMPLETIONS-1; i++) { status = reg_key_get_subkey_by_index(mem_ctx, base, i, - &subkeyname, NULL, NULL); + &subkeyname, NULL, NULL); if(W_ERROR_IS_OK(status)) { if(!strncmp(text, subkeyname, len)) { matches[j] = strdup(subkeyname); @@ -536,7 +533,8 @@ int main(int argc, char **argv) if (ctx->current == NULL) { int i; - for (i = 0; reg_predefined_keys[i].handle; i++) { + for (i = 0; (reg_predefined_keys[i].handle != 0) && + (ctx->current == NULL); i++) { WERROR err; err = reg_get_predefined_key(ctx->registry, reg_predefined_keys[i].handle, diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 19e4a010b4..6d55a3eb84 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -38,10 +38,9 @@ static void print_tree(int level, struct registry_key *p, bool fullpath, bool novals) { struct registry_key *subkey; - const char *valuename; - const char *keyname; - uint32_t value_type; - DATA_BLOB value_data; + const char *valuename, *keyname; + uint32_t valuetype; + DATA_BLOB valuedata; struct security_descriptor *sec_desc; WERROR error; int i; @@ -73,18 +72,14 @@ static void print_tree(int level, struct registry_key *p, if (!novals) { mem_ctx = talloc_init("print_tree"); - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, - p, - i, - &valuename, - &value_type, - &value_data)); i++) { + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index( + mem_ctx, p, i, &valuename, &valuetype, &valuedata)); + i++) { int j; - char *desc; for(j = 0; j < level+1; j++) putchar(' '); - desc = reg_val_description(mem_ctx, lp_iconv_convenience(cmdline_lp_ctx), valuename, - value_type, value_data); - printf("%s\n", desc); + printf("%s\n", reg_val_description(mem_ctx, + lp_iconv_convenience(cmdline_lp_ctx), valuename, + valuetype, valuedata)); } talloc_free(mem_ctx); diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 68efd56a86..b3b6e49ea5 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -140,8 +140,7 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, break; case REG_BINARY: - *data = strhex_to_data_blob(data_str); - talloc_steal(mem_ctx, data->data); + *data = strhex_to_data_blob(mem_ctx, data_str); break; default: |