r168: - Cleanups in rpc backend
authorJelmer Vernooij <jelmer@samba.org>
Sun, 11 Apr 2004 23:16:47 +0000 (23:16 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:51:13 +0000 (12:51 -0500)
- Small fixess in nt4 and dir backends
- Start on w95 file backend
(This used to be commit aa739e8d3c7108f6f2089af2d8d522feacc7f698)

source4/lib/registry/common/reg_interface.c
source4/lib/registry/common/registry.h
source4/lib/registry/config.m4
source4/lib/registry/reg_backend_dir/reg_backend_dir.c
source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c
source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
source4/lib/registry/reg_backend_w95/reg_backend_w95.c [new file with mode: 0644]
source4/lib/registry/tools/gregedit.c
source4/torture/rpc/winreg.c

index 5e6b4fbac882c906fa15128170312aae33fc9db7..917b03cf32f83d94e131f0d3feb84e01c8044601 100644 (file)
@@ -214,7 +214,11 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
 {
        if(!key) return WERR_INVALID_PARAM;
        
-       if(!key->handle->functions->num_subkeys) {
+       if(key->handle->functions->num_subkeys) {
+               return key->handle->functions->num_subkeys(key, count);
+       }
+
+       if(key->handle->functions->fetch_subkeys) {
                if(!key->cache_subkeys) 
                        key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
 
@@ -222,7 +226,20 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
                return WERR_OK;
        }
 
-       return key->handle->functions->num_subkeys(key, count);
+       if(key->handle->functions->get_subkey_by_index) {
+               int i;
+               WERROR error;
+               REG_KEY *dest;
+               for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) {
+                       reg_key_free(dest);
+               }
+
+               *count = i;
+               if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK;
+               return error;
+       }
+
+       return WERR_NOT_SUPPORTED;
 }
 
 WERROR reg_key_num_values(REG_KEY *key, int *count)
@@ -306,8 +323,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk
 
 WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
 {
-       int i, max;
-       REG_VAL *ret = NULL;
+       int i;
        WERROR error = WERR_OK;
 
        if(!key) return WERR_INVALID_PARAM;
@@ -361,7 +377,6 @@ WERROR reg_sync(REG_KEY *h, const char *location)
 
 WERROR reg_key_del_recursive(REG_KEY *key)
 {
-       BOOL succeed = True;
        WERROR error = WERR_OK;
        int i;
        
@@ -543,3 +558,27 @@ WERROR reg_save(REG_HANDLE *h, const char *location)
        /* FIXME */     
        return WERR_NOT_SUPPORTED;
 }
+
+WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent)
+{
+       char *parent_name;
+       char *last;
+       REG_KEY *root;
+       WERROR error;
+
+       error = reg_get_root(key->handle, &root);
+       if(!W_ERROR_IS_OK(error)) return error;
+
+       parent_name = strdup(reg_key_get_path(key));
+       last = strrchr(parent_name, '\\');
+
+       if(!last) {
+               SAFE_FREE(parent_name);
+               return WERR_FOOBAR;
+       }
+       *last = '\0';
+
+       error = reg_open_key(root, parent_name, parent);
+       SAFE_FREE(parent_name);
+       return error;
+}
index 9d7e17cf56bea7645d3f4bfa1bcd152b095ff503..208bcae1e1bffd3274c66d37b368e75e0aaab5a6 100644 (file)
@@ -58,8 +58,8 @@ struct reg_val_s {
 };
 
 /* FIXME */
-typedef void (*key_notification_function) ();
-typedef void (*value_notification_function) ();
+typedef void (*key_notification_function) (void);
+typedef void (*value_notification_function) (void);
 
 
 /* 
index c00b7cc50712dbd0ca4ef5d0ecfad5f3e960484c..d8acb26397459ced73791792c03a486a694abd39 100644 (file)
@@ -11,6 +11,7 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC)
 PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])])
 
 SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o)
+SMB_MODULE(reg_w95, REG, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o)
 SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o)
 SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o)
 SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS])
index 4daaf3d628e6d513dca5a7169f4582747901796d..375daa319bf729f4adcf350f32d2f289d4630ff6 100644 (file)
@@ -21,7 +21,7 @@
 #include "includes.h"
 #include "lib/registry/common/registry.h"
 
-static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc)
+static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **result)
 {
        char *path;
        int ret;
@@ -29,7 +29,7 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_m
        path = reg_path_win2unix(path);
        ret = mkdir(path, 0700);
        SAFE_FREE(path);
-       if(ret == 0)return WERR_OK;
+       if(ret == 0)return WERR_OK; /* FIXME */
        return WERR_INVALID_PARAM;
 }
 
