Index: /trunk/include/regfio.h
===================================================================
--- /trunk/include/regfio.h	(revision 77)
+++ /trunk/include/regfio.h	(revision 78)
@@ -31,6 +31,6 @@
  ***********************************************************/
 
-#ifndef _REGFIO_H
-#define _REGFIO_H
+#ifndef _REGFI_H
+#define _REGFI_H
 
 #include <stdlib.h>
@@ -47,4 +47,5 @@
 
 #include "smb_deps.h"
+#include "void_stack.h"
 
 /******************************************************************************/
@@ -72,4 +73,5 @@
 #define REGF_BLOCKSIZE		0x1000
 #define REGF_ALLOC_BLOCK	0x1000
+#define REGF_MAX_DEPTH		512
 
 /* header sizes for various records */
@@ -188,5 +190,5 @@
 			 */
   uint32 hbin_off;	/* offset from beginning of this hbin block */
-  uint32 subkey_index;	/* index to next subkey record to return */
+  /*uint32 subkey_index;*/	/* index to next subkey record to return */
   uint32 rec_size;	/* ((start_offset - end_offset) & 0xfffffff8) */
   
@@ -246,5 +248,5 @@
 				 */
   
-  /* unknowns used to simply writing */
+  /* unknowns */
   uint32 unknown1;
   uint32 unknown2;
@@ -256,20 +258,36 @@
 
 
+
+typedef struct {
+  REGF_FILE* f;
+  void_stack* keys;
+  uint32 cur_subkey;
+  uint32 cur_value;
+} REGFI_ITERATOR;
+
 /******************************************************************************/
 /* Function Declarations */
 
-const char*   regfio_type_val2str(unsigned int val);
-int           regfio_type_str2val(const char* str);
-
-char*         regfio_get_sacl(SEC_DESC *sec_desc);
-char*         regfio_get_dacl(SEC_DESC *sec_desc);
-char*         regfio_get_owner(SEC_DESC *sec_desc);
-char*         regfio_get_group(SEC_DESC *sec_desc);
-
-REGF_FILE*    regfio_open( const char *filename );
-int           regfio_close( REGF_FILE *r );
-
-REGF_NK_REC*  regfio_rootkey( REGF_FILE *file );
-REGF_NK_REC*  regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk );
-
-#endif	/* _REGFIO_H */
+const char*   regfi_type_val2str(unsigned int val);
+int           regfi_type_str2val(const char* str);
+
+char*         regfi_get_sacl(SEC_DESC *sec_desc);
+char*         regfi_get_dacl(SEC_DESC *sec_desc);
+char*         regfi_get_owner(SEC_DESC *sec_desc);
+char*         regfi_get_group(SEC_DESC *sec_desc);
+
+REGF_FILE*    regfi_open( const char *filename );
+int           regfi_close( REGF_FILE *r );
+
+REGF_NK_REC*  regfi_rootkey( REGF_FILE *file );
+/* REGF_NK_REC*  regfi_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk ); */
+
+REGFI_ITERATOR* regfi_iterator_create(REGF_FILE* fh);
+bool            regfi_iterator_down(REGFI_ITERATOR* i, const char* subkey_name);
+bool            regfi_iterator_up(REGFI_ITERATOR* i);
+REGF_NK_REC*    regfi_iterator_next_subkey(REGFI_ITERATOR* i);
+REGF_VK_REC*    regfi_iterator_next_value(REGFI_ITERATOR* i);
+REGF_VK_REC*    regfi_iterator_fetch_value(REGFI_ITERATOR* i, const char* value_name);
+char*           regfi_iterator_curpath(REGFI_ITERATOR* i);
+
+#endif	/* _REGFI_H */
Index: /trunk/lib/regfio.c
===================================================================
--- /trunk/lib/regfio.c	(revision 77)
+++ /trunk/lib/regfio.c	(revision 78)
@@ -29,6 +29,6 @@
 
 /* Registry types mapping */
-const unsigned int regfio_num_reg_types = 12;
-static const char* regfio_type_names[] =
+const unsigned int regfi_num_reg_types = 12;
+static const char* regfi_type_names[] =
   {"NONE", "SZ", "EXPAND_SZ", "BINARY", "DWORD", "DWORD_BE", "LINK",
    "MULTI_SZ", "RSRC_LIST", "RSRC_DESC", "RSRC_REQ_LIST", "QWORD"};
