diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/registry/reg_db.c | 20 | ||||
-rw-r--r-- | source3/registry/reg_dynamic.c | 152 | ||||
-rw-r--r-- | source3/registry/reg_frontend.c | 15 | ||||
-rw-r--r-- | source3/registry/reg_util.c | 11 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 92 |
6 files changed, 183 insertions, 109 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 2e29b94dfc..499f51b77e 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -257,7 +257,7 @@ REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \ - registry/reg_util.o + registry/reg_util.o registry/reg_dynamic.o RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index 3f618fbba4..884949375b 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -217,18 +217,6 @@ BOOL init_registry_db( void ) return True; } -/********************************************************************** - The full path to the registry key is used as database after the - \'s are converted to /'s. Key string is also normalized to UPPER - case. -**********************************************************************/ - -static void normalize_reg_path( pstring keyname ) -{ - pstring_sub( keyname, "\\", "/" ); - strupper_m( keyname ); -} - /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports @@ -308,7 +296,7 @@ static BOOL regdb_store_reg_keys( const char *key, REGSUBKEY_CTR *ctr ) REGSUBKEY_CTR subkeys, old_subkeys; char *oldkeyname; - /* fetch a list of the old subkeys so we can difure out if any were deleted */ + /* fetch a list of the old subkeys so we can determine if any were deleted */ regsubkey_ctr_init( &old_subkeys ); regdb_fetch_reg_keys( key, &old_subkeys ); @@ -331,6 +319,8 @@ static BOOL regdb_store_reg_keys( const char *key, REGSUBKEY_CTR *ctr ) tdb_delete_bystring( tdb_reg, path ); } } + + regsubkey_ctr_destroy( &old_subkeys ); /* now create records for any subkeys that don't already exist */ @@ -491,8 +481,10 @@ static int regdb_fetch_reg_values( const char* key, REGVAL_CTR *values ) data = tdb_fetch_bystring( tdb_reg, keystr ); - if ( !data.dptr ) + if ( !data.dptr ) { + /* all keys have zero values by default */ return 0; + } len = regdb_unpack_values( values, data.dptr, data.dsize ); diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c new file mode 100644 index 0000000000..926b96463a --- /dev/null +++ b/source3/registry/reg_dynamic.c @@ -0,0 +1,152 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * + * 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. + */ + +/* Implementation of registry frontend view functions. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +struct reg_dyn_values { + const char *path; + int (*fetch_values) ( REGVAL_CTR *val ); +}; + +/*********************************************************************** +***********************************************************************/ + +static int netlogon_params( REGVAL_CTR *regvals ) +{ + uint32 dwValue; + + if ( !account_policy_get(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) ) + dwValue = 0; + + regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD, + (char*)&dwValue, sizeof(dwValue) ); + + return regval_ctr_numvals( regvals ); +} + +/*********************************************************************** +***********************************************************************/ + +static int prod_options( REGVAL_CTR *regvals ) +{ + const char *value_ascii = ""; + fstring value; + int value_length; + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + value_ascii = "LanmanNT"; + break; + case ROLE_STANDALONE: + value_ascii = "ServerNT"; + break; + case ROLE_DOMAIN_MEMBER: + value_ascii = "WinNT"; + break; + } + + value_length = push_ucs2( value, value, value_ascii, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue( regvals, "ProductType", REG_SZ, value, + value_length ); + + return regval_ctr_numvals( regvals ); +} + +/*********************************************************************** +***********************************************************************/ + +static int tcpip_params( REGVAL_CTR *regvals ) +{ + fstring value; + int value_length; + char *hname; + fstring mydomainname; + + + hname = myhostname(); + value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue( regvals, "Hostname",REG_SZ, value, value_length ); + + get_mydnsdomname( mydomainname ); + value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue( regvals, "Domain", REG_SZ, value, value_length ); + + return regval_ctr_numvals( regvals ); +} + + +/*********************************************************************** + Structure holding the registry paths and pointers to the value + enumeration functions +***********************************************************************/ + +static struct reg_dyn_values dynamic_values[] = { + { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params }, + { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, + { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, + { NULL, NULL } +}; + +/*********************************************************************** +***********************************************************************/ + +int fetch_dynamic_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) +{ + int i; + pstring path; + + pstrcpy( path, key->name ); + normalize_reg_path( path ); + + for ( i=0; dynamic_values[i].path; i++ ) { + if ( strequal( path, dynamic_values[i].path ) ) + return dynamic_values[i].fetch_values( val ); + } + + return -1; +} + +/*********************************************************************** +***********************************************************************/ + +BOOL check_dynamic_reg_values( REGISTRY_KEY *key ) +{ + int i; + pstring path; + + pstrcpy( path, key->name ); + normalize_reg_path( path ); + + for ( i=0; dynamic_values[i].path; i++ ) { + /* can't write to dynamic keys */ + if ( strequal( path, dynamic_values[i].path ) ) + return True; + } + + return False; +} + diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 8b722ba1f5..440f108cc9 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -89,6 +89,9 @@ BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { + if ( check_dynamic_reg_values( key ) ) + return False; + if ( key->hook && key->hook->ops && key->hook->ops->store_values ) return key->hook->ops->store_values( key->name, val ); @@ -162,10 +165,8 @@ BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index 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 ) @@ -174,7 +175,15 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) if ( key->hook && key->hook->ops && key->hook->ops->fetch_values ) result = key->hook->ops->fetch_values( key->name, val ); + + /* if the backend lookup returned no data, try the dynamic overlay */ + + if ( result == 0 ) { + result = fetch_dynamic_reg_values( key, val ); + return ( result != -1 ) ? result : 0; + } + return result; } @@ -208,7 +217,7 @@ BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 ctr_init = True; } /* clear the cache when val_index == 0 or the path has changed */ - else if ( !val_index || StrCaseCmp(save_path, key->name) ) { + else if ( !val_index || !strequal(save_path, key->name) ) { DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name)); diff --git a/source3/registry/reg_util.c b/source3/registry/reg_util.c index 9120ce0e0a..165292cf2f 100644 --- a/source3/registry/reg_util.c +++ b/source3/registry/reg_util.c @@ -85,4 +85,15 @@ BOOL reg_split_key( char *path, char **base, char **key ) } +/********************************************************************** + The full path to the registry key is used as database after the + \'s are converted to /'s. Key string is also normalized to UPPER + case. +**********************************************************************/ + +void normalize_reg_path( pstring keyname ) +{ + pstring_sub( keyname, "\\", "/" ); + strupper_m( keyname ); +} diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 0e4c49aa48..4603bb077b 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -443,9 +443,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL { WERROR status = WERR_BADFILE; fstring name; - const char *value_ascii = ""; - fstring value; - int value_length; REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); REGISTRY_VALUE *val = NULL; REGVAL_CTR regvals; @@ -463,89 +460,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL DEBUG(5,("reg_info: looking up value: [%s]\n", name)); 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") ) { - uint32 dwValue; - - if ( (val = SMB_MALLOC_P(REGISTRY_VALUE)) == NULL ) { - DEBUG(0,("_reg_info: malloc() failed!\n")); - return WERR_NOMEM; - } - - if (!account_policy_get(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) - dwValue = 0; - regval_ctr_addvalue(®vals, "RefusePasswordChange", - REG_DWORD, - (const char*)&dwValue, sizeof(dwValue)); - val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - if ( strequal(name, REGSTR_PRODUCTTYPE) ) { - /* This makes the server look like a member server to clients */ - /* which tells clients that we have our own local user and */ - /* group databases and helps with ACL support. */ - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - value_ascii = REG_PT_LANMANNT; - break; - case ROLE_STANDALONE: - value_ascii = REG_PT_SERVERNT; - break; - case ROLE_DOMAIN_MEMBER: - value_ascii = REG_PT_WINNT; - break; - } - - value_length = push_ucs2(value, value, value_ascii, sizeof(value), - STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue(®vals, REGSTR_PRODUCTTYPE, REG_SZ, value, value_length); - val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - /* "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters" */ - - if ( strequal( name, "Hostname") ) { - char *hname; - - hname = myhostname(); - value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( ®vals, "Hostname",REG_SZ, value, value_length ); - - val = dup_registry_value( regval_ctr_specific_value( ®vals, 0 ) ); - - status = WERR_OK; - - goto out; - } - - if ( strequal( name, "Domain") ) { - fstring mydomainname; - - get_mydnsdomname( mydomainname ); - value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( ®vals, "Domain", 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++ ) { @@ -559,8 +473,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL free_registry_value( val ); } - -out: init_reg_r_query_value(q_u->ptr_buf, r_u, val, status); regval_ctr_destroy( ®vals ); @@ -880,7 +792,7 @@ static int validate_reg_filename( pstring fname ) } /******************************************************************* - Note: topkeypaty is the *full* path that this *key will be + Note: topkeypat is the *full* path that this *key will be loaded into (including the name of the key) ********************************************************************/ @@ -1479,8 +1391,6 @@ WERROR _reg_get_key_sec(pipes_struct *p, REG_Q_GET_KEY_SEC *q_u, REG_R_GET_KEY_ if ( !(key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) return WERR_ACCESS_DENIED; - - return WERR_ACCESS_DENIED; } |