@@ -83,7 +83,6 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
                if(e->d_type == DT_DIR && 
                   strcmp(e->d_name, ".") &&
                   strcmp(e->d_name, "..")) {
-                       char *newfullpath;
                        ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL);
                        ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name);
                        if(ar[(*count)])(*count)++;
@@ -106,16 +105,8 @@ static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentia
        return WERR_OK;
 }
 
-static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value)
+static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
 {
-       char *fullpath;
-       FILE *fd;
-       *value = reg_val_new(p, NULL);
-       (*value)->name = name?talloc_strdup((*value)->mem_ctx, name):NULL;
-       fullpath = reg_path_win2unix(strdup(reg_val_get_path(*value)));
-       
-       fd = fopen(fullpath, "w+");
-       
        /* FIXME */
        return WERR_NOT_SUPPORTED;
 }
index a7e5051ce4a60a6e0d1c39c9119477a1685f0cf9..fd91b4fbe64fafc849d10e92c7db13dfaa8dd223 100644 (file)
@@ -165,7 +165,7 @@ Offset      Size      Contents
 
 To determine the number of values, you have to look at the owner-nk-record!
 
-Der vk-Record
+The vk-Record
 =============
 Offset      Size      Contents
 0x0000      Word      ID: ASCII-"vk" = 0x6B76
@@ -473,7 +473,7 @@ typedef struct regf_struct_s {
        int fd;
        struct stat sbuf;
        char *base;
-       int modified;
+       BOOL modified;
        NTTIME last_mod_time;
        NK_HDR *first_key;
        int sk_count, sk_map_size;
@@ -485,7 +485,6 @@ typedef struct regf_struct_s {
         * keys when we are preparing to write them to a file
         */
        HBIN_BLK *blk_head, *blk_tail, *free_space;
-       TALLOC_CTX *mem_ctx;
 } REGF;
 
 DWORD str_to_dword(const char *a) {
@@ -886,7 +885,6 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val
        char val_name[1024];
        REGF *regf = parent->handle->backend_data;
        int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
-       const char *val_type;
        REG_VAL *tmp = NULL; 
 
        if (!vk_hdr) return WERR_INVALID_PARAM;
@@ -1021,7 +1019,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
 {
        REGF *regf = h->backend_data;
        REG_KEY *tmp = NULL, *own;
-       int name_len, clsname_len, sk_off, own_off;
+       int namlen, clsname_len, sk_off, own_off;
        unsigned int nk_id;
        SK_HDR *sk_hdr;
        int type;
@@ -1037,32 +1035,32 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
 
        SMB_REG_ASSERT(size < 0);
 
-       name_len = SVAL(&nk_hdr->nam_len,0);
+       namlen = SVAL(&nk_hdr->nam_len,0);
        clsname_len = SVAL(&nk_hdr->clsnam_len,0);
 
        /*
         * The value of -size should be ge 
-        * (sizeof(NK_HDR) - 1 + name_len)
+        * (sizeof(NK_HDR) - 1 + namlen)
         * The -1 accounts for the fact that we included the first byte of 
         * the name in the structure. clsname_len is the length of the thing 
         * pointed to by clsnam_off
         */
 
-       if (-size < (sizeof(NK_HDR) - 1 + name_len)) {
+       if (-size < (sizeof(NK_HDR) - 1 + namlen)) {
                DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr));
                DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n",
-                                 sizeof(NK_HDR), name_len, clsname_len));
+                                 sizeof(NK_HDR), namlen, clsname_len));
                return WERR_GENERAL_FAILURE;
        }
 
