From bd509a81cb6c295988a1626adfe394c9778c005e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 25 Jun 2005 17:31:40 +0000 Subject: r7908: * change REGISTRY_HOOK api to use const (fix compiler warning in init_registry_data() * Add means of storing registry values in registry.tdb * add builtin_registry_values[] array for REG_DWORD and REG_SZ values needed during startup * Finish up RegDeleteValue() and RegSetValue() * Finish up regdb_store_reg_values() and regdb_fetch_reg_values() I can now create and retrieve values using regedit.exe on Win2k. bin/net -S rain -U% rpc registry enumerate 'hklm\software\samba' Valuename = Version Type = REG_SZ Data = 3.0.20 Next is to do the virtual writes in reg_printing.c and I'll be done with Print Migrator (yeah! finally) (This used to be commit 3d837e58db9ded64d6b85f047012c7d487be4627) --- source3/include/rpc_reg.h | 9 +- source3/registry/reg_db.c | 186 ++++++++++++++++++++++++++++++++++++---- source3/registry/reg_eventlog.c | 12 +-- source3/registry/reg_frontend.c | 11 +-- source3/registry/reg_objects.c | 35 +++++--- source3/registry/reg_printing.c | 12 +-- source3/registry/reg_shares.c | 12 +-- source3/rpc_parse/parse_reg.c | 5 -- source3/rpc_server/srv_reg_nt.c | 32 +++---- 9 files changed, 231 insertions(+), 83 deletions(-) (limited to 'source3') diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h index 7ef2696228..7d6469bc8e 100644 --- a/source3/include/rpc_reg.h +++ b/source3/include/rpc_reg.h @@ -92,10 +92,10 @@ typedef struct { /* functions for enumerating subkeys and values */ - int (*fetch_subkeys)( char *key, REGSUBKEY_CTR *subkeys); - int (*fetch_values) ( char *key, REGVAL_CTR *val ); - BOOL (*store_subkeys)( char *key, REGSUBKEY_CTR *subkeys ); - BOOL (*store_values)( char *key, REGVAL_CTR *val ); + int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys); + int (*fetch_values) ( const char *key, REGVAL_CTR *val ); + BOOL (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys ); + BOOL (*store_values)( const char *key, REGVAL_CTR *val ); BOOL (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, NT_USER_TOKEN *token ); } REGISTRY_OPS; @@ -252,7 +252,6 @@ typedef struct { } REG_Q_DELETE_VALUE; typedef struct { - POLICY_HND key_pol; WERROR status; } REG_R_DELETE_VALUE; diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index af0a30b76c..3f618fbba4 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -27,9 +27,13 @@ static TDB_CONTEXT *tdb_reg; +#define VALUE_PREFIX "SAMBA_REGVAL" + +static BOOL regdb_store_reg_keys( const char *keyname, REGSUBKEY_CTR *subkeys ); +static BOOL regdb_store_reg_values( const char *keyname, REGVAL_CTR *values); +static int regdb_fetch_reg_keys( const char* key, REGSUBKEY_CTR *subkeys ); +static int regdb_fetch_reg_values( const char* key, REGVAL_CTR *values ); -static BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr ); -static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ); @@ -56,7 +60,6 @@ static const char *builtin_registry_paths[] = { "HKCR", NULL }; -#if 0 /* not used yet */ struct builtin_regkey_value { const char *path; const char *valuename; @@ -67,10 +70,10 @@ struct builtin_regkey_value { } data; }; -static struct builtin_regkey_value builtin_values[] = { +static struct builtin_regkey_value builtin_registry_values[] = { { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot", REG_SZ, { "c:\\Windows" } }, + { NULL, NULL, 0, { NULL } } }; -#endif #define REGVER_V1 1 /* first db version with write support */ @@ -83,8 +86,10 @@ static BOOL init_registry_data( void ) pstring path, base, remaining; fstring keyname, subkeyname; REGSUBKEY_CTR subkeys; + REGVAL_CTR values; int i; const char *p, *p2; + UNISTR2 data; /* loop over all of the predefined paths and add each component */ @@ -134,6 +139,39 @@ static BOOL init_registry_data( void ) } } + /* loop over all of the predefined values and add each component */ + + for ( i=0; builtin_registry_values[i].path != NULL; i++ ) { + regval_ctr_init( &values ); + + regdb_fetch_reg_values( builtin_registry_values[i].path, &values ); + switch( builtin_registry_values[i].type ) { + case REG_DWORD: + regval_ctr_addvalue( &values, + builtin_registry_values[i].valuename, + REG_DWORD, + (char*)&builtin_registry_values[i].data.dw_value, + sizeof(uint32) ); + break; + + case REG_SZ: + init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE); + regval_ctr_addvalue( &values, + builtin_registry_values[i].valuename, + REG_SZ, + (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + break; + + default: + DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n", + builtin_registry_values[i].type)); + } + regdb_store_reg_values( builtin_registry_values[i].path, &values ); + + regval_ctr_destroy( &values ); + } + return True; } @@ -197,7 +235,7 @@ static void normalize_reg_path( pstring keyname ) fstrings ***********************************************************************/ -static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr ) +static BOOL regdb_store_reg_keys_internal( const char *key, REGSUBKEY_CTR *ctr ) { TDB_DATA kbuf, dbuf; char *buffer, *tmpbuf; @@ -263,7 +301,7 @@ done: do not currently exist ***********************************************************************/ -static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) +static BOOL regdb_store_reg_keys( const char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; @@ -317,11 +355,10 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) /*********************************************************************** Retrieve an array of strings containing subkeys. Memory should be - released by the caller. The subkeys are stored in a catenated string - of null terminated character strings + released by the caller. ***********************************************************************/ -static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) +static int regdb_fetch_reg_keys( const char* key, REGSUBKEY_CTR *ctr ) { pstring path; uint32 num_items; @@ -363,20 +400,105 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr ) return num_items; } +/**************************************************************************** + Unpack a list of registry values frem the TDB + ***************************************************************************/ + +static int regdb_unpack_values(REGVAL_CTR *values, char *buf, int buflen) +{ + int len = 0; + uint32 type; + pstring valuename; + int size; + uint8 *data_p; + uint32 num_values = 0; + int i; + + + + /* loop and unpack the rest of the registry values */ + + len += tdb_unpack(buf+len, buflen-len, "d", &num_values); + + for ( i=0; ihook && key->hook->ops && key->hook->ops->store_subkeys ) return key->hook->ops->store_subkeys( key->name, subkeys ); - else - return False; + + return False; } @@ -94,8 +91,8 @@ BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { if ( key->hook && key->hook->ops && key->hook->ops->store_values ) return key->hook->ops->store_values( key->name, val ); - else - return False; + + return False; } diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 582a696529..7ee2cd8414 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -114,7 +114,6 @@ BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) } return False; - } /*********************************************************************** @@ -276,9 +275,23 @@ TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val ) if ( !val ) return NULL; - return val->ctx; -} + return val->ctx; } +/*********************************************************************** + Check for the existance of a value + **********************************************************************/ + +BOOL regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value ) +{ + int i; + + for ( i=0; inum_values; i++ ) { + if ( strequal( ctr->values[i]->valuename, value) ) + return True; + } + + return False; +} /*********************************************************************** Add a new registry value to the array **********************************************************************/ @@ -291,6 +304,10 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type, if ( !name ) return ctr->num_values; + /* Delete the current value (if it exists) and add the new one */ + + regval_ctr_delvalue( ctr, name ); + /* allocate a slot in the array of pointers */ if ( ctr->num_values == 0 ) @@ -366,7 +383,7 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name ) return 0; for ( i=0; inum_values; i++ ) { - if ( strcmp( ctr->values[i]->valuename, name ) == 0) + if ( strequal( ctr->values[i]->valuename, name ) ) break; } @@ -376,15 +393,9 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name ) return ctr->num_values; /* just shift everything down one */ - - for ( /* use previous i */; i<(ctr->num_values-1); i++ ) - memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) ); - - /* paranoia */ - - ZERO_STRUCTP( ctr->values[i] ); - ctr->num_values--; + if ( ctr->num_values ) + memmove( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE)*(ctr->num_values-i) ); return ctr->num_values; } diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 1ac91f4b90..30f2d74660 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -49,9 +49,9 @@ static const char *top_level_keys[MAX_TOP_LEVEL_KEYS] = { the memory allocated here. **********************************************************************/ -static char* trim_reg_path( char *path ) +static char* trim_reg_path( const char *path ) { - char *p; + const char *p; uint16 key_len = strlen(path); uint16 base_key_len; @@ -837,7 +837,7 @@ static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CT Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) +static int printing_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) { char *path; BOOL top_level = False; @@ -876,7 +876,7 @@ static int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) Caller is responsible for freeing memory *********************************************************************/ -static int printing_value_info( char *key, REGVAL_CTR *val ) +static int printing_value_info( const char *key, REGVAL_CTR *val ) { char *path; BOOL top_level = False; @@ -908,7 +908,7 @@ static int printing_value_info( char *key, REGVAL_CTR *val ) (for now at least) *********************************************************************/ -static BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) +static BOOL printing_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) { return True; } @@ -919,7 +919,7 @@ static BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) (for now at least) *********************************************************************/ -static BOOL printing_store_value( char *key, REGVAL_CTR *val ) +static BOOL printing_store_value( const char *key, REGVAL_CTR *val ) { return True; } diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c index 4531327d94..85ac812101 100644 --- a/source3/registry/reg_shares.c +++ b/source3/registry/reg_shares.c @@ -34,9 +34,9 @@ the memory allocated here. **********************************************************************/ -static char* trim_reg_path( char *path ) +static char* trim_reg_path( const char *path ) { - char *p; + const char *p; uint16 key_len = strlen(KEY_SHARES); /* @@ -67,7 +67,7 @@ static char* trim_reg_path( char *path ) Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) +static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) { char *path; BOOL top_level = False; @@ -101,7 +101,7 @@ static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) Caller is responsible for freeing memory *********************************************************************/ -static int shares_value_info( char *key, REGVAL_CTR *val ) +static int shares_value_info( const char *key, REGVAL_CTR *val ) { char *path; BOOL top_level = False; @@ -134,7 +134,7 @@ static int shares_value_info( char *key, REGVAL_CTR *val ) (for now at least) *********************************************************************/ -static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) +static BOOL shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) { return False; } @@ -145,7 +145,7 @@ static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) (for now at least) *********************************************************************/ -static BOOL shares_store_value( char *key, REGVAL_CTR *val ) +static BOOL shares_store_value( const char *key, REGVAL_CTR *val ) { return False; } diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c index 190f39eb79..9048f0f58f 100644 --- a/source3/rpc_parse/parse_reg.c +++ b/source3/rpc_parse/parse_reg.c @@ -343,8 +343,6 @@ BOOL reg_io_q_delete_value(const char *desc, REG_Q_DELETE_VALUE *q_u, if(!prs_unistr4("name", ps, depth, &q_u->name)) return False; - if(!prs_align(ps)) - return False; return True; } @@ -464,9 +462,6 @@ BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *q_u, prs_struct *ps, if(!prs_unistr4("key_class", ps, depth, &q_u->key_class)) return False; - if(!prs_align(ps)) - return False; - return True; } diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 3b25f11359..0e4c49aa48 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -464,6 +464,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL regval_ctr_init( ®vals ); + /* FIXME!!! Move these to a dynmanic lookup in the reg_fetch_values() */ /* couple of hard coded registry values */ if ( strequal(name, "RefusePasswordChange") ) { @@ -544,20 +545,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL goto out; } - /* "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" */ - - if ( strequal( name, "SystemRoot") ) { - value_length = push_ucs2( value, value, "c:\\windows", sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( ®vals, "SystemRoot", REG_SZ, value, value_length ); - - val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - /* else fall back to actually looking up the value */ for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ ) @@ -1311,6 +1298,7 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR values; BOOL write_result; + fstring valuename; if ( !key ) return WERR_BADFID; @@ -1320,12 +1308,16 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; + rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); + + regval_ctr_init( &values ); /* lookup the current values and add the new one */ fetch_reg_values( key, &values ); - /* FIXME!!!! regval_ctr_addvalue( &values, .... ); */ + + regval_ctr_addvalue( &values, valuename, q_u->type, q_u->value.buffer, q_u->value.buf_len ); /* now write to the registry backend */ @@ -1440,7 +1432,8 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR values; BOOL write_result; - + fstring valuename; + if ( !key ) return WERR_BADFID; @@ -1448,13 +1441,16 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; - + + rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); + regval_ctr_init( &values ); /* lookup the current values and add the new one */ fetch_reg_values( key, &values ); - /* FIXME!!!! regval_ctr_delval( &values, .... ); */ + + regval_ctr_delvalue( &values, valuename ); /* now write to the registry backend */ -- cgit