r3369: More registry updates
authorJelmer Vernooij <jelmer@samba.org>
Fri, 29 Oct 2004 13:38:37 +0000 (13:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:05:02 +0000 (13:05 -0500)
We now pass the RPC-WINREG torture test.
Also, constructions like the following work now:

regtree <-> smbd <-> NTUSER.DAT
(This used to be commit df952e95cd1cbbfb62b4620e9452993aaef44ad3)

source4/include/registry.h
source4/lib/registry/common/reg_interface.c
source4/rpc_server/winreg/rpc_winreg.c

index 3aea70ecc1bb4c01b860480b9fbf0bc4550ce3b3..a099ae1e0f71e73661bd2139cf2a5c820782d689 100644 (file)
@@ -73,7 +73,7 @@ struct registry_key {
 
 struct registry_value {
   char *name;
-  int data_type;
+  unsigned int data_type;
   int data_len;
   void *data_blk;    /* Might want a separate block */
   struct registry_hive *hive;
@@ -104,6 +104,7 @@ struct registry_operations {
        
        /* Implement this one */
        WERROR (*open_hive) (TALLOC_CTX *, struct registry_hive *, struct registry_key **);
+       WERROR (*close_hive) (struct registry_hive *);
 
        /* Or this one */
        WERROR (*open_key) (TALLOC_CTX *, struct registry_hive *, const char *name, struct registry_key **);
@@ -131,6 +132,7 @@ struct registry_operations {
        /* Key management */
        WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, SEC_DESC *, struct registry_key **);
        WERROR (*del_key)(struct registry_key *);
+       WERROR (*flush_key) (struct registry_key *);
 
        /* Value management */
        WERROR (*set_value)(struct registry_key *, const char *name, int type, void *data, int len); 
index 044dc9a0ad11f4941dc138ebbc32275ab73f15dd..09267a6370871aa3fc354a826ce2d5ac256c08a3 100644 (file)
@@ -340,7 +340,7 @@ WERROR reg_key_num_subkeys(struct registry_key *key, int *count)
                talloc_destroy(mem_ctx);
 
                *count = i;
-               if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK;
+               if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK;
                return error;
        }
 
@@ -351,8 +351,26 @@ WERROR reg_key_num_values(struct registry_key *key, int *count)
 {
        
        if(!key) return WERR_INVALID_PARAM;
-       
-       return key->hive->functions->num_values(key, count);
+
+       if (key->hive->functions->num_values) {
+               return key->hive->functions->num_values(key, count);
+       }
+
+       if(key->hive->functions->get_value_by_index) {
+               int i;
+               WERROR error;
+               struct registry_value *dest;
+               TALLOC_CTX *mem_ctx = talloc_init("num_subkeys");
+               
+               for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_value_by_index(mem_ctx, key, i, &dest)); i++);
+               talloc_destroy(mem_ctx);
+
+               *count = i;
+               if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK;
+               return error;
+       }
+
+       return WERR_NOT_SUPPORTED;
 }
 
 WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_key **subkey)
@@ -646,3 +664,55 @@ WERROR reg_key_flush(struct registry_key *key)
        /* No need for flushing, apparently */
        return WERR_OK;
 }
+
+WERROR reg_key_subkeysizes(struct registry_key *key, uint32 *max_subkeylen, uint32 *max_subkeysize)
+{
+       int i = 0; 
+       struct registry_key *subkey;
+       WERROR error;
+       TALLOC_CTX *mem_ctx = talloc_init("subkeysize");
+
+       *max_subkeylen = *max_subkeysize = 0;
+
+       do {
+               error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey);
+
+               if (W_ERROR_IS_OK(error)) {
+                       *max_subkeysize = MAX(*max_subkeysize, 0xFF);
+                       *max_subkeylen = MAX(*max_subkeylen, strlen(subkey->name));
+               }
+
+               i++;
+       } while (W_ERROR_IS_OK(error));
+
+       talloc_destroy(mem_ctx);
+
+       return WERR_OK;
+}
+
+WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint32 *max_valbufsize)
+{
+       int i = 0; 
+       struct registry_value *value;
+       WERROR error;
+       TALLOC_CTX *mem_ctx = talloc_init("subkeysize");
+
+       *max_valnamelen = *max_valbufsize = 0;
+
+       do {
+               error = reg_key_get_value_by_index(mem_ctx, key, i, &value);
+
+               if (W_ERROR_IS_OK(error)) {
+                       if (value->name) {
+                               *max_valnamelen = MAX(*max_valnamelen, strlen(value->name));
+                       }
+                       *max_valbufsize = MAX(*max_valbufsize, value->data_len);
+               }
+
+               i++;
+       } while (W_ERROR_IS_OK(error));
+
+       talloc_destroy(mem_ctx);
+
+       return WERR_OK;
+}
index 0a071ef7413e3eda80b1086833c008d9373c3b19..fcbbf124c04fb99080aa9b39083fefee02dcb1aa 100644 (file)
@@ -197,8 +197,31 @@ static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
 static WERROR winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct winreg_EnumValue *r)
 {
+       struct dcesrv_handle *h;
+       struct registry_key *key;
+       struct registry_value *value;
+       WERROR result;
 
-       return WERR_NOT_SUPPORTED;
+       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
+       DCESRV_CHECK_HANDLE(h);
+
+       key = h->data;
+
+       result = reg_key_get_value_by_index(mem_ctx, key, r->in.enum_index, &value);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+       
+       r->out.type = &value->data_type;
+       r->out.name_out.name = value->name;
+       r->out.value_out = talloc_p(mem_ctx, struct EnumValueOut);
+       r->out.value_out->offset = 0;
+       r->out.value_out->buffer = data_blob_talloc(mem_ctx, value->data_blk, value->data_len);
+       r->out.value_len1 = r->in.value_len1;
+       r->out.value_len2 = r->in.value_len2;
+       
+
+       return WERR_OK;
 }
 
 
@@ -280,7 +303,41 @@ static WERROR winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
 static WERROR winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct winreg_QueryInfoKey *r)
 {
-       return WERR_NOT_SUPPORTED;
+       struct dcesrv_handle *h;
+       struct registry_key *k;
+       WERROR ret;
+
+       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
+       DCESRV_CHECK_HANDLE(h);
+       k = h->data;
+
+       ret = reg_key_num_subkeys(k, &r->out.num_subkeys);
+       if (!W_ERROR_IS_OK(ret)) { 
+               return ret;
+       }
+
+       ret = reg_key_num_values(k, &r->out.num_values);
+       if (!W_ERROR_IS_OK(ret)) { 
+               return ret;
+       }
+
+       ret = reg_key_subkeysizes(k, &r->out.max_subkeysize, &r->out.max_subkeylen);
+       if (!W_ERROR_IS_OK(ret)) { 
+               return ret;
+       }
+
+       ret = reg_key_valuesizes(k, &r->out.max_valnamelen, &r->out.max_valbufsize);
+       if (!W_ERROR_IS_OK(ret)) { 
+               return ret;
+       }
+
+       r->out.secdescsize = 0; /* FIXME */
+       ZERO_STRUCT(r->out.last_changed_time); /* FIXME */      if (!W_ERROR_IS_OK(ret)) { 
+               return ret;
+       }
+
+
+       return WERR_OK;
 }
 
 
@@ -380,7 +437,8 @@ static WERROR winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call, TAL
 static WERROR winreg_GetVersion(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct winreg_GetVersion *r)
 {
-       return WERR_NOT_SUPPORTED;
+       r->out.version = 5;
+       return WERR_OK;
 }