-       DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len));
+       DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len));
 
        /* Fish out the key name and process the LF list */
 
-       SMB_REG_ASSERT(name_len < sizeof(key_name));
+       SMB_REG_ASSERT(namlen < sizeof(key_name));
 
-       strncpy(key_name, nk_hdr->key_nam, name_len);
-       key_name[name_len] = '\0';
+       strncpy(key_name, nk_hdr->key_nam, namlen);
+       key_name[namlen] = '\0';
 
        type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
        if(type == REG_ROOT_KEY && parent) {
@@ -1088,7 +1086,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
                clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off);
                DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off));
 
-               tmp->class_name = talloc_strdup_w(regf->mem_ctx, clsnamep);
+               tmp->class_name = talloc_strdup_w(h->mem_ctx, clsnamep);
 
                DEBUGADD(2,("  Class Name: %s\n", cls_name));
 
@@ -1572,22 +1570,17 @@ static WERROR nt_close_registry (REG_HANDLE *h)
        regf->base = NULL;
        close(regf->fd);    /* Ignore the error :-) */
 
-       free(regf->sk_map);
-       regf->sk_count = regf->sk_map_size = 0;
-
-       free(regf);
        return WERR_OK;
 }
 
 static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) 
 {
-       REGF *regf = (REGF *)malloc(sizeof(REGF));
+       REGF *regf = (REGF *)talloc_p(h->mem_ctx, REGF);
        REGF_HDR *regf_hdr;
        unsigned int regf_id, hbin_id;
        HBIN_HDR *hbin_hdr;
 
        memset(regf, 0, sizeof(REGF));
-       regf->mem_ctx = talloc_init("regf");
        regf->owner_sid_str = credentials;
        h->backend_data = regf;
 
index 7c30302e8423922290ae20928eaa0f8d9a27a855..f17bdbb3f5ee90b8a2d68e9038cffabf01f873ac 100644 (file)
 #include "includes.h"
 #include "lib/registry/common/registry.h"
 
+/**
+ * This is the RPC backend for the registry library.
+ *
+ * This backend is a little special. The root key is 'virtual'. All 
+ * of its subkeys are the hives available on the remote server.
+ */
+
 static void init_winreg_String(struct winreg_String *name, const char *s)
 {
     name->name = s;
@@ -35,7 +42,6 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
 
 #define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \
 { \
-       NTSTATUS status; \
        struct winreg_Open ## u r; \
        struct winreg_OpenUnknown unknown; \
        struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \
@@ -66,7 +72,7 @@ struct rpc_data {
 };
 
 struct {
-       char *name;
+       const char *name;
        struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h);
 } known_hives[] = {
 { "HKEY_LOCAL_MACHINE", open_HKLM },
@@ -98,7 +104,6 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char
                      lp_workgroup(),
                      user, pass);
 
-
        h->backend_data = mydata;
        
        return ntstatus_to_werror(status);
@@ -118,64 +123,66 @@ static WERROR rpc_close_registry(REG_HANDLE *h)
        return WERR_OK;
 }
 
-static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
+static WERROR rpc_key_put_policy_handle(REG_KEY *k)
 {
-       char *hivename;
-       int i = 0;
-       struct rpc_data *mydata = h->backend_data;
-       struct policy_handle *hive = NULL;
-       char *end = strchr(path+1, '\\');
-    NTSTATUS status;
+       struct policy_handle *key_handle, *hive = NULL;
     struct winreg_OpenKey r;
-       struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle));
-       TALLOC_CTX *mem_ctx;
-       if(end) hivename = strndup(path+1, end-path-1);
-       else hivename = strdup(path+1);
+       int i;
+       struct rpc_data *mydata = k->handle->backend_data;
+       char *realkeyname, *hivename;
+       if(k->backend_data) return WERR_OK;
+
+       /* First, ensure the handle to the hive is opened */
+       realkeyname = strchr(k->path, '\\');
+       if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1);
+       else hivename = strdup(k->path+1);
 
        for(i = 0; known_hives[i].name; i++) {
                if(!strcmp(hivename, known_hives[i].name)) {
-               if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, h);
+               if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, k->handle);
                        hive = mydata->hives[i];
