Author: jelmer
Date: 2007-08-04 18:15:53 +0000 (Sat, 04 Aug 2007)
New Revision: 24216

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24216

Log:
Support creating regf files, run tests against regf.
Modified:
   branches/4.0-regwrite/
   branches/4.0-regwrite/source/lib/registry/hive.h
   branches/4.0-regwrite/source/lib/registry/regf.c
   branches/4.0-regwrite/source/lib/registry/tests/hive.c


Changeset:

Property changes on: branches/4.0-regwrite
___________________________________________________________________
Name: bzr:revision-info
   - timestamp: Tue 2007-06-12 22:27:36.690999985 +0200
committer: Jelmer Vernooij <[EMAIL PROTECTED]>
properties: 
        branch-nick: 4.0-regwrite
        rebase-of: [EMAIL PROTECTED]

   + timestamp: Wed 2007-06-13 01:11:37.940999985 +0200
committer: Jelmer Vernooij <[EMAIL PROTECTED]>
properties: 
        branch-nick: 4.0-regwrite
        rebase-of: [EMAIL PROTECTED]

Name: bzr:revision-id:v3-trunk0
   - 11140 [EMAIL PROTECTED]
11142 [EMAIL PROTECTED]
11143 [EMAIL PROTECTED]
11144 [EMAIL PROTECTED]
11145 [EMAIL PROTECTED]
11146 [EMAIL PROTECTED]
11147 [EMAIL PROTECTED]
11148 [EMAIL PROTECTED]
11149 [EMAIL PROTECTED]
11150 [EMAIL PROTECTED]
11151 [EMAIL PROTECTED]
11152 [EMAIL PROTECTED]
11153 [EMAIL PROTECTED]
11154 [EMAIL PROTECTED]
11155 [EMAIL PROTECTED]
11156 [EMAIL PROTECTED]
11157 [EMAIL PROTECTED]
11158 [EMAIL PROTECTED]
11159 [EMAIL PROTECTED]
11160 [EMAIL PROTECTED]
11161 [EMAIL PROTECTED]
11162 [EMAIL PROTECTED]
11163 [EMAIL PROTECTED]
11164 [EMAIL PROTECTED]
11165 [EMAIL PROTECTED]
11166 [EMAIL PROTECTED]
11167 [EMAIL PROTECTED]
11168 [EMAIL PROTECTED]
11169 [EMAIL PROTECTED]
11170 [EMAIL PROTECTED]
11171 [EMAIL PROTECTED]
11172 [EMAIL PROTECTED]
11173 [EMAIL PROTECTED]
11174 [EMAIL PROTECTED]
11175 [EMAIL PROTECTED]
11176 [EMAIL PROTECTED]
11177 [EMAIL PROTECTED]
11178 [EMAIL PROTECTED]
11179 [EMAIL PROTECTED]
11180 [EMAIL PROTECTED]
11181 [EMAIL PROTECTED]
11182 [EMAIL PROTECTED]
11183 [EMAIL PROTECTED]
11184 [EMAIL PROTECTED]
11185 [EMAIL PROTECTED]
11186 [EMAIL PROTECTED]
11187 [EMAIL PROTECTED]
11188 [EMAIL PROTECTED]

   + 11140 [EMAIL PROTECTED]
11142 [EMAIL PROTECTED]
11143 [EMAIL PROTECTED]
11144 [EMAIL PROTECTED]
11145 [EMAIL PROTECTED]
11146 [EMAIL PROTECTED]
11147 [EMAIL PROTECTED]
11148 [EMAIL PROTECTED]
11149 [EMAIL PROTECTED]
11150 [EMAIL PROTECTED]
11151 [EMAIL PROTECTED]
11152 [EMAIL PROTECTED]
11153 [EMAIL PROTECTED]
11154 [EMAIL PROTECTED]
11155 [EMAIL PROTECTED]
11156 [EMAIL PROTECTED]
11157 [EMAIL PROTECTED]
11158 [EMAIL PROTECTED]
11159 [EMAIL PROTECTED]
11160 [EMAIL PROTECTED]
11161 [EMAIL PROTECTED]
11162 [EMAIL PROTECTED]
11163 [EMAIL PROTECTED]
11164 [EMAIL PROTECTED]
11165 [EMAIL PROTECTED]
11166 [EMAIL PROTECTED]
11167 [EMAIL PROTECTED]
11168 [EMAIL PROTECTED]
11169 [EMAIL PROTECTED]
11170 [EMAIL PROTECTED]
11171 [EMAIL PROTECTED]
11172 [EMAIL PROTECTED]
11173 [EMAIL PROTECTED]
11174 [EMAIL PROTECTED]
11175 [EMAIL PROTECTED]
11176 [EMAIL PROTECTED]
11177 [EMAIL PROTECTED]
11178 [EMAIL PROTECTED]
11179 [EMAIL PROTECTED]
11180 [EMAIL PROTECTED]
11181 [EMAIL PROTECTED]
11182 [EMAIL PROTECTED]
11183 [EMAIL PROTECTED]
11184 [EMAIL PROTECTED]
11185 [EMAIL PROTECTED]
11186 [EMAIL PROTECTED]
11187 [EMAIL PROTECTED]
11188 [EMAIL PROTECTED]
11189 [EMAIL PROTECTED]


