diff options
author | Gerald Carter <jerry@samba.org> | 2002-07-23 04:55:06 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2002-07-23 04:55:06 +0000 |
commit | e8177d1104c8f7a1035f5c9c340ae5c9b594a729 (patch) | |
tree | 6fb8ca0c2ae68a9892f0ff38cfb4440b83205c3e | |
parent | 445a52ebb0cdbc5fff47559f70c2000283da9611 (diff) | |
download | samba-e8177d1104c8f7a1035f5c9c340ae5c9b594a729.tar.gz samba-e8177d1104c8f7a1035f5c9c340ae5c9b594a729.tar.bz2 samba-e8177d1104c8f7a1035f5c9c340ae5c9b594a729.zip |
* changed structure of REG_R_ENUM_VALUE structure since the BUFFER2
is not and [in/out] buffer
* registry value enumeration is working now for the Print\Forms
key. The format of the binary data is not quite right yet
but all installed forms are listed
(This used to be commit 998eb9c7312c3c9a9ed1e9ec294593503c0304bf)
-rw-r--r-- | source3/include/rpc_reg.h | 6 | ||||
-rw-r--r-- | source3/registry/reg_frontend.c | 405 | ||||
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 8 | ||||
-rw-r--r-- | source3/rpc_parse/parse_reg.c | 35 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg.c | 26 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 49 |
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(®_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(®_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 |