+                       break;
                }
        }
        
        if(!hive) {
                DEBUG(0, ("No such hive: %s\n", hivename));
-               return NULL;
+               return WERR_FOOBAR;
        }
 
-       DEBUG(2, ("Opening %s, hive: %s\n", path, hivename));
+       if(realkeyname[0] == '\\')realkeyname++;
 
-       if(!end || !(*end) || !(*(end+1))) return hive;
+       if(!realkeyname || !(*realkeyname)) { 
+               k->backend_data = hive;
+               return WERR_OK;
+       }
+
+       key_handle = talloc(k->mem_ctx, sizeof(struct policy_handle));
+
+       /* Then, open the handle using the hive */
 
        memset(&r, 0, sizeof(struct winreg_OpenKey));
     r.in.handle = hive;
-    init_winreg_String(&r.in.keyname, end+1);
+    init_winreg_String(&r.in.keyname, realkeyname);
     r.in.unknown = 0x00000000;
     r.in.access_mask = 0x02000000;
     r.out.handle = key_handle;
-                        
-       mem_ctx = talloc_init("openkey");
-    status = dcerpc_winreg_OpenKey(mydata->pipe, mem_ctx, &r);
-       talloc_destroy(mem_ctx);
-                                                                                                                               
-    if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
-        return NULL;
-    }
 
-       return key_handle;
+    dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r);
+
+       if(W_ERROR_IS_OK(r.out.result)) k->backend_data = key_handle;
+                                                                                                                               
+       return r.out.result;
 }
 
 static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
 {
-       struct policy_handle *pol = rpc_get_key_handle(h, name);
-       if(!pol) return WERR_DEST_NOT_FOUND;
-       *key = reg_key_new_abs(name, h, pol);
-       return WERR_OK;
+       WERROR error;
+       *key = reg_key_new_abs(name, h, NULL);
+       return rpc_key_put_policy_handle(*key);
 }
 
-static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys
+static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey
 {
        struct winreg_EnumKey r;
        struct winreg_EnumKeyNameRequest keyname;
@@ -183,28 +190,22 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
        struct winreg_Time tm;
        struct rpc_data *mydata = parent->handle->backend_data;
        int i;
-       REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *));
-       NTSTATUS status = NT_STATUS_OK;
+       NTSTATUS status;
        TALLOC_CTX *mem_ctx;
 
-       /* List the hives */
-       if(parent->backend_data == parent->handle->backend_data) { 
-               for(i = 0; known_hives[i].name; i++) {
-                       ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL);
-                       (*count)++;
-                       ar = talloc_realloc(parent->mem_ctx, ar, sizeof(REG_KEY *) * ((*count)+1));
-               }
+       /* If parent is the root key, list the hives */
+       if(parent->backend_data == mydata) { 
+               if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
 
-               *subkeys = ar;
+               *subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle));
 
                return WERR_OK;
        }
 
-       if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
-
-       if(!parent->backend_data) return WERR_GENERAL_FAILURE;
+       if(!parent->backend_data) {
+               rpc_key_put_policy_handle(parent);
+       }
 