Modified: branches/4.0-regwrite/source/lib/registry/hive.h
===================================================================
--- branches/4.0-regwrite/source/lib/registry/hive.h    2007-08-04 18:15:47 UTC 
(rev 24215)
+++ branches/4.0-regwrite/source/lib/registry/hive.h    2007-08-04 18:15:53 UTC 
(rev 24216)
@@ -167,6 +167,10 @@
 
 WERROR reg_create_directory(TALLOC_CTX *parent_ctx, 
                        const char *location, struct hive_key **key);
+WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, 
+                                                        const char *location, 
+                                                        int major_version, 
+                                                        struct hive_key **key);
 
 
 #endif /* __REGISTRY_HIVE_H__ */

Modified: branches/4.0-regwrite/source/lib/registry/regf.c
===================================================================
--- branches/4.0-regwrite/source/lib/registry/regf.c    2007-08-04 18:15:47 UTC 
(rev 24215)
+++ branches/4.0-regwrite/source/lib/registry/regf.c    2007-08-04 18:15:53 UTC 
(rev 24216)
@@ -26,6 +26,8 @@
 #include "librpc/gen_ndr/ndr_security.h"
 #include "librpc/gen_ndr/winreg.h"
 
+static struct hive_operations reg_backend_regf;
+
 /**
  * There are several places on the web where the REGF format is explained; 
  *
@@ -127,7 +129,7 @@
        return ret;
 }
 
-static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, 
+static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, 
                                                  TALLOC_CTX *ctx, 
tdr_pull_fn_t pull_fn, void *p)
 {
        struct tdr_pull pull;
@@ -137,15 +139,15 @@
        pull.data = hbin_get(regf, offset);
        if (!pull.data.data) {
                DEBUG(1, ("Unable to get data at 0x%04x\n", offset));
-               return False;
+               return false;
        }
        
        if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) {
                DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", 
offset));
-               return False;
+               return false;
        }
 
-       return True;
+       return true;
 }
 
 /* Allocate some new data */
@@ -306,7 +308,8 @@
        SIVALS(hbin->data, rel_offset, size);
 }
 
-/* Store a data blob data was already stored, but has changed in size
+/**
+ * Store a data blob data was already stored, but has changed in size
  * Will try to save it at the current location if possible, otherwise 
  * does a free + store */
 static uint32_t hbin_store_resize (struct regf_data *data, uint32_t 
orig_offset, DATA_BLOB blob)
@@ -370,7 +373,8 @@
        return hbin_store(data, blob);
 }
 
-static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t 
push_fn, uint32_t orig_offset, void *p)
+static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t 
push_fn, 
+                                                                          
uint32_t orig_offset, void *p)
 {
        struct tdr_push *push = talloc_zero(regf, struct tdr_push);
        uint32_t ret;
@@ -387,7 +391,8 @@
        return ret;
 }
 
-static uint32_t regf_create_lh_hash(const char *name) {
+static uint32_t regf_create_lh_hash(const char *name) 
+{
        char *hash_name;
        uint32_t ret = 0;
        uint16_t i;
@@ -411,17 +416,22 @@
        const struct regf_key_data *private_data = 
                (const struct regf_key_data *)key;
 
-       *num_subkeys = private_data->nk->num_subkeys;
-       *num_values = private_data->nk->num_values;
+       if (num_subkeys != NULL)
+               *num_subkeys = private_data->nk->num_subkeys;
 
-       if (private_data->nk->clsname_offset != -1) {
-               DATA_BLOB data = hbin_get(private_data->hive, 
-                                                                 
private_data->nk->clsname_offset);
-               *classname = talloc_strndup(mem_ctx, 
-                                                (char*)data.data, 
private_data->nk->clsname_length);
-       } else 
-               *classname = NULL;
+       if (num_values != NULL)
+               *num_values = private_data->nk->num_values;
 
+       if (classname != NULL) {
+               if (private_data->nk->clsname_offset != -1) {
+                       DATA_BLOB data = hbin_get(private_data->hive, 
+                                                                         
private_data->nk->clsname_offset);
+                       *classname = talloc_strndup(mem_ctx, 
+                                                        (char*)data.data, 
private_data->nk->clsname_length);
+               } else 
+                       *classname = NULL;
+       }
+
        /* FIXME: Last mod time */
        
        return WERR_OK;
@@ -435,6 +445,7 @@
        struct regf_key_data *ret;
 
        ret = talloc_zero(ctx, struct regf_key_data);
+       ret->key.ops = &reg_backend_regf;
        ret->hive = talloc_reference(ret, regf);
        ret->offset = offset;
        nk = talloc(ret, struct nk_block);
@@ -656,7 +667,8 @@
                                break;
                        } else {
                                DEBUG(0,("Unknown sublist in ri block\n"));
-                               SMB_ASSERT(0);
+
+                               return WERR_GENERAL_FAILURE;
                        }
                        
                }