@@ -36,18 +36,18 @@
 
 /* Returns NULL on error */
-const char* regfio_type_val2str(unsigned int val)
+const char* regfi_type_val2str(unsigned int val)
 {
   if(val == REG_KEY)
     return "KEY";
   
-  if(val >= regfio_num_reg_types)
+  if(val >= regfi_num_reg_types)
     return NULL;
   
-  return regfio_type_names[val];
+  return regfi_type_names[val];
 }
 
 
 /* Returns -1 on error */
-int regfio_type_str2val(const char* str)
+int regfi_type_str2val(const char* str)
 {
   int i;
@@ -56,6 +56,6 @@
     return REG_KEY;
 
-  for(i=0; i < regfio_num_reg_types; i++)
-    if (strcmp(regfio_type_names[i], str) == 0) 
+  for(i=0; i < regfi_num_reg_types; i++)
+    if (strcmp(regfi_type_names[i], str) == 0) 
       return i;
 
@@ -69,5 +69,5 @@
 /* Security descriptor parsing functions  */
 
-const char* regfio_ace_type2str(uint8 type)
+const char* regfi_ace_type2str(uint8 type)
 {
   static const char* map[7] 
@@ -89,5 +89,5 @@
  *   http://msdn2.microsoft.com/en-us/library/aa772242.aspx
  */
-char* regfio_ace_flags2str(uint8 flags)
+char* regfi_ace_flags2str(uint8 flags)
 {
   static const char* flag_map[32] = 
@@ -147,5 +147,5 @@
 
 
-char* regfio_ace_perms2str(uint32 perms)
+char* regfi_ace_perms2str(uint32 perms)
 {
   uint32 i, p;
@@ -226,5 +226,5 @@
 
 
-char* regfio_sid2str(DOM_SID* sid)
+char* regfi_sid2str(DOM_SID* sid)
 {
   uint32 i, size = MAXSUBAUTHS*11 + 24;
@@ -248,5 +248,5 @@
 
 
-char* regfio_get_acl(SEC_ACL* acl)
+char* regfi_get_acl(SEC_ACL* acl)
 {
   uint32 i, extra, size = 0;
@@ -263,8 +263,8 @@
   for (i = 0; i < acl->num_aces && !failed; i++)
   {
-    sid_str = regfio_sid2str(&acl->ace[i].trustee);
-    type_str = regfio_ace_type2str(acl->ace[i].type);
-    perms_str = regfio_ace_perms2str(acl->ace[i].info.mask);
-    flags_str = regfio_ace_flags2str(acl->ace[i].flags);
+    sid_str = regfi_sid2str(&acl->ace[i].trustee);
+    type_str = regfi_ace_type2str(acl->ace[i].type);
+    perms_str = regfi_ace_perms2str(acl->ace[i].info.mask);
+    flags_str = regfi_ace_flags2str(acl->ace[i].flags);
     
     if(flags_str != NULL && perms_str != NULL 
@@ -307,8 +307,8 @@
 
 
-char* regfio_get_sacl(SEC_DESC *sec_desc)
+char* regfi_get_sacl(SEC_DESC *sec_desc)
 {
   if (sec_desc->sacl)
-    return regfio_get_acl(sec_desc->sacl);
+    return regfi_get_acl(sec_desc->sacl);
   else
     return NULL;
@@ -316,8 +316,8 @@
 
 
-char* regfio_get_dacl(SEC_DESC *sec_desc)
+char* regfi_get_dacl(SEC_DESC *sec_desc)
 {
   if (sec_desc->dacl)
-    return regfio_get_acl(sec_desc->dacl);
+    return regfi_get_acl(sec_desc->dacl);
   else
     return NULL;
@@ -325,13 +325,13 @@
 
 
-char* regfio_get_owner(SEC_DESC *sec_desc)
-{
-  return regfio_sid2str(sec_desc->owner_sid);
-}
-
-
-char* regfio_get_group(SEC_DESC *sec_desc)
-{
-  return regfio_sid2str(sec_desc->grp_sid);
+char* regfi_get_owner(SEC_DESC *sec_desc)
+{
+  return regfi_sid2str(sec_desc->owner_sid);
+}
+
+
+char* regfi_get_group(SEC_DESC *sec_desc)
+{
+  return regfi_sid2str(sec_desc->grp_sid);
 }
 
@@ -1368,5 +1368,5 @@
  first hbin offset.
 *******************************************************************/
-REGF_FILE* regfio_open( const char *filename )
+REGF_FILE* regfi_open( const char *filename )
 {
   REGF_FILE *rb;
@@ -1382,5 +1382,5 @@
   /*	if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) 
     {
-    regfio_close( rb );
+    regfi_close( rb );
     return NULL;
     }
@@ -1391,6 +1391,6 @@
 
   if ( (rb->fd = open(filename, flags)) == -1 ) {
-    /* DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno)));*/
-    regfio_close( rb );
+    /* DEBUG(0,("regfi_open: failure to open %s (%s)\n", filename, strerror(errno)));*/
+    regfi_close( rb );
     return NULL;
   }
@@ -1399,6 +1399,6 @@
 	
   if ( !read_regf_block( rb ) ) {
-    /* DEBUG(0,("regfio_open: Failed to read initial REGF block\n"));*/
-    regfio_close( rb );
+    /* DEBUG(0,("regfi_open: Failed to read initial REGF block\n"));*/
+    regfi_close( rb );
     return NULL;
   }
@@ -1412,5 +1412,5 @@
 /*******************************************************************
  *******************************************************************/
-static void regfio_mem_free( REGF_FILE *file )
+static void regfi_mem_free( REGF_FILE *file )
 {
   /* free any zalloc()'d memory */
@@ -1424,9 +1424,9 @@
 /*******************************************************************
  *******************************************************************/
-int regfio_close( REGF_FILE *file )
+int regfi_close( REGF_FILE *file )
 {
   int fd;
 
-  regfio_mem_free( file );
+  regfi_mem_free( file );
 
   /* nothing to do if there is no open file */
@@ -1447,5 +1447,5 @@
  on my experience.  --jerry
 *******************************************************************/
-REGF_NK_REC* regfio_rootkey( REGF_FILE *file )
+REGF_NK_REC* regfi_rootkey( REGF_FILE *file )
 {
   REGF_NK_REC *nk;
@@ -1459,5 +1459,5 @@
 		
   if ( !(nk = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC) )) ) {
-    /*DEBUG(0,("regfio_rootkey: zalloc() failed!\n"));*/
+    /*DEBUG(0,("regfi_rootkey: zalloc() failed!\n"));*/
     return NULL;
   }
@@ -1492,5 +1492,5 @@
 	
   if ( !found ) {
-    /*DEBUG(0,("regfio_rootkey: corrupt registry file ?  No root key record located\n"));*/
+    /*DEBUG(0,("regfi_rootkey: corrupt registry file ?  No root key record located\n"));*/
     return NULL;
   }
@@ -1510,5 +1510,5 @@
  NK record.  Remember that offsets are from the *first* HBIN block.
 *******************************************************************/
-REGF_NK_REC* regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk )
+REGF_NK_REC* regfi_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk )
 {
   REGF_NK_REC *subkey;
@@ -1529,5 +1529,5 @@
     return NULL;
   }
-	
+  
   nk_offset = nk->subkeys.hashes[nk->subkey_index].nk_off;
   if(!prs_set_offset(&hbin->ps, 
Index: /trunk/src/reglookup.c
===================================================================
--- /trunk/src/reglookup.c	(revision 77)
+++ /trunk/src/reglookup.c	(revision 78)
@@ -216,5 +216,5 @@
     {
       tmp_err = strerror(-ret_err);
-      str_type = regfio_type_val2str(type);
+      str_type = regfi_type_val2str(type);
       *error_msg = (char*)malloc(65+strlen(str_type)+strlen(tmp_err)+1);
       if(*error_msg == NULL)
@@ -385,5 +385,5 @@
 {
   void_stack* ret_val;
-  void_stack* rev_ret = void_stack_new(1024);
+  void_stack* rev_ret = void_stack_new(REGF_MAX_DEPTH);
   const char* cur = s;
   char* next = NULL;
@@ -405,5 +405,6 @@
       memcpy(copy, cur, next-cur);
       copy[next-cur] = '\0';
-      void_stack_push(rev_ret, copy);
+      if(!void_stack_push(rev_ret, copy))
+	bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
     }
     cur = next+1;
@@ -412,5 +413,6 @@
   {
     copy = strdup(cur);
-    void_stack_push(rev_ret, copy);
+    if(!void_stack_push(rev_ret, copy))
+      bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
   }
 
@@ -541,5 +543,5 @@
 	      "warning returned: %s\n", prefix, quoted_name, conv_error);
 
-  str_type = regfio_type_val2str(vk->type);
+  str_type = regfi_type_val2str(vk->type);
   if(print_security)
   {
@@ -597,8 +599,8 @@
   if(print_security)
   {
-    owner = regfio_get_owner(k->sec_desc->sec_desc);
-    group = regfio_get_group(k->sec_desc->sec_desc);
-    sacl = regfio_get_sacl(k->sec_desc->sec_desc);
-    dacl = regfio_get_dacl(k->sec_desc->sec_desc);
+    owner = regfi_get_owner(k->sec_desc->sec_desc);
+    group = regfi_get_group(k->sec_desc->sec_desc);
+    sacl = regfi_get_sacl(k->sec_desc->sec_desc);
+    dacl = regfi_get_dacl(k->sec_desc->sec_desc);
     if(owner == NULL)
       owner = empty_str;
@@ -636,5 +638,5 @@
   uint32 path_len = 0;
   uint32 prefix_len = strlen(prefix);
-  int key_type = regfio_type_str2val("KEY");
+  int key_type = regfi_type_str2val("KEY");
   
   if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
@@ -672,5 +674,5 @@
     while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
     {
-      if((sub = regfio_fetch_subkey(f, cur)) == NULL)
+      if((sub = regfi_fetch_subkey(f, cur)) == NULL)
       {
 	sub = void_stack_pop(nk_stack);
@@ -684,5 +686,6 @@
       {
 	sub->subkey_index = 0;
-	void_stack_push(nk_stack, sub);
+	if(!void_stack_push(nk_stack, sub))
+	  bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
 	path = stack2Path(nk_stack);
 	if(path != NULL)
@@ -753,10 +756,12 @@
     found_cur = false;
     while(!found_cur &&
-	  (sub = regfio_fetch_subkey(f, cur)) != NULL)
+	  (sub = regfi_fetch_subkey(f, cur)) != NULL)
     {
       if(strcasecmp(sub->keyname, cur_str) == 0)
       {
 	cur = sub;
-	void_stack_push(nk_stack, sub);
+	if(!void_stack_push(nk_stack, sub))
+	  bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
+
 	found_cur = true;
       }
@@ -802,10 +807,11 @@
 	            " of specified path.\n");
 
-  while((sub = regfio_fetch_subkey(f, cur)) != NULL)
+  while((sub = regfi_fetch_subkey(f, cur)) != NULL)
   {
     if(strcasecmp(sub->keyname, cur_str) == 0)
     {
-      sub_nk_stack = void_stack_new(1024);
-      void_stack_push(sub_nk_stack, sub);
+      sub_nk_stack = void_stack_new(REGF_MAX_DEPTH);
+      if(!void_stack_push(sub_nk_stack, sub))
+	bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
       prefix = stack2Path(nk_stack);
       prefix_len = strlen(prefix);
@@ -890,5 +896,5 @@
 	bailOut(1, "ERROR: '-t' option requires parameter.\n");
       }
-      if((type_filter = regfio_type_str2val(argv[argi])) < 0)
+      if((type_filter = regfi_type_str2val(argv[argi])) < 0)
       {
 	fprintf(stderr, "ERROR: Invalid type specified: %s.\n", argv[argi]);
@@ -917,5 +923,5 @@
     bailOut(2, "ERROR: Memory allocation problem.\n");
 
-  f = regfio_open(registry_file);
+  f = regfi_open(registry_file);
   if(f == NULL)
   {
@@ -924,6 +930,6 @@
   }
 
-  root = regfio_rootkey(f);
-  nk_stack = void_stack_new(1024);
+  root = regfi_rootkey(f);
+  nk_stack = void_stack_new(REGF_MAX_DEPTH);
 
   if(void_stack_push(nk_stack, root))
@@ -950,8 +956,8 @@
   }
   else
-    bailOut(2, "ERROR: Memory allocation problem.\n");
+    bailOut(2, "ERROR: Registry maximum depth exceeded.\n");
 
   void_stack_destroy_deep(nk_stack);
-  regfio_close(f);
+  regfi_close(f);
 
   return 0;