-       (*count) = 0;
        r.in.handle = parent->backend_data;
        keyname.unknown = 0x0000020a;
        init_winreg_String(&keyname.key_name, NULL);
@@ -215,134 +216,59 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
        r.in.last_changed_time = &tm;
        r.out.result.v = 0;
 
-       for(i = 0; NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result); i++) {
-               r.in.enum_index = i;
-               r.in.unknown = r.out.unknown = 0x0414;
-               r.in.key_name_len = r.out.key_name_len = 0;
-               status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
-               if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
-                       ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL);
-                       (*count)++;
-                       ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_KEY *));
-               }
-       }
-
-       *subkeys = ar;
-       return r.out.result;
-}
-
-static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) 
-{
-       struct winreg_EnumValue r;
-       struct winreg_Uint8buf value;
-       struct winreg_String valuename;
-       struct rpc_data *mydata = parent->handle->backend_data;
-       TALLOC_CTX *mem_ctx;
-       uint32 type, requested_len, returned_len;
-       NTSTATUS status = NT_STATUS_OK;
-       REG_VAL **ar = malloc(sizeof(REG_VAL *));
-
-       (*count) = 0;
-
-       /* Root */
-       if(parent->backend_data == parent->handle->backend_data) {
-               *values = ar;
-               return WERR_OK;
+       r.in.enum_index = n;
+       r.in.unknown = r.out.unknown = 0x0414;
+       r.in.key_name_len = r.out.key_name_len = 0;
+       status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
+       if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
+               *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL);
        }
-       
-       if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
-
-       if(!parent->backend_data) return WERR_GENERAL_FAILURE;
-
-       r.in.handle = parent->backend_data;
-       r.in.enum_index = 0;
-
-       init_winreg_String(&valuename, NULL);
-       r.in.name = r.out.name = &valuename;
-
-       type = 0;
-       r.in.type = r.out.type = &type;
-       value.max_len = 0x7fff;
-       value.offset = 0;
-       value.len = 0;
-       value.buffer = NULL;
-
-       r.in.value = r.out.value = &value;
-
-       requested_len = value.max_len;
-       r.in.requested_len = &requested_len;
-       returned_len = 0;
-       r.in.returned_len = &returned_len;
-       r.out.result.v = 0;
-
-       while(1) {
-               status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r);
-               if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
-                       r.in.enum_index++;
-                       ar[(*count)] = reg_val_new(parent, NULL);
-                       ar[(*count)]->name = talloc_strdup(ar[*count]->mem_ctx, r.out.name->name);
-                       ar[(*count)]->data_type = *r.out.type;
-                       ar[(*count)]->data_len = value.len;
-                       ar[(*count)]->data_blk = talloc(ar[*count]->mem_ctx, value.len);
-                       memcpy(ar[(*count)]->data_blk, value.buffer, value.len);
-                       (*count)++;
-                       ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_VAL *));
-               } else break;
-       } 
-       
-       *values = ar;
 
        return r.out.result;
 }
 
-static WERROR rpc_add_key(REG_KEY *parent, const char *name)
+static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key)
 {
+       rpc_key_put_policy_handle(parent);
        /* FIXME */
        return WERR_NOT_SUPPORTED;
 }
 
-static struct policy_handle*get_hive(REG_KEY *k)
-{
-       int i;
-       struct rpc_data *mydata = k->handle->backend_data;
-       for(i = 0; known_hives[i].name; i++) {
-               if(!strncmp(known_hives[i].name, reg_key_get_path(k)+1, strlen(known_hives[i].name))) 
-               return mydata->hives[i];
-       }
-       return NULL;
-}
+
 
 static WERROR rpc_del_key(REG_KEY *k)
 {
        NTSTATUS status;
        struct rpc_data *mydata = k->handle->backend_data;
        struct winreg_DeleteKey r;
-       char *hivepath;
-       struct policy_handle *hive = get_hive(k);
+       REG_KEY *parent;
+       WERROR error = reg_key_get_parent(k, &parent);
+       if(!W_ERROR_IS_OK(error)) return error;
+       rpc_key_put_policy_handle(parent);
 
-       printf("first: %s\n", reg_key_get_path(k));
-       hivepath = strchr(reg_key_get_path(k), '\\');
-       hivepath = strchr(hivepath+1, '\\');
-       printf("asfter: %s\n", hivepath+1);
-       
-    r.in.handle = hive;
-    init_winreg_String(&r.in.key, hivepath+1);
+    r.in.handle = parent->backend_data;
+    init_winreg_String(&r.in.key, k->name);
  
     status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
 
        return r.out.result;
 }
 