@@ -769,7 +781,7 @@
                                break;
                }
                if (key_off == 0)
-                       return WERR_DEST_NOT_FOUND;
+                       return WERR_NOT_FOUND;
        } else if (!strncmp((char *)data.data, "lf", 2)) {
                struct lf_block lf;
                struct tdr_pull pull;
@@ -799,7 +811,7 @@
                                break;
                }
                if (key_off == 0)
-                       return WERR_DEST_NOT_FOUND;
+                       return WERR_NOT_FOUND;
        } else if (!strncmp((char *)data.data, "lh", 2)) {
                struct lh_block lh;
                struct tdr_pull pull;
@@ -831,7 +843,7 @@
                                break;
                }       
                if (key_off == 0)
-                       return WERR_DEST_NOT_FOUND;
+                       return WERR_NOT_FOUND;
        } else if (!strncmp((char *)data.data, "ri", 2)) {
                struct ri_block ri;
                struct tdr_pull pull;
@@ -900,7 +912,7 @@
                                break;
                }
                if (!key_off)
-                       return WERR_DEST_NOT_FOUND;
+                       return WERR_NOT_FOUND;
        } else {
                DEBUG(0, ("Unknown subkey list type.\n"));
                return WERR_GENERAL_FAILURE;
@@ -920,7 +932,7 @@
        struct nk_block root;
        DATA_BLOB data;
        uint32_t sk_offset, cur_sk_offset;
-       BOOL update_cur_sk = false;
+       bool update_cur_sk = false;
 
        /* Get the root nk */
        hbin_get_tdr(regf, regf->header->data_offset, regf, 
@@ -1214,7 +1226,7 @@
                struct li_block li;
                struct tdr_pull pull;
                uint16_t i;
-               BOOL found_offset = false;
+               bool found_offset = false;
        
                DEBUG(10, ("Subkeys in LI list\n"));
                
@@ -1255,7 +1267,7 @@
                struct lf_block lf;
                struct tdr_pull pull;
                uint16_t i;
-               BOOL found_offset = false;
+               bool found_offset = false;
                
                DEBUG(10, ("Subkeys in LF list\n"));
                
@@ -1298,7 +1310,7 @@
                struct lh_block lh;
                struct tdr_pull pull;
                uint16_t i;
-               BOOL found_offset = false;
+               bool found_offset = false;
                
                DEBUG(10, ("Subkeys in LH list\n"));
                
@@ -1356,7 +1368,7 @@
        struct nk_block *nk = private_data->nk;
        struct vk_block vk;
        uint32_t vk_offset;
-       BOOL found_offset = false;
+       bool found_offset = false;
        DATA_BLOB values;
        uint32_t i;
 
@@ -1415,15 +1427,15 @@
        parent_nk = private_data->nk;
 
        if (parent_nk->subkeys_offset == -1) {
-               DEBUG(0, ("Subkey list is empty, this key cannot contain 
subkeys.\n"));
-               return WERR_DEST_NOT_FOUND;
+               DEBUG(4, ("Subkey list is empty, this key cannot contain 
subkeys.\n"));
+               return WERR_NOT_FOUND;
        }
 
        /* Find the key */
        if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, 
                                                                           
(struct hive_key **)&key))) {
                DEBUG(0, ("Key '%s' not found\n", name));
-               return WERR_DEST_NOT_FOUND;
+               return WERR_NOT_FOUND;
        }
        
        if (key->nk->subkeys_offset != -1 || 
@@ -1483,7 +1495,6 @@
        nk.clsname_length = 0;
        nk.key_name = name;
        
-
        /* Get the security descriptor of the root key */
        root = talloc_zero(ctx, struct nk_block);
        if (!hbin_get_tdr(regf, regf->header->data_offset, root, 
(tdr_pull_fn_t)tdr_pull_nk_block, root)) {
@@ -1645,6 +1656,86 @@
        return WERR_OK;
 }
 
+WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, 
+                                                        const char *location, 
+                                                        int minor_version,
+                                                        struct hive_key **key)
+{
+       struct regf_data *regf;
+       struct regf_hdr *regf_hdr;
+       struct tdr_pull pull;
+       int i;
+       struct nk_block nk;
+       WERROR error;
+
+       regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
+
+       DEBUG(5, ("Attempting to create registry file\n"));
+
+       /* Get the header */
+       regf->fd = creat(location, 0644);
+
+       if (regf->fd == -1) {
+               DEBUG(0,("Could not create file: %s, %s\n", location,
+                                strerror(errno)));
+               talloc_free(regf);
+               return WERR_GENERAL_FAILURE;
+       }
+
+       regf_hdr = talloc_zero(regf, struct regf_hdr);
+       regf_hdr->REGF_ID = "regf";
+       unix_to_nt_time(&regf_hdr->modtime, time(NULL));
+       regf_hdr->version.major = 1;
+       regf_hdr->version.minor = minor_version;
+       regf_hdr->last_block = 0x1000; /* Block size */
+       regf_hdr->description = talloc_strdup(regf_hdr, "registry created by 
Samba 4");
+       regf_hdr->chksum = 0;
+
+       regf->header = regf_hdr;
+
+       pull.offset = 0x1000;
+
+       i = 0;
+       /* Read in all hbin blocks */
+       regf->hbins = talloc_array(regf, struct hbin_block *, 1);
+       regf->hbins[0] = NULL;
+
+       regf_hdr->data_offset = -1; /* FIXME */
+
+       nk.header = "nk";
+       nk.type = REG_SUB_KEY;
+       unix_to_nt_time(&nk.last_change, time(NULL));
+       nk.uk1 = 0;
+       nk.parent_offset = -1;
+       nk.num_subkeys = 0;
+       nk.uk2 = 0;
+       nk.subkeys_offset = -1;
+       nk.unknown_offset = -1;
+       nk.num_values = 0;
+       nk.values_offset = -1;
+       memset(nk.unk3, 0, 5);
+       nk.clsname_offset = -1; /* FIXME: fill in */
+       nk.clsname_length = 0;
+       nk.key_name = "";
+       
+       nk.sk_offset = -1; /* FIXME: fill in */
+       
+       /* Store the new nk key */
+       regf->header->data_offset = hbin_store_tdr(regf, (tdr_push_fn_t) 
tdr_push_nk_block, &nk);
+       
+       *key = (struct hive_key *)regf_get_key(parent_ctx, regf, 
regf->header->data_offset);
+
+       /* We can drop our own reference now that *key will have created one */
+       talloc_free(regf);
+
+       error = regf_save_hbin(regf);
+       if (!W_ERROR_IS_OK(error)) {
+               return error;
+       }
+
+       return WERR_OK;
+}
+
 WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, 
                                                  const char *location, struct 
hive_key **key)
 {
@@ -1691,11 +1782,6 @@
                return WERR_GENERAL_FAILURE;
        }
 
-       DEBUG(1, ("Registry '%s' read. Version %d.%d.%d.%d\n", 
-                         regf_hdr->description, regf_hdr->version.major,
-                         regf_hdr->version.minor, regf_hdr->version.release,
-                         regf_hdr->version.build));
-
        /*
         * Validate the header ...
         */

Modified: branches/4.0-regwrite/source/lib/registry/tests/hive.c
===================================================================
--- branches/4.0-regwrite/source/lib/registry/tests/hive.c      2007-08-04 
18:15:47 UTC (rev 24215)
+++ branches/4.0-regwrite/source/lib/registry/tests/hive.c      2007-08-04 
18:15:53 UTC (rev 24216)
@@ -119,7 +119,22 @@
        *data = key;
 
        return true;
+}
 
+static bool hive_setup_regf(struct torture_context *tctx, void **data)
+{
+       struct hive_key *key;
+       WERROR error;
+
+       error = reg_create_regf_file(tctx, "bla-regf", 5, &key);
+       if (!W_ERROR_IS_OK(error)) {
+               fprintf(stderr, "Unable to create new regf file\n");
+               return false;
+       }
+
+       *data = key;
+
+       return true;
 }
 
 static bool test_dir_refuses_null_location(struct torture_context *tctx)
@@ -147,5 +162,10 @@
        tcase = torture_suite_add_tcase(suite, "ldb");
        torture_tcase_set_fixture(tcase, hive_setup_ldb, NULL);
        tcase_add_tests(tcase);
+
+       tcase = torture_suite_add_tcase(suite, "regf");
+       torture_tcase_set_fixture(tcase, hive_setup_regf, NULL);
+       tcase_add_tests(tcase);
+
        return suite;
 }

Reply via email to