werror: replace WERR_INVALID_PARAM with WERR_INVALID_PARAMETER in source3/registry/
[amitay/samba.git] / source3 / registry / reg_api.c
index ba5fb313c596a42639888b2b6a85c75614a88648..35d1c83141bf9a1b35f23ce267d2dc20ffde7bd7 100644 (file)
@@ -70,6 +70,7 @@
 #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
@@ -95,7 +96,7 @@ static WERROR fill_value_cache(struct registry_key *key)
 
        if (fetch_reg_values(key->key, key->values) == -1) {
                TALLOC_FREE(key->values);
-               return WERR_BADFILE;
+               return WERR_FILE_NOT_FOUND;
        }
 
        return WERR_OK;
@@ -117,7 +118,7 @@ static WERROR fill_subkey_cache(struct registry_key *key)
 
        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;
@@ -132,13 +133,12 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
                                   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));
 
@@ -148,7 +148,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
            !(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;
        }
 
@@ -169,7 +169,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
                 * 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);
@@ -185,7 +185,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
        }
 
        if (key->name == NULL) {
-               result = WERR_NOMEM;
+               result = WERR_NOT_ENOUGH_MEMORY;
                goto done;
        }
 
@@ -200,25 +200,17 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
        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;
@@ -237,16 +229,21 @@ done:
 }
 
 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);
 }
 
 
@@ -255,7 +252,7 @@ WERROR reg_openhive(TALLOC_CTX *mem_ctx, const char *hive,
  **********************************************************************/
 
 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;
@@ -266,7 +263,7 @@ WERROR reg_openkey(TALLOC_CTX *mem_ctx, struct registry_key *parent,
 
        path = talloc_strdup(frame, name);
        if (path == NULL) {
-               err = WERR_NOMEM;
+               err = WERR_NOT_ENOUGH_MEMORY;
                goto error;
        }
 
@@ -282,7 +279,7 @@ WERROR reg_openkey(TALLOC_CTX *mem_ctx, struct registry_key *parent,
 
                name_component = talloc_strndup(frame, path, (p - path));
                if (name_component == NULL) {
-                       err = WERR_NOMEM;
+                       err = WERR_NOT_ENOUGH_MEMORY;
                        goto error;
                }
 
@@ -307,7 +304,7 @@ 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;
 
@@ -315,7 +312,8 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
                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;
        }
 
@@ -326,7 +324,7 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
        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) {
@@ -337,7 +335,7 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
 }
 
 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;
@@ -347,7 +345,8 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
                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;
        }
 
@@ -359,7 +358,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
 
        val = talloc_zero(mem_ctx, struct registry_value);
        if (val == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        val->type = regval_type(blob);
@@ -369,7 +368,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
            && !(*pname = talloc_strdup(
                         mem_ctx, regval_name(blob)))) {
                TALLOC_FREE(val);
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        *pval = val;
@@ -378,7 +377,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
 
 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;
@@ -396,7 +395,7 @@ static WERROR reg_enumvalue_nocachefill(TALLOC_CTX *mem_ctx,
 
        val = talloc_zero(mem_ctx, struct registry_value);
        if (val == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        val->type = regval_type(blob);
@@ -406,7 +405,7 @@ static WERROR reg_enumvalue_nocachefill(TALLOC_CTX *mem_ctx,
            && !(*pname = talloc_strdup(
                         mem_ctx, regval_name(blob)))) {
                TALLOC_FREE(val);
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        *pval = val;
@@ -417,7 +416,7 @@ WERROR reg_queryvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
                      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;
@@ -442,7 +441,7 @@ WERROR reg_queryvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
                }
        }
 
-       return WERR_BADFILE;
+       return WERR_FILE_NOT_FOUND;
 }
 
 WERROR reg_querymultiplevalues(TALLOC_CTX *mem_ctx,
@@ -470,7 +469,7 @@ 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++) {
@@ -501,7 +500,7 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
                        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;
@@ -513,7 +512,7 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
 
        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;
@@ -540,7 +539,7 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
        *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);
@@ -558,24 +557,24 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
 }
 
 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;
        }
 
@@ -619,7 +618,7 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
                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
                 */
@@ -627,13 +626,14 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
        }
 
        /*
-        * 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;
        }
 
@@ -641,11 +641,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
         * 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;
@@ -655,7 +650,7 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
         * 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;
        }
@@ -687,7 +682,7 @@ static WERROR reg_deletekey_internal(TALLOC_CTX *mem_ctx,
        struct registry_key *key;
        name = talloc_strdup(mem_ctx, path);
        if (name == NULL) {
-               err = WERR_NOMEM;
+               err = WERR_NOT_ENOUGH_MEMORY;
                goto done;
        }
 
@@ -705,7 +700,7 @@ static WERROR reg_deletekey_internal(TALLOC_CTX *mem_ctx,
        }
 
        if (name[0] == '\0') {
-               err = WERR_INVALID_PARAM;
+               err = WERR_INVALID_PARAMETER;
                goto done;
        }
 
@@ -802,7 +797,7 @@ WERROR reg_setvalue(struct registry_key *key, const char *name,
 
        if (res == 0) {
                TALLOC_FREE(key->values);
-               err = WERR_NOMEM;
+               err = WERR_NOT_ENOUGH_MEMORY;
                goto done;
        }
 
@@ -838,7 +833,7 @@ static WERROR reg_value_exists(struct registry_key *key, const char *name)
        blob = regval_ctr_getvalue(key->values, name);
 
        if (blob == NULL) {
-               return WERR_BADFILE;
+               return WERR_FILE_NOT_FOUND;
        } else {
                return WERR_OK;
        }
@@ -913,7 +908,7 @@ WERROR reg_setkeysecurity(struct registry_key *key,
 WERROR reg_getversion(uint32_t *version)
 {
        if (version == NULL) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        *version = 0x00000005; /* Windows 2000 registry API version */
@@ -963,7 +958,7 @@ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
        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",
@@ -1023,10 +1018,10 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
 
        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)) {
@@ -1045,7 +1040,7 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
                                  "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));
 
                }