#include "reg_dispatcher.h"
#include "reg_objects.h"
#include "../librpc/gen_ndr/ndr_security.h"
+#include "reg_parse_internal.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
if (fetch_reg_values(key->key, key->values) == -1) {
TALLOC_FREE(key->values);
- return WERR_BADFILE;
+ return WERR_FILE_NOT_FOUND;
}
return WERR_OK;
if (fetch_reg_keys(key->key, key->subkeys) == -1) {
TALLOC_FREE(key->subkeys);
- return WERR_NO_MORE_ITEMS;
+ return WERR_FILE_NOT_FOUND;
}
return WERR_OK;
struct registry_key *parent,
const char *name,
const struct security_token *token,
- uint32 access_desired,
+ uint32_t access_desired,
struct registry_key **pregkey)
{
WERROR result = WERR_OK;
struct registry_key *regkey;
struct registry_key_handle *key;
- struct regsubkey_ctr *subkeys = NULL;
DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
!(regkey->token = dup_nt_token(regkey, token)) ||
!(regkey->key = talloc_zero(regkey, struct registry_key_handle)))
{
- result = WERR_NOMEM;
+ result = WERR_NOT_ENOUGH_MEMORY;
goto done;
}
* Open a copy of the parent key
*/
if (!parent) {
- result = WERR_BADFILE;
+ result = WERR_FILE_NOT_FOUND;
goto done;
}
key->name = talloc_strdup(key, parent->key->name);
}
if (key->name == NULL) {
- result = WERR_NOMEM;
+ result = WERR_NOT_ENOUGH_MEMORY;
goto done;
}
if (key->ops == NULL) {
DEBUG(0,("reg_open_onelevel: Failed to assign "
"registry_ops to [%s]\n", key->name ));
- result = WERR_BADFILE;
+ result = WERR_FILE_NOT_FOUND;
goto done;
}
- /* check if the path really exists; failed is indicated by -1 */
- /* if the subkey count failed, bail out */
+ /* FIXME: Existence is currently checked by fetching the subkeys */
- result = regsubkey_ctr_init(key, &subkeys);
+ result = fill_subkey_cache(regkey);
if (!W_ERROR_IS_OK(result)) {
goto done;
}
- if ( fetch_reg_keys( key, subkeys ) == -1 ) {
- result = WERR_BADFILE;
- goto done;
- }
-
- TALLOC_FREE( subkeys );
-
if ( !regkey_access_check( key, access_desired, &key->access_granted,
token ) ) {
result = WERR_ACCESS_DENIED;
}
WERROR reg_openhive(TALLOC_CTX *mem_ctx, const char *hive,
- uint32 desired_access,
+ uint32_t desired_access,
const struct security_token *token,
struct registry_key **pkey)
{
+ const struct hive_info *hi;
SMB_ASSERT(hive != NULL);
- SMB_ASSERT(hive[0] != '\0');
SMB_ASSERT(strchr(hive, '\\') == NULL);
- return regkey_open_onelevel(mem_ctx, NULL, hive, token, desired_access,
- pkey);
+ hi = hive_info(hive);
+ if (hi == NULL) {
+ return WERR_FILE_NOT_FOUND;
+ }
+
+ return regkey_open_onelevel(mem_ctx, NULL, hi->short_name, token,
+ desired_access, pkey);
}
**********************************************************************/
WERROR reg_openkey(TALLOC_CTX *mem_ctx, struct registry_key *parent,
- const char *name, uint32 desired_access,
+ const char *name, uint32_t desired_access,
struct registry_key **pkey)
{
struct registry_key *direct_parent = parent;
path = talloc_strdup(frame, name);
if (path == NULL) {
- err = WERR_NOMEM;
+ err = WERR_NOT_ENOUGH_MEMORY;
goto error;
}
name_component = talloc_strndup(frame, path, (p - path));
if (name_component == NULL) {
- err = WERR_NOMEM;
+ err = WERR_NOT_ENOUGH_MEMORY;
goto error;
}
}
WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
- uint32 idx, char **name, NTTIME *last_write_time)
+ uint32_t idx, char **name, NTTIME *last_write_time)
{
WERROR err;
return WERR_ACCESS_DENIED;
}
- if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) {
+ err = fill_subkey_cache(key);
+ if (!W_ERROR_IS_OK(err)) {
return err;
}
if (!(*name = talloc_strdup(mem_ctx,
regsubkey_ctr_specific_key(key->subkeys, idx))))
{
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
if (last_write_time) {
}
WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
- uint32 idx, char **pname, struct registry_value **pval)
+ uint32_t idx, char **pname, struct registry_value **pval)
{
struct registry_value *val;
struct regval_blob *blob;
return WERR_ACCESS_DENIED;
}
- if (!(W_ERROR_IS_OK(err = fill_value_cache(key)))) {
+ err = fill_value_cache(key);
+ if (!(W_ERROR_IS_OK(err))) {
return err;
}
val = talloc_zero(mem_ctx, struct registry_value);
if (val == NULL) {
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
val->type = regval_type(blob);
&& !(*pname = talloc_strdup(
mem_ctx, regval_name(blob)))) {
TALLOC_FREE(val);
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
*pval = val;
static WERROR reg_enumvalue_nocachefill(TALLOC_CTX *mem_ctx,
struct registry_key *key,
- uint32 idx, char **pname,
+ uint32_t idx, char **pname,
struct registry_value **pval)
{
struct registry_value *val;
val = talloc_zero(mem_ctx, struct registry_value);
if (val == NULL) {
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
val->type = regval_type(blob);
&& !(*pname = talloc_strdup(
mem_ctx, regval_name(blob)))) {
TALLOC_FREE(val);
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
*pval = val;
const char *name, struct registry_value **pval)
{
WERROR err;
- uint32 i;
+ uint32_t i;
if (!(key->key->access_granted & KEY_QUERY_VALUE)) {
return WERR_ACCESS_DENIED;
}
}
- return WERR_BADFILE;
+ return WERR_FILE_NOT_FOUND;
}
WERROR reg_querymultiplevalues(TALLOC_CTX *mem_ctx,
vals = talloc_zero_array(mem_ctx, struct registry_value, num_names);
if (vals == NULL) {
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
for (n=0; n < num_names; n++) {
uint32_t *max_valbufsize, uint32_t *secdescsize,
NTTIME *last_changed_time)
{
- uint32 i, max_size;
+ uint32_t i, max_size;
size_t max_len;
TALLOC_CTX *mem_ctx;
WERROR err;
if (!W_ERROR_IS_OK(fill_subkey_cache(key)) ||
!W_ERROR_IS_OK(fill_value_cache(key))) {
- return WERR_BADFILE;
+ return WERR_FILE_NOT_FOUND;
}
max_len = 0;
*max_valbufsize = max_size;
if (!(mem_ctx = talloc_new(key))) {
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
err = regkey_get_secdesc(mem_ctx, key->key, &secdesc);
}
WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
- const char *subkeypath, uint32 desired_access,
+ const char *subkeypath, uint32_t 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;
+ uint32_t access_granted;
mem_ctx = talloc_new(ctx);
if (mem_ctx == NULL) {
- return WERR_NOMEM;
+ return WERR_NOT_ENOUGH_MEMORY;
}
path = talloc_strdup(mem_ctx, subkeypath);
if (path == NULL) {
- err = WERR_NOMEM;
+ err = WERR_NOT_ENOUGH_MEMORY;
goto done;
}
goto trans_done;
}
- if (!W_ERROR_EQUAL(err, WERR_BADFILE)) {
+ if (!W_ERROR_EQUAL(err, WERR_FILE_NOT_FOUND)) {
/*
* Something but "notfound" has happened, so bail out
*/
}
/*
- * We have to make a copy of the current key, as we opened it only
- * with ENUM_SUBKEY access.
+ * We may (e.g. in the iteration) have opened the key with ENUM_SUBKEY.
+ * Instead of re-opening the key with CREATE_SUB_KEY, we simply
+ * duplicate the access check here and skip the expensive full open.
*/
-
- err = reg_openkey(mem_ctx, key, "", KEY_CREATE_SUB_KEY,
- &create_parent);
- if (!W_ERROR_IS_OK(err)) {
+ if (!regkey_access_check(key->key, KEY_CREATE_SUB_KEY, &access_granted,
+ key->token))
+ {
+ err = WERR_ACCESS_DENIED;
goto trans_done;
}
* Actually create the subkey
*/
- err = fill_subkey_cache(create_parent);
- if (!W_ERROR_IS_OK(err)) {
- goto trans_done;
- }
-
err = create_reg_subkey(key->key, path);
if (!W_ERROR_IS_OK(err)) {
goto trans_done;
* Now open the newly created key
*/
- err = reg_openkey(ctx, create_parent, path, desired_access, pkey);
+ err = reg_openkey(ctx, key, path, desired_access, pkey);
if (W_ERROR_IS_OK(err) && (paction != NULL)) {
*paction = REG_CREATED_NEW_KEY;
}
struct registry_key *key;
name = talloc_strdup(mem_ctx, path);
if (name == NULL) {
- err = WERR_NOMEM;
+ err = WERR_NOT_ENOUGH_MEMORY;
goto done;
}
}
if (name[0] == '\0') {
- err = WERR_INVALID_PARAM;
+ err = WERR_INVALID_PARAMETER;
goto done;
}
if (res == 0) {
TALLOC_FREE(key->values);
- err = WERR_NOMEM;
+ err = WERR_NOT_ENOUGH_MEMORY;
goto done;
}
blob = regval_ctr_getvalue(key->values, name);
if (blob == NULL) {
- return WERR_BADFILE;
+ return WERR_FILE_NOT_FOUND;
} else {
return WERR_OK;
}
WERROR reg_getversion(uint32_t *version)
{
if (version == NULL) {
- return WERR_INVALID_PARAM;
+ return WERR_INVALID_PARAMETER;
}
*version = 0x00000005; /* Windows 2000 registry API version */
WERROR werr = WERR_OK;
struct registry_key *key;
char *subkey_name = NULL;
- uint32 i;
+ uint32_t i;
TALLOC_CTX *mem_ctx = talloc_stackframe();
DEBUG(5, ("reg_deletekey_recursive_internal: deleting '%s' from '%s'\n",
if (!W_ERROR_IS_OK(werr)) {
WERROR werr2;
-
- DEBUG(1, (__location__ " failed to delete key '%s' from key "
- "'%s': %s\n", path, parent->key->name,
- win_errstr(werr)));
+ DEBUG(W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND) ? 5 : 1,
+ (__location__ ": failed to delete key '%s' from key "
+ "'%s': %s\n", path, parent->key->name,
+ win_errstr(werr)));
werr2 = regdb_transaction_cancel();
if (!W_ERROR_IS_OK(werr2)) {
"error committing transaction: %s\n",
win_errstr(werr)));
} else {
- DEBUG(5, ("reg_reletekey_recursive_trans: deleted key '%s' from '%s'\n",
+ DEBUG(5, ("reg_deletekey_recursive_trans: deleted key '%s' from '%s'\n",
path, parent->key->name));
}