summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_reg.h6
-rw-r--r--source3/registry/reg_frontend.c405
-rw-r--r--source3/rpc_parse/parse_prs.c8
-rw-r--r--source3/rpc_parse/parse_reg.c35
-rw-r--r--source3/rpc_server/srv_reg.c26
-rw-r--r--source3/rpc_server/srv_reg_nt.c49
6 files changed, 375 insertions, 154 deletions
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index 7dbf49cf84..d025cb2c0d 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/include/rpc_reg.h
@@ -32,7 +32,6 @@
#define REG_CREATE_KEY 0x06
#define REG_DELETE_KEY 0x07
#define REG_DELETE_VALUE 0x08
-#define REG_ENUM_VALUE 0x0a
#define REG_FLUSH_KEY 0x0b
#define REG_GET_KEY_SEC 0x0c
#define _REG_UNK_0D 0x0d
@@ -50,6 +49,7 @@
#define REG_OPEN_HKU 0x04
#define REG_CLOSE 0x05
#define REG_ENUM_KEY 0x09
+#define REG_ENUM_VALUE 0x0a
#define REG_OPEN_ENTRY 0x0f
#define REG_QUERY_KEY 0x10
#define REG_INFO 0x11
@@ -97,6 +97,7 @@ typedef struct {
char *string;
uint32 dword;
uint8 *binary;
+ void *void_ptr; /* for casting only */
} data;
} REGISTRY_VALUE;
@@ -314,6 +315,7 @@ typedef struct q_reg_query_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
+
} REG_Q_ENUM_VALUE;
/* REG_R_ENUM_VALUE */
@@ -326,7 +328,7 @@ typedef struct r_reg_enum_value_info
uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
uint32 ptr_value; /* pointer */
- BUFFER2 *buf_value; /* value, in byte buffer */
+ BUFFER2 buf_value; /* value, in byte buffer */
uint32 ptr1; /* pointer */
uint32 len_value1; /* */
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index d8a10940fd..a282207376 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -37,151 +37,6 @@ REGISTRY_HOOK reg_hooks[] = {
};
-/***********************************************************************
- Open the registry database and initialize the REGISTRY_HOOK cache
- ***********************************************************************/
-
-BOOL init_registry( void )
-{
- int i;
-
- if ( !init_registry_db() ) {
- DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
- return False;
- }
-
- /* build the cache tree of registry hooks */
-
- reghook_cache_init();
-
- for ( i=0; reg_hooks[i].keyname; i++ ) {
- if ( !reghook_cache_add(&reg_hooks[i]) )
- return False;
- }
-
- if ( DEBUGLEVEL >= 20 )
- reghook_dump_cache(20);
-
- return True;
-}
-
-
-
-
-/***********************************************************************
- High level wrapper function for storing registry subkeys
- ***********************************************************************/
-
-BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
-{
- if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
- return key->hook->ops->store_subkeys_fn( key->name, subkeys );
- else
- return False;
-
-}
-
-/***********************************************************************
- High level wrapper function for storing registry values
- ***********************************************************************/
-
-BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
- return key->hook->ops->store_values_fn( key->name, val );
- else
- return False;
-}
-
-
-/***********************************************************************
- High level wrapper function for enumerating registry subkeys
- Initialize the TALLOC_CTX if necessary
- ***********************************************************************/
-
-int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
-{
- int result = -1;
-
- if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
- result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
-
- return result;
-}
-
-/***********************************************************************
- retreive a specific subkey specified by index. Caller is
- responsible for freeing memory
- ***********************************************************************/
-
-BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
-{
- char *s;
- REGSUBKEY_CTR ctr;
-
- ZERO_STRUCTP( &ctr );
-
- regsubkey_ctr_init( &ctr );
-
- if ( fetch_reg_keys( key, &ctr) == -1 )
- return False;
-
- if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
- return False;
-
- *subkey = strdup( s );
-
- regsubkey_ctr_destroy( &ctr );
-
- return True;
-}
-
-
-/***********************************************************************
- High level wrapper function for enumerating registry values
- Initialize the TALLOC_CTX if necessary
- ***********************************************************************/
-
-int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- int result = -1;
-
- if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
- result = key->hook->ops->value_fn( key->name, val );
-
- return result;
-}
-
-/***********************************************************************
- Utility function for splitting the base path of a registry path off
- by setting base and new_path to the apprapriate offsets withing the
- path.
-
- WARNING!! Does modify the original string!
- ***********************************************************************/
-
-BOOL reg_split_path( char *path, char **base, char **new_path )
-{
- char *p;
-
- *new_path = *base = NULL;
-
- if ( !path)
- return False;
-
- *base = path;
-
- p = strchr( path, '\\' );
-
- if ( p ) {
- *p = '\0';
- *new_path = p+1;
- }
-
- return True;
-}
-
-
/*
* Utility functions for REGSUBKEY_CTR
*/
@@ -209,6 +64,8 @@ int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname )
{
len = strlen( keyname );
+ /* allocate a space for the char* in the array */
+
if ( ctr->subkeys == 0 )
ctr->subkeys = talloc( ctr->ctx, sizeof(char*) );
else {
@@ -217,6 +74,8 @@ int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname )
ctr->subkeys = pp;
}
+ /* allocate the string and save it in the array */
+
ctr->subkeys[ctr->num_subkeys] = talloc( ctr->ctx, len+1 );
strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 );
ctr->num_subkeys++;
@@ -282,6 +141,88 @@ int regval_ctr_numvals( REGVAL_CTR *ctr )
return ctr->num_values;
}
+/***********************************************************************
+ allocate memory for and duplicate a REGISTRY_VALUE.
+ This is malloc'd memory so the caller should free it when done
+ **********************************************************************/
+
+REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
+{
+ REGISTRY_VALUE *copy = NULL;
+ BOOL fail = True;
+
+ if ( !val )
+ return NULL;
+
+ if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
+ DEBUG(0,("dup_registry_value: malloc() failed!\n"));
+ return NULL;
+ }
+
+ /* copy all the non-pointer initial data */
+
+ memcpy( copy, val, sizeof(REGISTRY_VALUE) );
+
+ switch ( val->type ) {
+ case REG_SZ:
+ if ( !(copy->data.string = strdup( val->data.string )) ) {
+ DEBUG(0,("dup_registry_value: strdup() failed for [%s]!\n",
+ val->data.string));
+ goto done;
+ }
+ break;
+
+ case REG_DWORD:
+ /* nothing to be done; already copied by memcpy() */
+ break;
+
+ case REG_BINARY:
+ if ( !(copy->data.string = memdup( val->data.binary, val->size )) ) {
+ DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
+ val->size));
+ goto done;
+ }
+ break;
+ }
+
+ fail = False;
+
+done:
+ if ( fail )
+ SAFE_FREE( copy );
+
+ return copy;
+}
+
+/**********************************************************************
+ free the memory allocated to a REGISTRY_VALUE
+ *********************************************************************/
+
+void free_registry_value( REGISTRY_VALUE *val )
+{
+ if ( !val )
+ return;
+
+ switch ( val->type )
+ {
+ case REG_SZ:
+ SAFE_FREE( val->data.string );
+ break;
+ case REG_BINARY:
+ SAFE_FREE( val->data.binary );
+ break;
+ }
+
+ SAFE_FREE( val );
+
+ return;
+}
+
+/***********************************************************************
+ Retreive a pointer to a specific value. Caller shoud dup the structure
+ since this memory may go away with a regval_ctr_destroy()
+ **********************************************************************/
+
REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
{
if ( !(idx < ctr->num_values) )
@@ -354,3 +295,177 @@ void regval_ctr_destroy( REGVAL_CTR *ctr )
}
}
+/***********************************************************************
+ Open the registry database and initialize the REGISTRY_HOOK cache
+ ***********************************************************************/
+
+BOOL init_registry( void )
+{
+ int i;
+
+ if ( !init_registry_db() ) {
+ DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
+ return False;
+ }
+
+ /* build the cache tree of registry hooks */
+
+ reghook_cache_init();
+
+ for ( i=0; reg_hooks[i].keyname; i++ ) {
+ if ( !reghook_cache_add(&reg_hooks[i]) )
+ return False;
+ }
+
+ if ( DEBUGLEVEL >= 20 )
+ reghook_dump_cache(20);
+
+ return True;
+}
+
+
+
+
+/***********************************************************************
+ High level wrapper function for storing registry subkeys
+ ***********************************************************************/
+
+BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
+{
+ if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
+ return key->hook->ops->store_subkeys_fn( key->name, subkeys );
+ else
+ return False;
+
+}
+
+/***********************************************************************
+ High level wrapper function for storing registry values
+ ***********************************************************************/
+
+BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
+{
+ if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
+ return key->hook->ops->store_values_fn( key->name, val );
+ else
+ return False;
+}
+
+
+/***********************************************************************
+ High level wrapper function for enumerating registry subkeys
+ Initialize the TALLOC_CTX if necessary
+ ***********************************************************************/
+
+int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
+{
+ int result = -1;
+
+ if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
+ result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
+
+ return result;
+}
+
+/***********************************************************************
+ retreive a specific subkey specified by index. Caller is
+ responsible for freeing memory
+ ***********************************************************************/
+
+BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
+{
+ char *s;
+ REGSUBKEY_CTR ctr;
+
+ ZERO_STRUCTP( &ctr );
+
+ regsubkey_ctr_init( &ctr );
+
+ if ( fetch_reg_keys( key, &ctr) == -1 )
+ return False;
+
+ if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
+ return False;
+
+ *subkey = strdup( s );
+
+ regsubkey_ctr_destroy( &ctr );
+
+ return True;
+}
+
+
+/***********************************************************************
+ High level wrapper function for enumerating registry values
+ Initialize the TALLOC_CTX if necessary
+ ***********************************************************************/
+
+int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
+{
+ int result = -1;
+
+ if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
+ result = key->hook->ops->value_fn( key->name, val );
+
+ return result;
+}
+
+
+/***********************************************************************
+ retreive a specific subkey specified by index. Caller is
+ responsible for freeing memory
+ ***********************************************************************/
+
+BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 key_index )
+{
+ REGVAL_CTR ctr;
+ REGISTRY_VALUE *v;
+
+ ZERO_STRUCTP( &ctr );
+
+ regval_ctr_init( &ctr );
+
+ if ( fetch_reg_values( key, &ctr) == -1 )
+ return False;
+
+ if ( !(v = regval_ctr_specific_value( &ctr, key_index )) )
+ return False;
+
+ *val = dup_registry_value( v );
+
+ regval_ctr_destroy( &ctr );
+
+ return True;
+}
+
+/***********************************************************************
+ Utility function for splitting the base path of a registry path off
+ by setting base and new_path to the apprapriate offsets withing the
+ path.
+
+ WARNING!! Does modify the original string!
+ ***********************************************************************/
+
+BOOL reg_split_path( char *path, char **base, char **new_path )
+{
+ char *p;
+
+ *new_path = *base = NULL;
+
+ if ( !path)
+ return False;
+
+ *base = path;
+
+ p = strchr( path, '\\' );
+
+ if ( p ) {
+ *p = '\0';
+ *new_path = p+1;
+ }
+
+ return True;
+}
+
+
+
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 2ab8c7246e..4de6b88e9c 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -893,9 +893,11 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
return False;
if (UNMARSHALLING(ps)) {
- str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
- if (str->buffer == NULL)
- return False;
+ if ( str->buf_len ) {
+ str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
+ if ( str->buffer == NULL )
+ return False;
+ }
}
p = (char *)str->buffer;
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index 1ebc1532f3..3987f20885 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -1139,6 +1139,38 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
}
/*******************************************************************
+makes a structure.
+********************************************************************/
+
+void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
+{
+ ZERO_STRUCTP(r_u);
+
+ /* value name */
+
+ init_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
+ init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
+
+ /* type */
+
+ r_u->ptr_type = 1;
+ r_u->type = val->type;
+
+ /* data */
+
+ r_u->ptr_value = 1;
+ init_buffer2( &r_u->buf_value, val->data.void_ptr, val->size );
+
+ /* lengths */
+
+ r_u->ptr1 = 1;
+ r_u->len_value1 = val->size;
+
+ r_u->ptr2 = 1;
+ r_u->len_value2 = val->size;
+}
+
+/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -1158,6 +1190,7 @@ BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
return False;
+
if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
return False;
if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
@@ -1228,7 +1261,7 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
return False;
- if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
+ if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
return False;
if(!prs_align(ps))
return False;
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index a096325860..ee873e32e9 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -290,6 +290,31 @@ static BOOL api_reg_enum_key(pipes_struct *p)
return True;
}
+/*******************************************************************
+ api_reg_enum_value
+ ********************************************************************/
+
+static BOOL api_reg_enum_value(pipes_struct *p)
+{
+ REG_Q_ENUM_VALUE q_u;
+ REG_R_ENUM_VALUE r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!reg_io_q_enum_val("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_enum_value(p, &q_u, &r_u);
+
+ if(!reg_io_r_enum_val("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
/*******************************************************************
@@ -302,6 +327,7 @@ static struct api_struct api_reg_cmds[] =
{ "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
{ "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
{ "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },
+ { "REG_ENUM_VALUE" , REG_ENUM_VALUE , api_reg_enum_value },
{ "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key },
{ "REG_INFO" , REG_INFO , api_reg_info },
{ "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index 72e0631e8b..99439bcc38 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -237,10 +237,14 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
lenmax = sizemax = 0;
num_values = regval_ctr_numvals( &values );
- for ( i=0; i<num_values && val; i++ ) {
+ val = regval_ctr_specific_value( &values, 0 );
+
+ for ( i=0; i<num_values && val; i++ )
+ {
+ lenmax = MAX(lenmax, strlen(val->valuename)+1 );
+ sizemax = MAX(sizemax, val->size );
+
val = regval_ctr_specific_value( &values, i );
- lenmax = MAX(lenmax, strlen(val[i].valuename)+1 );
- sizemax = MAX(sizemax, val[i].size );
}
*maxnum = num_values;
@@ -480,6 +484,45 @@ done:
return status;
}
+/*****************************************************************************
+ Implementation of REG_ENUM_VALUE
+ ****************************************************************************/
+
+NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+ REGISTRY_VALUE *val;
+
+
+ DEBUG(5,("_reg_enum_value: Enter\n"));
+
+ if ( !regkey )
+ return NT_STATUS_INVALID_HANDLE;
+
+ DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
+
+ if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
+ {
+ status = NT_STATUS_NO_MORE_ENTRIES;
+ goto done;
+ }
+
+ DEBUG(10,("_reg_enum_value: retrieved value named [%s]\n", val->valuename));
+
+ /* subkey has the string name now */
+
+ init_reg_r_enum_val( r_u, val );
+
+
+ DEBUG(5,("_reg_enum_value: Exit\n"));
+
+done:
+ SAFE_FREE( val );
+
+ return status;
+}
+
/*******************************************************************
reg_shutdwon