+static void rpc_close_key(REG_KEY *k)
+{
+       reg_key_free(k);
+}
+
 static struct registry_ops reg_backend_rpc = {
        .name = "rpc",
        .open_registry = rpc_open_registry,
        .close_registry = rpc_close_registry,
        .open_root_key = rpc_open_root,
        .open_key = rpc_open_key,
-       .fetch_subkeys = rpc_fetch_subkeys,
-       .fetch_values = rpc_fetch_values,
+       .get_subkey_by_index = rpc_get_subkey_by_index,
        .add_key = rpc_add_key,
        .del_key = rpc_del_key,
+       .free_key_backend_data = rpc_close_key,
 };
 
 NTSTATUS reg_rpc_init(void)
diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c
new file mode 100644 (file)
index 0000000..79ebd54
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+   Samba Unix/Linux SMB client utility libeditreg.c 
+   Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
+
+   Backend for Windows '95 registry files. Explanation of file format 
+   comes from http://www.cs.mun.ca/~michael/regutils/.
+
+   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.  */
+
+#include "includes.h"
+#include "lib/registry/common/registry.h"
+
+/**
+ * The registry starts with a header that contains pointers to 
+ * the rgdb.
+ *
+ * After the main header follows the RGKN header (key index table) */
+
+typedef unsigned int DWORD;
+typedef unsigned short WORD;
+
+typedef struct regc_block {
+       DWORD REGC_ID;          /* REGC */
+       DWORD uk1;
+       DWORD rgdb_offset;
+       DWORD chksum;
+       WORD  num_rgdb;
+       WORD  flags;
+       DWORD  uk2;
+       DWORD  uk3;
+       DWORD  uk4;
+       DWORD  uk5;
+} REGC_HDR;
+
+typedef struct rgkn_block {
+       DWORD RGKN_ID;          /* RGKN */
+       DWORD size;
+       DWORD root_offset;
+       DWORD free_offset;
+       DWORD flags;
+       DWORD chksum;
+       DWORD uk1;
+       DWORD uk2;
+} RGKN_HDR;
+
+typedef struct rgkn_key {
+       DWORD inuse;
+       DWORD hash;
+       DWORD next_free;
+       DWORD parent;
+       DWORD child;
+       DWORD next;
+       WORD id;
+       WORD rgdb;
+} RGKN_KEY;
+
+typedef struct rgdb_block {
+       DWORD RGDB_ID;          /* RGDB */
+       DWORD size;
+       DWORD unused_size;
+       WORD flags;
+       WORD section;
+       DWORD free_offset;      /* -1 if there is no free space */
+       WORD max_id;
+       WORD first_free_id;
+       DWORD uk1;
+       DWORD chksum;
+} RGDB_HDR;
+
+typedef struct rgdb_key {
+       DWORD inuse;
+       DWORD hash;
+       DWORD next_free;
+       DWORD parent;
+       DWORD child;
+       DWORD next;
+       WORD id;
+       WORD rgdb;
+} RGDB_KEY;
+
+typedef struct rgdb_value {
+       DWORD type;
+       DWORD uk1;
+       DWORD name_len;
+       DWORD data_len;
+} RGDB_VALUE;
+
+typedef struct regc_struct_s {
+       int fd;
+       struct stat sbuf;
+       BOOL modified;
+       char *base;
+} REGC;
+
+static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
+{
+       REGC *regc = talloc_p(h->mem_ctx, REGC);
+       REGC_HDR *regc_hdr;
+       RGKN_HDR *rgkn_hdr;
+       DWORD regc_id, rgkn_id;
+       memset(regc, 0, sizeof(REGC));
+       h->backend_data = regc;
+
+       if((regc->fd = open(location, O_RDONLY, 0000)) < 0) {
+               return WERR_FOOBAR;
+       }
+
+       if(fstat(regc->fd, &regc->sbuf) < 0) {
+               return WERR_FOOBAR;
+       }
+
+       regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0);
+       regc_hdr = (REGC_HDR *)regc->base;
+
+       if ((int)regc->base == 1) {
+               return WERR_FOOBAR;
+       }
+       
+       if ((regc_id = IVAL(&regc_hdr->REGC_ID,0)) != str_to_dword("REGC")) {
+               DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n", 
+                                 regc_id, location));
+               return WERR_FOOBAR;
+       }
+
+       rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR);
+
+       if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
+               DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n", 
+                                 rgkn_id, location));
+               return WERR_FOOBAR;
+       }
+
+       //rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR);
+
+       /* FIXME */
+
+       return WERR_OK;
+}
+
+static WERROR w95_close_reg(REG_HANDLE *h)
+{
+       REGC *regc = h->backend_data;
+    if (regc->base) munmap(regc->base, regc->sbuf.st_size);
+    regc->base = NULL;
+    close(regc->fd);
+       return WERR_OK;
+}
+
+static struct registry_ops reg_backend_w95 = {
+       .name = "w95",
+       .open_registry = w95_open_reg,
+       .close_registry = w95_close_reg,
+};
+
+NTSTATUS reg_w95_init(void)
+{
+       return register_backend("registry", &reg_backend_w95);
+}
index 51fad4287dfe03ba265210b35bbbf6932b633a10..4fbb1b27058279aef5aadfe097cf27881e4e2f89 100644 (file)
@@ -84,6 +84,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
        g_assert(k);
        
        for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
