diff options
author | Volker Lendecke <vlendec@samba.org> | 2006-12-01 20:01:09 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:16:18 -0500 |
commit | ecf90c495eb850cd6f376fb4e090640b69f0c029 (patch) | |
tree | f3f30d71daab2abb56f50bac558fb9a43f28d6f1 | |
parent | e57de5730cd65bca08ea2dabcf2d74d52825285e (diff) | |
download | samba-ecf90c495eb850cd6f376fb4e090640b69f0c029.tar.gz samba-ecf90c495eb850cd6f376fb4e090640b69f0c029.tar.bz2 samba-ecf90c495eb850cd6f376fb4e090640b69f0c029.zip |
r19991: Sorry for this 2000-liner...
The main thing here is a rewrite of srv_winreg_nt.c. The core functionality
has moved to registry/reg_api.c which is then usable by the rest of Samba as
well.
On that way it fixes creating keys with more than one element in the
path. This did not work before.
Two things that sneaked in (sorry :-) is the change of some routines from
NTSTATUS to WERROR the removed "parent" argument to regkey_open_internal.
Volker
(This used to be commit fea52801de8c7b85c578d200c599475680c5339f)
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 2 | ||||
-rw-r--r-- | source3/include/reg_objects.h | 8 | ||||
-rw-r--r-- | source3/lib/util_reg.c | 60 | ||||
-rw-r--r-- | source3/registry/reg_api.c | 511 | ||||
-rw-r--r-- | source3/registry/reg_frontend.c | 63 | ||||
-rw-r--r-- | source3/rpc_server/srv_eventlog_nt.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_winreg_nt.c | 703 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 7 | ||||
-rw-r--r-- | source3/services/services_db.c | 16 | ||||
-rw-r--r-- | source3/smbd/service.c | 11 | ||||
-rw-r--r-- | source3/utils/net_rpc_printer.c | 7 | ||||
-rw-r--r-- | source3/utils/net_rpc_registry.c | 25 |
13 files changed, 768 insertions, 649 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 2d80efaa1a..369461c914 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -322,7 +322,7 @@ REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \ registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o \ - registry/reg_smbconf.o + registry/reg_smbconf.o registry/reg_api.o RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 357ca5f626..e066ba279c 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1970,7 +1970,7 @@ BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_me Duplicate a SID token. ****************************************************************************/ -NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken) +NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken) { NT_USER_TOKEN *token; diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index e3226b7ae9..b108d6d082 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -146,5 +146,11 @@ typedef struct _RegistryKey { REGISTRY_HOOK *hook; } REGISTRY_KEY; -#endif /* _REG_OBJECTS_H */ +struct registry_key { + REGISTRY_KEY *key; + REGSUBKEY_CTR *subkeys; + REGVAL_CTR *values; + struct nt_user_token *token; +}; +#endif /* _REG_OBJECTS_H */ diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c index 7d6dbe6d00..9f9cd40331 100644 --- a/source3/lib/util_reg.c +++ b/source3/lib/util_reg.c @@ -68,8 +68,8 @@ const char *reg_type_lookup(enum winreg_Type type) return result; } -NTSTATUS reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, - uint32 *num_values, char ***values) +WERROR reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, + uint32 *num_values, char ***values) { const smb_ucs2_t *p = (const smb_ucs2_t *)buf; *num_values = 0; @@ -79,7 +79,7 @@ NTSTATUS reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, */ if (!(*values = TALLOC_ARRAY(mem_ctx, char *, 1))) { - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } len /= 2; /* buf is a set of UCS2 strings */ @@ -94,31 +94,31 @@ NTSTATUS reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, True); if (dstlen == (size_t)-1) { TALLOC_FREE(*values); - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } ADD_TO_ARRAY(*values, char *, val, values, num_values); if (*values == NULL) { - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } p += thislen; len -= thislen; } - return NT_STATUS_OK; + return WERR_OK; } -NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx, - struct registry_value **pvalue, - enum winreg_Type type, uint8 *data, - uint32 size, uint32 length) +WERROR 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; + WERROR err; if (!(value = TALLOC_ZERO_P(mem_ctx, struct registry_value))) { - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } value->type = type; @@ -126,7 +126,7 @@ NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx, switch (type) { case REG_DWORD: if ((size != 4) || (length != 4)) { - status = NT_STATUS_INVALID_PARAMETER; + err = WERR_INVALID_PARAM; goto error; } value->v.dword = IVAL(data, 0); @@ -143,12 +143,12 @@ NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx, uint32 num_ucs2 = length / 2; if ((length % 2) != 0) { - status = NT_STATUS_INVALID_PARAMETER; + err = WERR_INVALID_PARAM; goto error; } if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, num_ucs2+1))) { - status = NT_STATUS_NO_MEMORY; + err = WERR_NOMEM; goto error; } @@ -162,16 +162,16 @@ NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx, SAFE_FREE(tmp); if (value->v.sz.len == (size_t)-1) { - status = NT_STATUS_INVALID_PARAMETER; + err = WERR_INVALID_PARAM; 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))) { + err = reg_pull_multi_sz(value, (void *)data, length, + &value->v.multi_sz.num_strings, + &value->v.multi_sz.strings); + if (!(W_ERROR_IS_OK(err))) { goto error; } break; @@ -180,21 +180,21 @@ NTSTATUS registry_pull_value(TALLOC_CTX *mem_ctx, value->v.binary.length = length; break; default: - status = NT_STATUS_INVALID_PARAMETER; + err = WERR_INVALID_PARAM; goto error; } *pvalue = value; - return NT_STATUS_OK; + return WERR_OK; error: TALLOC_FREE(value); - return status; + return err; } -NTSTATUS registry_push_value(TALLOC_CTX *mem_ctx, - const struct registry_value *value, - DATA_BLOB *presult) +WERROR registry_push_value(TALLOC_CTX *mem_ctx, + const struct registry_value *value, + DATA_BLOB *presult) { switch (value->type) { case REG_DWORD: { @@ -202,7 +202,7 @@ NTSTATUS registry_push_value(TALLOC_CTX *mem_ctx, SIVAL(buf, 0, value->v.dword); *presult = data_blob_talloc(mem_ctx, (void *)buf, 4); if (presult->data == NULL) { - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } break; } @@ -213,13 +213,13 @@ NTSTATUS registry_push_value(TALLOC_CTX *mem_ctx, 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; + return WERR_NOMEM; } break; } default: - return NT_STATUS_INVALID_PARAMETER; + return WERR_INVALID_PARAM; } - return NT_STATUS_OK; + return WERR_OK; } diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c new file mode 100644 index 0000000000..672e69c6c7 --- /dev/null +++ b/source3/registry/reg_api.c @@ -0,0 +1,511 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Volker Lendecke 2006 + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Attempt to wrap the existing API in a more winreg.idl-like way */ + +#include "includes.h" + +static WERROR fill_value_cache(struct registry_key *key) +{ + if (key->values != NULL) { + return WERR_OK; + } + + if (!(key->values = TALLOC_ZERO_P(key, REGVAL_CTR))) { + return WERR_NOMEM; + } + if (fetch_reg_values(key->key, key->values) == -1) { + TALLOC_FREE(key->values); + return WERR_BADFILE; + } + + return WERR_OK; +} + +static WERROR fill_subkey_cache(struct registry_key *key) +{ + if (key->subkeys != NULL) { + return WERR_OK; + } + + if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) { + return WERR_NOMEM; + } + + if (fetch_reg_keys(key->key, key->subkeys) == -1) { + TALLOC_FREE(key->subkeys); + return WERR_NO_MORE_ITEMS; + } + + return WERR_OK; +} + +WERROR reg_openhive(TALLOC_CTX *mem_ctx, const char *hive, + uint32 desired_access, + const struct nt_user_token *token, + struct registry_key **pkey) +{ + struct registry_key *key; + WERROR err; + + SMB_ASSERT(hive[0] != '\0'); + SMB_ASSERT(strchr(hive, '\\') == NULL); + + if (!(key = TALLOC_ZERO_P(mem_ctx, struct registry_key))) { + return WERR_NOMEM; + } + + if (!(key->token = dup_nt_token(key, token))) { + TALLOC_FREE(key); + return WERR_NOMEM; + } + + err = regkey_open_internal(key, &key->key, hive, token, + desired_access); + + if (!W_ERROR_IS_OK(err)) { + TALLOC_FREE(key); + return err; + } + + *pkey = key; + return WERR_OK; + +} + +WERROR reg_openkey(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, uint32 desired_access, + struct registry_key **pkey) +{ + struct registry_key *key; + WERROR err; + char *path; + + if (!(key = TALLOC_ZERO_P(mem_ctx, struct registry_key))) { + return WERR_NOMEM; + } + + if (!(key->token = dup_nt_token(key, parent->token))) { + TALLOC_FREE(key); + return WERR_NOMEM; + } + + if (name[0] == '\0') { + /* + * Make a copy of the parent + */ + path = talloc_strdup(key, parent->key->name); + } + else { + /* + * Normal subpath open + */ + path = talloc_asprintf(key, "%s\\%s", parent->key->name, + name); + } + + if (!path) { + TALLOC_FREE(key); + return WERR_NOMEM; + } + + err = regkey_open_internal(key, &key->key, path, parent->token, + desired_access); + TALLOC_FREE(path); + + if (!W_ERROR_IS_OK(err)) { + TALLOC_FREE(key); + return err; + } + + *pkey = key; + return WERR_OK; +} + +WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key, + uint32 idx, char **name, NTTIME *last_write_time) +{ + WERROR err; + + if (!(key->key->access_granted & SEC_RIGHTS_ENUM_SUBKEYS)) { + return WERR_ACCESS_DENIED; + } + + if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) { + return err; + } + + if (idx >= key->subkeys->num_subkeys) { + return WERR_NO_MORE_ITEMS; + } + + if (!(*name = talloc_strdup(mem_ctx, key->subkeys->subkeys[idx]))) { + return WERR_NOMEM; + } + + if (last_write_time) { + *last_write_time = 0; + } + + return WERR_OK; +} + +WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key, + uint32 idx, const char **pname, + struct registry_value **pval) +{ + struct registry_value *val; + WERROR err; + + if (!(key->key->access_granted & SEC_RIGHTS_QUERY_VALUE)) { + return WERR_ACCESS_DENIED; + } + + if (!(W_ERROR_IS_OK(err = fill_value_cache(key)))) { + return err; + } + + if (idx >= key->values->num_values) { + return WERR_BADFILE; + } + + err = registry_pull_value(mem_ctx, &val, + key->values->values[idx]->type, + key->values->values[idx]->data_p, + key->values->values[idx]->size, + key->values->values[idx]->size); + if (!W_ERROR_IS_OK(err)) { + return err; + } + + if (pname + && !(*pname = talloc_strdup( + mem_ctx, key->values->values[idx]->valuename))) { + SAFE_FREE(val); + return WERR_NOMEM; + } + + *pval = val; + return WERR_OK; +} + +WERROR reg_queryvalue(TALLOC_CTX *mem_ctx, struct registry_key *key, + const char *name, struct registry_value **pval) +{ + WERROR err; + uint32 i; + + if (!(key->key->access_granted & SEC_RIGHTS_QUERY_VALUE)) { + return WERR_ACCESS_DENIED; + } + + if (!(W_ERROR_IS_OK(err = fill_value_cache(key)))) { + return err; + } + + for (i=0; i<key->values->num_values; i++) { + if (strequal(key->values->values[i]->valuename, name)) { + return reg_enumvalue(mem_ctx, key, i, NULL, pval); + } + } + + return WERR_BADFILE; +} + +WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys, + uint32_t *max_subkeylen, uint32_t *max_subkeysize, + uint32_t *num_values, uint32_t *max_valnamelen, + uint32_t *max_valbufsize, uint32_t *secdescsize, + NTTIME *last_changed_time) +{ + uint32 i, max_size; + size_t max_len; + TALLOC_CTX *mem_ctx; + WERROR err; + struct security_descriptor *secdesc; + + if (!(key->key->access_granted & SEC_RIGHTS_QUERY_VALUE)) { + return WERR_ACCESS_DENIED; + } + + if (!W_ERROR_IS_OK(fill_subkey_cache(key)) || + !W_ERROR_IS_OK(fill_value_cache(key))) { + return WERR_BADFILE; + } + + max_len = 0; + for (i=0; i<key->subkeys->num_subkeys; i++) { + max_len = MAX(max_len, strlen(key->subkeys->subkeys[i])); + } + + *num_subkeys = key->subkeys->num_subkeys; + *max_subkeylen = max_len; + *max_subkeysize = 0; /* Class length? */ + + max_len = 0; + max_size = 0; + for (i=0; i<key->values->num_values; i++) { + max_len = MAX(max_len, + strlen(key->values->values[i]->valuename)); + max_size = MAX(max_size, key->values->values[i]->size); + } + + *num_values = key->values->num_values; + *max_valnamelen = max_len; + *max_valbufsize = max_size; + + if (!(mem_ctx = talloc_new(key))) { + return WERR_NOMEM; + } + + err = regkey_get_secdesc(mem_ctx, key->key, &secdesc); + if (!W_ERROR_IS_OK(err)) { + TALLOC_FREE(mem_ctx); + return err; + } + + *secdescsize = sec_desc_size(secdesc); + TALLOC_FREE(mem_ctx); + + *last_changed_time = 0; + + return WERR_OK; +} + +WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, + const char *subkeypath, uint32 desired_access, + struct registry_key **pkey, + enum winreg_CreateAction *paction) +{ + struct registry_key *key = parent; + struct registry_key *create_parent; + TALLOC_CTX *mem_ctx; + char *path, *end; + WERROR err; + REGSUBKEY_CTR *subkeys; + + if (!(mem_ctx = talloc_new(ctx))) return WERR_NOMEM; + + if (!(path = talloc_strdup(mem_ctx, subkeypath))) { + err = WERR_NOMEM; + goto done; + } + + while ((end = strchr(path, '\\')) != NULL) { + struct registry_key *tmp; + enum winreg_CreateAction action; + + *end = '\0'; + + err = reg_createkey(mem_ctx, key, path, + SEC_RIGHTS_ENUM_SUBKEYS, &tmp, &action); + if (!W_ERROR_IS_OK(err)) { + goto done; + } + + if (key != parent) { + TALLOC_FREE(key); + } + + key = tmp; + path = end+1; + } + + /* + * At this point, "path" contains the one-element subkey of "key". We + * can try to open it. + */ + + err = reg_openkey(ctx, key, path, desired_access, pkey); + if (W_ERROR_IS_OK(err)) { + *paction = REG_OPENED_EXISTING_KEY; + return WERR_OK; + } + + if (!W_ERROR_EQUAL(err, WERR_BADFILE)) { + /* + * Something but "notfound" has happened, so bail out + */ + goto done; + } + + /* + * We have to make a copy of the current key, as we opened it only + * with ENUM_SUBKEY access. + */ + + err = reg_openkey(mem_ctx, key, "", SEC_RIGHTS_CREATE_SUBKEY, + &create_parent); + if (!W_ERROR_IS_OK(err)) { + goto done; + } + + /* + * Actually create the subkey + */ + + if (!(subkeys = TALLOC_ZERO_P(mem_ctx, REGSUBKEY_CTR))) { + err = WERR_NOMEM; + goto done; + } + + err = fill_subkey_cache(create_parent); + if (!W_ERROR_IS_OK(err)) goto done; + + err = regsubkey_ctr_addkey(create_parent->subkeys, path); + if (!W_ERROR_IS_OK(err)) goto done; + + if (!store_reg_keys(create_parent->key, create_parent->subkeys)) { + TALLOC_FREE(create_parent->subkeys); + err = WERR_REG_IO_FAILURE; + goto done; + } + + /* + * Now open the newly created key + */ + + err = reg_openkey(ctx, create_parent, path, desired_access, pkey); + if (W_ERROR_IS_OK(err) && (paction != NULL)) { + *paction = REG_CREATED_NEW_KEY; + } + + done: + TALLOC_FREE(mem_ctx); + return err; +} + + +WERROR reg_deletekey(struct registry_key *parent, const char *path) +{ + WERROR err; + TALLOC_CTX *mem_ctx; + char *name, *end; + int num_subkeys; + + if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM; + + if (!(name = talloc_strdup(mem_ctx, path))) { + err = WERR_NOMEM; + goto error; + } + + if ((end = strrchr(name, '\\')) != NULL) { + struct registry_key *tmp; + + *end = '\0'; + + err = reg_openkey(mem_ctx, parent, name, + SEC_RIGHTS_CREATE_SUBKEY, &tmp); + if (!W_ERROR_IS_OK(err)) { + goto error; + } + + parent = tmp; + name = end+1; + } + + if (name[0] == '\0') { + err = WERR_INVALID_PARAM; + goto error; + } + + if (!W_ERROR_IS_OK(err = fill_subkey_cache(parent))) { + goto error; + } + + num_subkeys = parent->subkeys->num_subkeys; + + if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) { + err = WERR_BADFILE; + goto error; + } + + if (!store_reg_keys(parent->key, parent->subkeys)) { + TALLOC_FREE(parent->subkeys); + err = WERR_REG_IO_FAILURE; + goto error; + } + + err = WERR_OK; + error: + TALLOC_FREE(mem_ctx); + return err; +} + +WERROR reg_setvalue(struct registry_key *key, const char *name, + const struct registry_value *val) +{ + WERROR err; + DATA_BLOB value_data; + int res; + + if (!(key->key->access_granted & SEC_RIGHTS_SET_VALUE)) { + return WERR_ACCESS_DENIED; + } + + if (!W_ERROR_IS_OK(err = fill_value_cache(key))) { + return err; + } + + err = registry_push_value(key, val, &value_data); + if (!W_ERROR_IS_OK(err)) { + return err; + } + + res = regval_ctr_addvalue(key->values, name, val->type, + (char *)value_data.data, value_data.length); + TALLOC_FREE(value_data.data); + + if (res == 0) { + TALLOC_FREE(key->values); + return WERR_NOMEM; + } + + if (!store_reg_values(key->key, key->values)) { + TALLOC_FREE(key->values); + return WERR_REG_IO_FAILURE; + } + + return WERR_OK; +} + +WERROR reg_deletevalue(struct registry_key *key, const char *name) +{ + WERROR err; + + if (!(key->key->access_granted & SEC_RIGHTS_SET_VALUE)) { + return WERR_ACCESS_DENIED; + } + + if (!W_ERROR_IS_OK(err = fill_value_cache(key))) { + return err; + } + + regval_ctr_delvalue(key->values, name); + + if (!store_reg_values(key->key, key->values)) { + TALLOC_FREE(key->values); + return WERR_REG_IO_FAILURE; + } + + return WERR_OK; +} + diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 79fbc8ef52..aefd2b6f51 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -189,9 +189,9 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) return result; } -NTSTATUS registry_fetch_values(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, - uint32 *pnum_values, char ***pnames, - struct registry_value ***pvalues) +WERROR registry_fetch_values(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, + uint32 *pnum_values, char ***pnames, + struct registry_value ***pvalues) { REGVAL_CTR *ctr; char **names; @@ -199,42 +199,42 @@ NTSTATUS registry_fetch_values(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, uint32 i; if (!(ctr = TALLOC_ZERO_P(mem_ctx, REGVAL_CTR))) { - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } if (fetch_reg_values(key, ctr) == -1) { TALLOC_FREE(ctr); - return NT_STATUS_INVALID_PARAMETER; + return WERR_INVALID_PARAM; } if (ctr->num_values == 0) { *pnum_values = 0; TALLOC_FREE(ctr); - return NT_STATUS_OK; + return WERR_OK; } if ((!(names = TALLOC_ARRAY(ctr, char *, ctr->num_values))) || (!(values = TALLOC_ARRAY(ctr, struct registry_value *, ctr->num_values)))) { TALLOC_FREE(ctr); - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } for (i=0; i<ctr->num_values; i++) { REGISTRY_VALUE *val = ctr->values[i]; - NTSTATUS status; + WERROR err; if (!(names[i] = talloc_strdup(names, val->valuename))) { TALLOC_FREE(ctr); - return NT_STATUS_NO_MEMORY; + return WERR_NOMEM; } - status = registry_pull_value(values, &values[i], - val->type, val->data_p, - val->size, val->size); - if (!NT_STATUS_IS_OK(status)) { + err = registry_pull_value(values, &values[i], + val->type, val->data_p, + val->size, val->size); + if (!W_ERROR_IS_OK(err)) { TALLOC_FREE(ctr); - return status; + return err; } } @@ -243,7 +243,7 @@ NTSTATUS registry_fetch_values(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, *pvalues = talloc_move(mem_ctx, &values); TALLOC_FREE(ctr); - return NT_STATUS_OK; + return WERR_OK; } /*********************************************************************** @@ -310,7 +310,7 @@ WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, REGISTRY_KEY *parent, REGISTRY_KEY *key; REGSUBKEY_CTR *subkeys = NULL; - DEBUG(7,("regkey_open_internal: name = [%s]\n", name)); + DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name)); if ((parent != NULL) && ((parent->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) == 0)) { @@ -365,7 +365,7 @@ WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, REGISTRY_KEY *parent, /* Look up the table of registry I/O operations */ if ( !(key->hook = reghook_cache_find( key->name )) ) { - DEBUG(0,("open_registry_key: Failed to assigned a " + DEBUG(0,("reg_open_onelevel: Failed to assigned a " "REGISTRY_HOOK to [%s]\n", key->name )); result = WERR_BADFILE; goto done; @@ -403,13 +403,14 @@ done: return result; } -WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY *parent, - REGISTRY_KEY **regkey, const char *name, - NT_USER_TOKEN *token, uint32 access_desired ) +WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey, + const char *path, + const struct nt_user_token *token, + uint32 access_desired ) { TALLOC_CTX *mem_ctx; const char *p; - BOOL free_parent = False; + REGISTRY_KEY *parent = NULL; WERROR err; size_t len; @@ -417,21 +418,20 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY *parent, return WERR_NOMEM; } - len = strlen(name); - if ((len > 0) && (name[len-1] == '\\')) { - if (!(name = talloc_strndup(mem_ctx, name, len-1))) { + len = strlen(path); + if ((len > 0) && (path[len-1] == '\\')) { + if (!(path = talloc_strndup(mem_ctx, path, len-1))) { TALLOC_FREE(mem_ctx); return WERR_NOMEM; } } - while ((p = strchr(name, '\\')) != NULL) { + while ((p = strchr(path, '\\')) != NULL) { char *name_component; REGISTRY_KEY *intermediate; - if (!(name_component = talloc_strndup( - mem_ctx, name, (p - name)))) { + mem_ctx, path, (p - path)))) { TALLOC_FREE(mem_ctx); return WERR_NOMEM; } @@ -446,15 +446,12 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY *parent, return WERR_NOMEM; } - if (free_parent) { - TALLOC_FREE(parent); - } + TALLOC_FREE(parent); parent = intermediate; - free_parent = True; - name = p+1; + path = p+1; } - err = regkey_open_onelevel(ctx, parent, regkey, name, token, + err = regkey_open_onelevel(ctx, parent, regkey, path, token, access_desired); TALLOC_FREE(mem_ctx); return err; diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 73dfd42184..6911bdcd3b 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -411,7 +411,7 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info ) pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname ); - wresult = regkey_open_internal( NULL, NULL, &keyinfo, path, + wresult = regkey_open_internal( NULL, &keyinfo, path, get_root_nt_token( ), REG_KEY_READ ); if ( !W_ERROR_IS_OK( wresult ) ) { diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 847bc967c5..4b394428c3 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -30,30 +30,24 @@ static struct generic_mapping reg_generic_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; -struct regkey_info { - REGISTRY_KEY *key; - REGVAL_CTR *value_cache; - REGSUBKEY_CTR *subkey_cache; -}; - /****************************************************************** free() function for struct regkey_info *****************************************************************/ -static void free_regkey_info(void *ptr) +static void free_regkey(void *ptr) { - struct regkey_info *info = (struct regkey_info *)ptr; - TALLOC_FREE(info); + struct registry_key *key = (struct registry_key *)ptr; + TALLOC_FREE(key); } /****************************************************************** Find a registry key handle and return a REGISTRY_KEY *****************************************************************/ -static struct regkey_info *find_regkey_info_by_hnd(pipes_struct *p, - POLICY_HND *hnd) +static struct registry_key *find_regkey_by_hnd(pipes_struct *p, + POLICY_HND *hnd) { - struct regkey_info *regkey = NULL; + struct registry_key *regkey = NULL; if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) { DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: ")); @@ -63,35 +57,6 @@ static struct regkey_info *find_regkey_info_by_hnd(pipes_struct *p, return regkey; } -static REGISTRY_KEY *find_regkey_by_hnd(pipes_struct *p, POLICY_HND *hnd) -{ - struct regkey_info *regkey = find_regkey_info_by_hnd(p, hnd); - - if (regkey == NULL) { - return NULL; - } - - return regkey->key; -} - -static WERROR fill_value_cache(struct regkey_info *info) -{ - if (info->value_cache != NULL) { - return WERR_OK; - } - - if (!(info->value_cache = TALLOC_ZERO_P(info, REGVAL_CTR))) { - return WERR_NOMEM; - } - - if (fetch_reg_values(info->key, info->value_cache) == -1) { - TALLOC_FREE(info->value_cache); - return WERR_BADFILE; - } - - return WERR_OK; -} - /******************************************************************* Function for open a new registry handle and creating a handle Note that P should be valid & hnd should already have space @@ -101,40 +66,31 @@ static WERROR fill_value_cache(struct regkey_info *info) *******************************************************************/ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, - struct regkey_info **pinfo, - REGISTRY_KEY *parent, + struct registry_key *parent, const char *subkeyname, uint32 access_desired ) { - WERROR result = WERR_OK; - struct regkey_info *info; + WERROR result = WERR_OK; + struct registry_key *key; - /* create a full registry path and strip any trailing '\' - characters */ + /* now do the internal open */ - if (!(info = TALLOC_ZERO_P(NULL, struct regkey_info))) { - return WERR_NOMEM; + if (parent == NULL) { + result = reg_openhive(NULL, subkeyname, access_desired, + p->pipe_user.nt_user_token, &key); + } + else { + result = reg_openkey(NULL, parent, subkeyname, access_desired, + &key); } - - /* now do the internal open */ - - result = regkey_open_internal( info, parent, &info->key, subkeyname, - p->pipe_user.nt_user_token, - access_desired ); if ( !W_ERROR_IS_OK(result) ) { - TALLOC_FREE(info); return result; } - if ( !create_policy_hnd( p, hnd, free_regkey_info, info ) ) { - TALLOC_FREE(info); + if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) { return WERR_BADFILE; } - - if (pinfo) { - *pinfo = info; - } return WERR_OK;; } @@ -146,10 +102,11 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd) { - REGISTRY_KEY *regkey = find_regkey_by_hnd(p, hnd); + struct registry_key *regkey = find_regkey_by_hnd(p, hnd); if ( !regkey ) { - DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); + DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", + OUR_HANDLE(hnd))); return False; } @@ -159,89 +116,6 @@ static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd) } /******************************************************************** - retrieve information about the subkeys - *******************************************************************/ - -static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen ) -{ - int num_subkeys, i; - uint32 max_len; - REGSUBKEY_CTR *subkeys; - uint32 len; - - if ( !key ) - return False; - - if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) - return False; - - if ( fetch_reg_keys( key, subkeys ) == -1 ) - return False; - - /* find the longest string */ - - max_len = 0; - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - - for ( i=0; i<num_subkeys; i++ ) { - len = strlen( regsubkey_ctr_specific_key(subkeys, i) ); - max_len = MAX(max_len, len); - } - - *maxnum = num_subkeys; - *maxlen = max_len*2; - - TALLOC_FREE( subkeys ); - - return True; -} - -/******************************************************************** - retrieve information about the values. - *******************************************************************/ - -static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum, - uint32 *maxlen, uint32 *maxsize ) -{ - REGVAL_CTR *values; - uint32 sizemax, lenmax; - int i, num_values; - - if ( !key ) - return False; - - if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) - return False; - - if ( fetch_reg_values( key, values ) == -1 ) - return False; - - lenmax = sizemax = 0; - num_values = regval_ctr_numvals( values ); - - for ( i=0; i<num_values; i++ ) { - REGISTRY_VALUE *val; - - if (!(val = regval_ctr_specific_value( values, i ))) { - break; - } - - lenmax = MAX(lenmax, val->valuename ? - strlen(val->valuename)+1 : 0 ); - sizemax = MAX(sizemax, val->size ); - } - - *maxnum = num_values; - *maxlen = lenmax*2; - *maxsize = sizemax; - - TALLOC_FREE( values ); - - return True; -} - - -/******************************************************************** reg_close ********************************************************************/ @@ -260,7 +134,7 @@ WERROR _winreg_CloseKey(pipes_struct *p, struct policy_handle *handle) WERROR _winreg_OpenHKLM(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKLM, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKLM, access_mask); } /******************************************************************* @@ -269,7 +143,7 @@ WERROR _winreg_OpenHKLM(pipes_struct *p, uint16_t *system_name, uint32_t access_ WERROR _winreg_OpenHKPD(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKPD, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKPD, access_mask); } /******************************************************************* @@ -278,7 +152,7 @@ WERROR _winreg_OpenHKPD(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKPT(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKPT, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKPT, access_mask); } /******************************************************************* @@ -287,7 +161,7 @@ WERROR _winreg_OpenHKPT(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKCR(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKCR, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKCR, access_mask); } /******************************************************************* @@ -296,7 +170,7 @@ WERROR _winreg_OpenHKCR(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKU(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKU, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKU, access_mask); } /******************************************************************* @@ -305,7 +179,7 @@ WERROR _winreg_OpenHKU(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKCU(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKCU, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKCU, access_mask); } /******************************************************************* @@ -314,7 +188,7 @@ WERROR _winreg_OpenHKCU(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKCC(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKCC, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKCC, access_mask); } /******************************************************************* @@ -323,7 +197,7 @@ WERROR _winreg_OpenHKCC(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKDD(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKDD, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKDD, access_mask); } /******************************************************************* @@ -332,46 +206,23 @@ WERROR _winreg_OpenHKDD(pipes_struct *p, uint16_t *system_name, WERROR _winreg_OpenHKPN(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle) { - return open_registry_key(p, handle, NULL, NULL, KEY_HKPN, access_mask); + return open_registry_key(p, handle, NULL, KEY_HKPN, access_mask); } /******************************************************************* reg_reply_open_entry ********************************************************************/ -WERROR _winreg_OpenKey(pipes_struct *p, struct policy_handle *parent_handle, struct winreg_String keyname, uint32_t unknown, uint32_t access_mask, struct policy_handle *handle) +WERROR _winreg_OpenKey(pipes_struct *p, struct policy_handle *parent_handle, + struct winreg_String keyname, uint32_t unknown, + uint32_t access_mask, struct policy_handle *handle) { - char *name; - REGISTRY_KEY *parent = find_regkey_by_hnd(p, parent_handle ); - uint32 check_rights; + struct registry_key *parent = find_regkey_by_hnd(p, parent_handle ); if ( !parent ) return WERR_BADFID; - if ( (name = talloc_strdup( p->mem_ctx, keyname.name )) == NULL ) { - return WERR_INVALID_PARAM; - } - - /* check granted access first; what is the correct mask here? */ - - check_rights = ( SEC_RIGHTS_ENUM_SUBKEYS| - SEC_RIGHTS_CREATE_SUBKEY| - SEC_RIGHTS_QUERY_VALUE| - SEC_RIGHTS_SET_VALUE); - - if ( !(parent->access_granted & check_rights) ) { - DEBUG(8,("Rights check failed, parent had %04x, check_rights %04x\n",parent->access_granted, check_rights)); - return WERR_ACCESS_DENIED; - } - - /* - * very crazy, but regedit.exe on Win2k will attempt to call - * REG_OPEN_ENTRY with a keyname of "". We should return a new - * (second) handle here on the key->name. regedt32.exe does - * not do this stupidity. --jerry - */ - - return open_registry_key( p, handle, NULL, parent, name, access_mask ); + return open_registry_key(p, handle, parent, keyname.name, access_mask); } /******************************************************************* @@ -384,28 +235,26 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle, uint32_t *data_size, uint32_t *value_length) { WERROR status = WERR_BADFILE; - struct regkey_info *info = find_regkey_info_by_hnd( p, handle ); - REGISTRY_KEY *regkey; + struct registry_key *regkey = find_regkey_by_hnd( p, handle ); prs_struct prs_hkpd; uint8_t *outbuf; uint32_t outbuf_size; + DATA_BLOB val_blob; BOOL free_buf = False; BOOL free_prs = False; - if ( !info ) + if ( !regkey ) return WERR_BADFID; - regkey = info->key; - *value_length = *type = 0; - DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name)); - DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->type)); + DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name)); + DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type)); /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */ - if(regkey->type == REG_KEY_HKPD) + if(regkey->key->type == REG_KEY_HKPD) { if(strequal(value_name.name, "Global")) { prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL); @@ -445,35 +294,27 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle, *type = REG_BINARY; } else { - REGISTRY_VALUE *val = NULL; - uint32 i; - - status = fill_value_cache(info); + struct registry_value *val; - if (!(W_ERROR_IS_OK(status))) { - return status; - } - - for (i=0; i<info->value_cache->num_values; i++) { - if (strequal(info->value_cache->values[i]->valuename, - value_name.name)) { - val = info->value_cache->values[i]; - break; - } - } - - if (val == NULL) { + status = reg_queryvalue(p->mem_ctx, regkey, value_name.name, + &val); + if (!W_ERROR_IS_OK(status)) { if (data_size) { *data_size = 0; } if (value_length) { *value_length = 0; } - return WERR_BADFILE; + return status; } - outbuf = val->data_p; - outbuf_size = val->size; + status = registry_push_value(p->mem_ctx, val, &val_blob); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + outbuf = val_blob.data; + outbuf_size = val_blob.length; *type = val->type; } @@ -509,30 +350,32 @@ WERROR _winreg_QueryInfoKey(pipes_struct *p, struct policy_handle *handle, uint32_t *secdescsize, NTTIME *last_changed_time) { WERROR status = WERR_OK; - REGISTRY_KEY *regkey = find_regkey_by_hnd( p, handle ); + struct registry_key *regkey = find_regkey_by_hnd( p, handle ); if ( !regkey ) - return WERR_BADFID; - - if ( !get_subkey_information( regkey, num_subkeys, max_subkeylen) ) { - DEBUG(0,("_winreg_QueryInfoKey: get_subkey_information() failed!\n")); - return WERR_ACCESS_DENIED; - } - - if ( !get_value_information( regkey, num_values, max_valnamelen, max_valbufsize) ) { - DEBUG(0,("_winreg_QueryInfoKey: get_value_information() failed!\n")); - return WERR_ACCESS_DENIED; + return WERR_BADFID; + + classname->name = NULL; + + status = reg_queryinfokey(regkey, num_subkeys, max_subkeylen, + max_subkeysize, num_values, max_valnamelen, + max_valbufsize, secdescsize, + last_changed_time); + if (!W_ERROR_IS_OK(status)) { + return status; } - *secdescsize = 0; /* used to be hard coded for 0x00000078 */ - *last_changed_time = 0; - *max_subkeysize = 0; /* maybe this is the classname length ? */ + /* + * These calculations account for the registry buffers being + * UTF-16. They are inexact at best, but so far they worked. + */ + + *max_subkeylen *= 2; - /* don't bother with class names for now */ - - classname->name = NULL; + *max_valnamelen += 1; + *max_valnamelen *= 2; - return status; + return WERR_OK; } @@ -542,7 +385,7 @@ WERROR _winreg_QueryInfoKey(pipes_struct *p, struct policy_handle *handle, WERROR _winreg_GetVersion(pipes_struct *p, struct policy_handle *handle, uint32_t *version) { - REGISTRY_KEY *regkey = find_regkey_by_hnd( p, handle ); + struct registry_key *regkey = find_regkey_by_hnd( p, handle ); if ( !regkey ) return WERR_BADFID; @@ -559,49 +402,24 @@ WERROR _winreg_GetVersion(pipes_struct *p, struct policy_handle *handle, uint32_ WERROR _winreg_EnumKey(pipes_struct *p, struct policy_handle *handle, uint32_t enum_index, struct winreg_StringBuf *name, struct winreg_StringBuf *keyclass, NTTIME *last_changed_time) { - WERROR status = WERR_OK; - struct regkey_info *info = find_regkey_info_by_hnd( p, handle ); - REGISTRY_KEY *regkey; + WERROR err; + struct registry_key *key = find_regkey_by_hnd( p, handle ); - if ( !info ) + if ( !key ) return WERR_BADFID; - regkey = info->key; - if ( !name || !keyclass ) return WERR_INVALID_PARAM; - DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name)); - - if (!info->subkey_cache) { - if (!(info->subkey_cache = TALLOC_ZERO_P( - info, REGSUBKEY_CTR))) { - return WERR_NOMEM; - } - - if (fetch_reg_keys(regkey, info->subkey_cache) == -1) { - TALLOC_FREE(info->subkey_cache); - return WERR_NO_MORE_ITEMS; - } - } - - if (enum_index >= info->subkey_cache->num_subkeys) { - return WERR_NO_MORE_ITEMS; - } + DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name)); - DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n", - info->subkey_cache->subkeys[enum_index])); - - if (!(name->name = talloc_strdup( - p->mem_ctx, info->subkey_cache->subkeys[enum_index]))) { - status = WERR_NOMEM; - } - if ( last_changed_time ) { - *last_changed_time = 0; + err = reg_enumkey(p->mem_ctx, key, enum_index, (char **)&name->name, + last_changed_time); + if (!W_ERROR_IS_OK(err)) { + return err; } keyclass->name = ""; - - return status; + return WERR_OK; } /***************************************************************************** @@ -613,35 +431,33 @@ WERROR _winreg_EnumValue(pipes_struct *p, struct policy_handle *handle, enum winreg_Type *type, uint8_t *data, uint32_t *data_size, uint32_t *value_length) { - WERROR status = WERR_OK; - struct regkey_info *info = find_regkey_info_by_hnd( p, handle ); - REGISTRY_KEY *regkey; - REGISTRY_VALUE *val = NULL; + WERROR err; + struct registry_key *key = find_regkey_by_hnd( p, handle ); + const char *valname; + struct registry_value *val; + DATA_BLOB value_blob; - if ( !info ) + if ( !key ) return WERR_BADFID; if ( !name ) return WERR_INVALID_PARAM; - regkey = info->key; - DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n", - regkey->name)); + key->key->name)); - status = fill_value_cache(info); - if (!W_ERROR_IS_OK(status)) { - return status; + err = reg_enumvalue(p->mem_ctx, key, enum_index, &valname, &val); + if (!W_ERROR_IS_OK(err)) { + return err; } - if (enum_index >= info->value_cache->num_values) { - return WERR_BADFILE; + err = registry_push_value(p->mem_ctx, val, &value_blob); + if (!W_ERROR_IS_OK(err)) { + return err; } - val = info->value_cache->values[enum_index]; - - if (!(name->name = talloc_strdup(p->mem_ctx, val->valuename))) { - return WERR_NOMEM; + if (name != NULL) { + name->name = valname; } if (type != NULL) { @@ -653,18 +469,18 @@ WERROR _winreg_EnumValue(pipes_struct *p, struct policy_handle *handle, return WERR_INVALID_PARAM; } - if (val->size > *data_size) { + if (value_blob.length > *data_size) { return WERR_MORE_DATA; } - memcpy( data, val->data_p, val->size ); + memcpy( data, value_blob.data, value_blob.length ); } if (value_length != NULL) { - *value_length = val->size; + *value_length = value_blob.length; } if (data_size != NULL) { - *data_size = val->size; + *data_size = value_blob.length; } return WERR_OK; @@ -951,7 +767,7 @@ static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) WERROR _winreg_RestoreKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, uint32_t flags) { - REGISTRY_KEY *regkey = find_regkey_by_hnd( p, handle ); + struct registry_key *regkey = find_regkey_by_hnd( p, handle ); pstring fname; int snum; @@ -963,7 +779,8 @@ WERROR _winreg_RestoreKey(pipes_struct *p, struct policy_handle *handle, struct pstrcpy( fname, filename->name ); - DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from \"%s\"\n", regkey->name, fname)); + DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from " + "\"%s\"\n", regkey->key->name, fname)); if ( (snum = validate_reg_filename( fname )) == -1 ) return WERR_OBJECT_PATH_INVALID; @@ -973,9 +790,10 @@ WERROR _winreg_RestoreKey(pipes_struct *p, struct policy_handle *handle, struct if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) ) return WERR_ACCESS_DENIED; - DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", regkey->name, fname, lp_servicename(snum) )); + DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", + regkey->key->name, fname, lp_servicename(snum) )); - return restore_registry_key( regkey, fname ); + return restore_registry_key( regkey->key, fname ); } /******************************************************************** @@ -1136,7 +954,7 @@ static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) WERROR _winreg_SaveKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, struct KeySecurityAttribute *sec_attrib) { - REGISTRY_KEY *regkey = find_regkey_by_hnd( p, handle ); + struct registry_key *regkey = find_regkey_by_hnd( p, handle ); pstring fname; int snum; @@ -1148,14 +966,16 @@ WERROR _winreg_SaveKey(pipes_struct *p, struct policy_handle *handle, struct win pstrcpy( fname, filename->name ); - DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n", regkey->name, fname)); + DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n", + regkey->key->name, fname)); if ( (snum = validate_reg_filename( fname )) == -1 ) return WERR_OBJECT_PATH_INVALID; - DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", regkey->name, fname, lp_servicename(snum) )); + DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", + regkey->key->name, fname, lp_servicename(snum) )); - return backup_registry_key( regkey, fname ); + return backup_registry_key( regkey->key, fname ); } /******************************************************************* @@ -1181,303 +1001,88 @@ WERROR _winreg_CreateKey( pipes_struct *p, struct policy_handle *handle, struct policy_handle *new_handle, enum winreg_CreateAction *action_taken ) { - struct regkey_info *parent = find_regkey_info_by_hnd(p, handle); - struct regkey_info *newparentinfo, *keyinfo; - POLICY_HND newparent_handle; - REGSUBKEY_CTR *subkeys; - BOOL write_result; - char *name; + struct registry_key *parent = find_regkey_by_hnd(p, handle); + struct registry_key *new_key; WERROR result; if ( !parent ) return WERR_BADFID; - if ( (name = talloc_strdup( p->mem_ctx, keyname.name )) == NULL ) { - return WERR_NOMEM; - } - - /* ok. Here's what we do. */ - - if ( strrchr( name, '\\' ) ) { - pstring newkeyname; - char *ptr; - - /* (1) check for enumerate rights on the parent handle. - Clients can try create things like 'SOFTWARE\Samba' on - the HKLM handle. (2) open the path to the child parent - key if necessary */ - - if ( !(parent->key->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) ) - return WERR_ACCESS_DENIED; - - pstrcpy( newkeyname, name ); - ptr = strrchr( newkeyname, '\\' ); - *ptr = '\0'; - - result = open_registry_key( p, &newparent_handle, - &newparentinfo, - parent->key, newkeyname, - (REG_KEY_READ|REG_KEY_WRITE) ); - - if ( !W_ERROR_IS_OK(result) ) - return result; - - /* copy the new key name (just the lower most keyname) */ - - if ( (name = talloc_strdup( p->mem_ctx, ptr+1 )) == NULL ) { - return WERR_NOMEM; - } - } - else { - /* use the existing open key information */ - newparentinfo = parent; - memcpy( &newparent_handle, handle, sizeof(POLICY_HND) ); - } - - /* (3) check for create subkey rights on the correct parent */ - - if ( !(newparentinfo->key->access_granted - & SEC_RIGHTS_CREATE_SUBKEY) ) { - result = WERR_ACCESS_DENIED; - goto done; - } - - if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { - result = WERR_NOMEM; - goto done; + result = reg_createkey(NULL, parent, keyname.name, access_mask, + &new_key, action_taken); + if (!W_ERROR_IS_OK(result)) { + return result; } - /* (4) lookup the current keys and add the new one */ - - fetch_reg_keys( newparentinfo->key, subkeys ); - regsubkey_ctr_addkey( subkeys, name ); - - /* now write to the registry backend */ - - write_result = store_reg_keys( newparentinfo->key, subkeys ); - - TALLOC_FREE( subkeys ); - TALLOC_FREE( newparentinfo->subkey_cache ); - - if ( !write_result ) - return WERR_REG_IO_FAILURE; - - /* (5) open the new key and return the handle. Note that it is probably - not correct to grant full access on this open handle. */ - - result = open_registry_key( p, new_handle, &keyinfo, - newparentinfo->key, name, REG_KEY_READ ); - keyinfo->key->access_granted = REG_KEY_ALL; - - /* FIXME: report the truth here */ - - if ( action_taken ) { - *action_taken = REG_CREATED_NEW_KEY; + if (!create_policy_hnd(p, new_handle, free_regkey, new_key)) { + TALLOC_FREE(new_key); + return WERR_BADFILE; } -done: - /* close any intermediate key handles */ - - if ( newparentinfo != parent ) - close_registry_key( p, &newparent_handle ); - - return result; + return WERR_OK; } - /******************************************************************* ********************************************************************/ -WERROR _winreg_SetValue(pipes_struct *p, struct policy_handle *handle, struct winreg_String name, enum winreg_Type type, uint8_t *data, uint32_t size) +WERROR _winreg_SetValue(pipes_struct *p, struct policy_handle *handle, + struct winreg_String name, enum winreg_Type type, + uint8_t *data, uint32_t size) { - struct regkey_info *info = find_regkey_info_by_hnd(p, handle); - REGISTRY_KEY *key; - REGVAL_CTR *values; - BOOL write_result; + struct registry_key *key = find_regkey_by_hnd(p, handle); + struct registry_value *val; + WERROR status; - if ( !info ) + if ( !key ) return WERR_BADFID; - key = info->key; - - /* access checks first */ - - if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) - return WERR_ACCESS_DENIED; - - DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->name, + DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->key->name, name.name)); - - if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) - return WERR_NOMEM; - - /* lookup the current values and add the new one */ - - fetch_reg_values( key, values ); - - regval_ctr_addvalue( values, name.name, type, - (const char *)data, size ); - - /* now write to the registry backend */ - - write_result = store_reg_values( key, values ); - - TALLOC_FREE( values ); - - if ( !write_result ) - return WERR_REG_IO_FAILURE; - TALLOC_FREE(info->value_cache); + status = registry_pull_value(p->mem_ctx, &val, type, data, size, size); + if (!W_ERROR_IS_OK(status)) { + return status; + } - return WERR_OK; + return reg_setvalue(key, name.name, val); } /******************************************************************* ********************************************************************/ -WERROR _winreg_DeleteKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String key) +WERROR _winreg_DeleteKey(pipes_struct *p, struct policy_handle *handle, + struct winreg_String key) { - struct regkey_info *parent = find_regkey_info_by_hnd(p, handle); - struct regkey_info *newparentinfo = NULL; - POLICY_HND newparent_handle; - REGSUBKEY_CTR *subkeys; - BOOL write_result; - char *name; - WERROR result; + struct registry_key *parent = find_regkey_by_hnd(p, handle); if ( !parent ) return WERR_BADFID; - /* MSDN says parent the handle must have been opened with DELETE access */ - - /* (1) check for delete rights on the parent */ - - if ( !(parent->key->access_granted & STD_RIGHT_DELETE_ACCESS) ) { - result = WERR_ACCESS_DENIED; - goto done; - } - - if ( (name = talloc_strdup( p->mem_ctx, key.name )) == NULL ) { - result = WERR_INVALID_PARAM; - goto done; - } - - /* ok. Here's what we do. */ - - if ( strrchr( name, '\\' ) ) { - pstring newkeyname; - char *ptr; - - /* (2) open the path to the child parent key if necessary */ - /* split the registry path and save the subkeyname */ - - pstrcpy( newkeyname, name ); - ptr = strrchr( newkeyname, '\\' ); - *ptr = '\0'; - if ( (name = talloc_strdup( p->mem_ctx, ptr+1 )) == NULL ) { - result = WERR_NOMEM; - goto done; - } - - result = open_registry_key( p, &newparent_handle, - &newparentinfo, parent->key, - newkeyname, - (REG_KEY_READ|REG_KEY_WRITE) ); - if ( !W_ERROR_IS_OK(result) ) { - goto done; - } - } - else { - /* use the existing open key information */ - newparentinfo = parent; - } - - if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { - result = WERR_NOMEM; - goto done; - } - - /* lookup the current keys and delete the new one */ - - fetch_reg_keys( newparentinfo->key, subkeys ); - - regsubkey_ctr_delkey( subkeys, name ); - - /* now write to the registry backend */ - - write_result = store_reg_keys( newparentinfo->key, subkeys ); - - TALLOC_FREE( subkeys ); - TALLOC_FREE( newparentinfo->subkey_cache ); - - result = write_result ? WERR_OK : WERR_REG_IO_FAILURE; - -done: - /* close any intermediate key handles */ - - if ( newparentinfo != parent ) - close_registry_key( p, &newparent_handle ); - - return result; + return reg_deletekey(parent, key.name); } /******************************************************************* ********************************************************************/ -WERROR _winreg_DeleteValue(pipes_struct *p, struct policy_handle *handle, struct winreg_String value) +WERROR _winreg_DeleteValue(pipes_struct *p, struct policy_handle *handle, + struct winreg_String value) { - struct regkey_info *info = find_regkey_info_by_hnd(p, handle); - REGISTRY_KEY *key; - REGVAL_CTR *values; - BOOL write_result; - char *valuename; + struct registry_key *key = find_regkey_by_hnd(p, handle); - if ( !info ) + if ( !key ) return WERR_BADFID; - key = info->key; - - /* access checks first */ - - if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) - return WERR_ACCESS_DENIED; - - if ( (valuename = talloc_strdup( p->mem_ctx, value.name )) == NULL ) { - return WERR_INVALID_PARAM; - } - - DEBUG(8,("_reg_delete_value: Setting value for [%s:%s]\n", key->name, valuename)); - - if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) - return WERR_NOMEM; - - /* lookup the current values and add the new one */ - - fetch_reg_values( key, values ); - - regval_ctr_delvalue( values, valuename ); - - /* now write to the registry backend */ - - write_result = store_reg_values( key, values ); - - TALLOC_FREE( values ); - - if ( !write_result ) - return WERR_REG_IO_FAILURE; - - TALLOC_FREE(info->value_cache); - - return WERR_OK; + return reg_deletevalue(key, value.name); } /******************************************************************* ********************************************************************/ -WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle, uint32_t sec_info, struct KeySecurityData *sd) +WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle, + uint32_t sec_info, struct KeySecurityData *sd) { - REGISTRY_KEY *key = find_regkey_by_hnd(p, handle); + struct registry_key *key = find_regkey_by_hnd(p, handle); WERROR err; struct security_descriptor *secdesc; uint8 *data; @@ -1488,10 +1093,10 @@ WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle, uin /* access checks first */ - if ( !(key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) + if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) return WERR_ACCESS_DENIED; - err = regkey_get_secdesc(p->mem_ctx, key, &secdesc); + err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc); if (!W_ERROR_IS_OK(err)) { return err; } @@ -1519,7 +1124,7 @@ WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle, uin WERROR _winreg_SetKeySecurity(pipes_struct *p, struct policy_handle *handle, uint32_t access_mask, struct KeySecurityData *sd) { - REGISTRY_KEY *key = find_regkey_by_hnd(p, handle); + struct registry_key *key = find_regkey_by_hnd(p, handle); struct security_descriptor *secdesc; WERROR err; @@ -1528,7 +1133,7 @@ WERROR _winreg_SetKeySecurity(pipes_struct *p, struct policy_handle *handle, uin /* access checks first */ - if ( !(key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) ) + if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) ) return WERR_ACCESS_DENIED; err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, sd->data, @@ -1537,7 +1142,7 @@ WERROR _winreg_SetKeySecurity(pipes_struct *p, struct policy_handle *handle, uin return err; } - return regkey_set_secdesc(key, secdesc); + return regkey_set_secdesc(key->key, secdesc); } /******************************************************************* diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 3257ec9215..fe16573248 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -712,10 +712,9 @@ static void display_reg_value(REGISTRY_VALUE value) uint32 i, num_values; char **values; - if (!NT_STATUS_IS_OK(reg_pull_multi_sz(NULL, value.data_p, - value.size, - &num_values, - &values))) { + if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, + value.size, &num_values, + &values))) { d_printf("reg_pull_multi_sz failed\n"); break; } diff --git a/source3/services/services_db.c b/source3/services/services_db.c index 40022ab365..c9e172da2a 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -322,7 +322,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* open the new service key */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( NULL, NULL, &key_service, path, + wresult = regkey_open_internal( NULL, &key_service, path, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", @@ -360,7 +360,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); - wresult = regkey_open_internal( NULL, NULL, &key_secdesc, path, + wresult = regkey_open_internal( NULL, &key_secdesc, path, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", @@ -412,7 +412,7 @@ void svcctl_init_keys( void ) /* bad mojo here if the lookup failed. Should not happen */ - wresult = regkey_open_internal( NULL, NULL, &key, KEY_SERVICES, + wresult = regkey_open_internal( NULL, &key, KEY_SERVICES, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { @@ -476,7 +476,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); - wresult = regkey_open_internal( NULL, NULL, &key, path, token, + wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", @@ -536,7 +536,7 @@ BOOL svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc, /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); - wresult = regkey_open_internal( NULL, NULL, &key, path, token, + wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", @@ -583,7 +583,7 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( NULL, NULL, &key, path, token, + wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", @@ -630,7 +630,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( NULL, NULL, &key, path, token, + wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", @@ -670,7 +670,7 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( NULL, NULL, &key, path, token, + wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", diff --git a/source3/smbd/service.c b/source3/smbd/service.c index e63bc01a7d..048c0f00b1 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -234,7 +234,6 @@ static int load_registry_service(const char *servicename) REGISTRY_KEY *key; char *path; WERROR err; - NTSTATUS status; uint32 i, num_values; char **value_names; @@ -250,7 +249,7 @@ static int load_registry_service(const char *servicename) return -1; } - err = regkey_open_internal(NULL, NULL, &key, path, get_root_nt_token(), + err = regkey_open_internal(NULL, &key, path, get_root_nt_token(), REG_KEY_READ); SAFE_FREE(path); @@ -258,12 +257,12 @@ static int load_registry_service(const char *servicename) return -1; } - status = registry_fetch_values(NULL, key, &num_values, &value_names, - &values); + err = registry_fetch_values(NULL, key, &num_values, &value_names, + &values); TALLOC_FREE(key); - if (!NT_STATUS_IS_OK(status)) { + if (!W_ERROR_IS_OK(err)) { goto error; } @@ -320,7 +319,7 @@ void load_registry_shares(void) goto done; } - err = regkey_open_internal(keys, NULL, &key, KEY_SMBCONF, + err = regkey_open_internal(keys, &key, KEY_SMBCONF, get_root_nt_token(), REG_KEY_READ); if (!(W_ERROR_IS_OK(err))) { goto done; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 5a18253aaf..d0b55454f9 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -132,10 +132,9 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value) uint32 i, num_values; char **values; - if (!NT_STATUS_IS_OK(reg_pull_multi_sz(NULL, value.data_p, - value.size, - &num_values, - &values))) { + if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, + value.size, &num_values, + &values))) { d_printf("reg_pull_multi_sz failed\n"); break; } diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index c684b04b8e..3634b0a4f2 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -266,6 +266,7 @@ static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx, char n; struct winreg_ValNameBuf name_buf; + WERROR err; n = '\0'; name_buf.name = &n; @@ -301,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; } } @@ -333,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; @@ -590,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"); |