summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/registry/reg_db.c20
-rw-r--r--source3/registry/reg_dynamic.c152
-rw-r--r--source3/registry/reg_frontend.c15
-rw-r--r--source3/registry/reg_util.c11
-rw-r--r--source3/rpc_server/srv_reg_nt.c92
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( &regvals );
-
- /* 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(&regvals, "RefusePasswordChange",
- REG_DWORD,
- (const char*)&dwValue, sizeof(dwValue));
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 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(&regvals, REGSTR_PRODUCTTYPE, REG_SZ, value, value_length);
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 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( &regvals, "Hostname",REG_SZ, value, value_length );
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 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( &regvals, "Domain", REG_SZ, value, value_length );
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 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( &regvals );
@@ -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;
}