+               int count;
                /* Replace the blank child with the first directory entry
            You may be tempted to remove the blank child node and then 
            append a new one.  Don't.  If you remove the blank child 
@@ -103,14 +104,8 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
                                                sub,
                                                -1);
                
-               gtk_tree_store_append(store_keys, &tmpiter, &iter);
-       }
-
-       /* Remove placeholder child */
-       if(i == 0) {
-           gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), 
-                                     &iter, parent);
-               gtk_tree_store_remove(store_keys, &iter);
+               if(W_ERROR_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0) 
+                       gtk_tree_store_append(store_keys, &tmpiter, &iter);
        }
 
        if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
index 42326b1468eaa838b4f3b40fb26a69b8c8433f07..3864de650325d5ed2d67f27389fce976f81d8ae6 100644 (file)
@@ -493,6 +493,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
                ret = False;
        }
 
+       if (!test_FlushKey(p, mem_ctx, &handle)) {
+               printf("FlushKey failed\n");
+               ret = False;
+       }
+
        if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
                printf("CreateKey failed (OpenKey after Create didn't work)\n");
                ret = False;
@@ -503,6 +508,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
                ret = False;
        }
 
+       if (!test_FlushKey(p, mem_ctx, &handle)) {
+               printf("FlushKey failed\n");
+               ret = False;
+       }
+
        if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
                printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
                ret = False;
@@ -513,12 +523,6 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
                ret = False;
        }
 
-       if (!test_FlushKey(p, mem_ctx, &handle)) {
-               printf("FlushKey failed\n");
-               ret = False;
-       }
-
-
        /* The HKCR hive has a very large fanout */
 
        if (open_fn == test_OpenHKCR) {