From 06ae9ac5d98a752d8ca17686a4a3b1786fbe520d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 18 Jul 2002 23:00:24 +0000 Subject: virtual registry framework with initial printing hooks. (This used to be commit a43d9788fa8823d678ee72470421b980165ec2b0) --- source3/registry/reg_cachehook.c | 96 ++++++++++++ source3/registry/reg_db.c | 311 ++++++++++++++++++++++++++++++++++++++ source3/registry/reg_frontend.c | 313 ++++++++------------------------------- source3/registry/reg_printing.c | 243 ++++++++++++++++++++++++++++++ 4 files changed, 709 insertions(+), 254 deletions(-) create mode 100644 source3/registry/reg_cachehook.c create mode 100644 source3/registry/reg_db.c create mode 100644 source3/registry/reg_printing.c (limited to 'source3/registry') diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c new file mode 100644 index 0000000000..daf2f24180 --- /dev/null +++ b/source3/registry/reg_cachehook.c @@ -0,0 +1,96 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald Carter 2002. + * + * 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 hook cache tree */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +static SORTED_TREE *cache_tree; + +/********************************************************************** + Initialize the cache tree + *********************************************************************/ + +BOOL reghook_cache_init( void ) +{ + cache_tree = sorted_tree_init( NULL, NULL ); + + return ( cache_tree == NULL ); +} + +/********************************************************************** + Add a new REGISTRY_HOOK to the cache. Note that the keyname + is not in the exact format that a SORTED_TREE expects. + *********************************************************************/ + +BOOL reghook_cache_add( REGISTRY_HOOK *hook ) +{ + pstring key; + + if ( !hook ) + return False; + + pstrcpy( key, "\\"); + pstrcat( key, hook->keyname ); + + pstring_sub( key, "\\", "/" ); + + DEBUG(10,("reghook_cache_add: Adding key [%s]\n", key)); + + return sorted_tree_add( cache_tree, key, hook ); +} + +/********************************************************************** + Initialize the cache tree + *********************************************************************/ + +REGISTRY_HOOK* reghook_cache_find( char *keyname ) +{ + char *key; + + if ( !keyname ) + return NULL; + + if ( (key = strdup( keyname )) == NULL ) { + DEBUG(0,("reghook_cache_find: strdup() failed for string [%s] !?!?!\n", + keyname)); + return NULL; + } + + string_sub( key, "\\", "/", 0 ); + + DEBUG(10,("reghook_cache_find: Searching for keyname [%s]\n", key)); + + return sorted_tree_find( cache_tree, key ) ; +} + +/********************************************************************** + Initialize the cache tree + *********************************************************************/ + +void reghook_dump_cache( int debuglevel ) +{ + DEBUG(debuglevel,("reghook_dump_cache: Starting cache dump now...\n")); + + sorted_tree_print_keys( cache_tree, debuglevel ); +} diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c new file mode 100644 index 0000000000..a521cdcdd0 --- /dev/null +++ b/source3/registry/reg_db.c @@ -0,0 +1,311 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald Carter 2002. + * + * 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 internal registry database functions. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +static TDB_CONTEXT *tdb_reg; + + +/*********************************************************************** + Open the registry data in the tdb + ***********************************************************************/ + +static BOOL init_registry_data( void ) +{ + pstring keyname; + char *subkeys[3]; + + /* HKEY_LOCAL_MACHINE */ + + pstrcpy( keyname, KEY_HKLM ); + subkeys[0] = "SYSTEM"; + if ( !regdb_store_reg_keys( keyname, subkeys, 1 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM" ); + subkeys[0] = "CurrentControlSet"; + if ( !regdb_store_reg_keys( keyname, subkeys, 1 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet" ); + subkeys[0] = "Control"; + subkeys[1] = "services"; + if ( !regdb_store_reg_keys( keyname, subkeys, 2 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" ); + subkeys[0] = "Print"; + subkeys[1] = "ProduceOptions"; + if ( !regdb_store_reg_keys( keyname, subkeys, 2 )) + return False; + +#if 0 /* JERRY */ + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/Print" ); + subkeys[0] = "Environments"; + subkeys[1] = "Forms"; + subkeys[2] = "Printers"; + if ( !regdb_store_reg_keys( keyname, subkeys, 0 )) + return False; +#endif + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" ); + if ( !regdb_store_reg_keys( keyname, subkeys, 0 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/services" ); + subkeys[0] = "Netlogon"; + if ( !regdb_store_reg_keys( keyname, subkeys, 1 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon" ); + subkeys[0] = "parameters"; + if ( !regdb_store_reg_keys( keyname, subkeys, 1 )) + return False; + + pstrcpy( keyname, KEY_HKLM ); + pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon/parameters" ); + if ( !regdb_store_reg_keys( keyname, subkeys, 0 )) + return False; + + + /* HKEY_USER */ + + pstrcpy( keyname, KEY_HKU ); + if ( !regdb_store_reg_keys( keyname, subkeys, 0 ) ) + return False; + + return True; +} + +/*********************************************************************** + Open the registry database + ***********************************************************************/ + +BOOL init_registry_db( void ) +{ + static pid_t local_pid; + + if (tdb_reg && local_pid == sys_getpid()) + return True; + + /* + * try to open first without creating so we can determine + * if we need to init the data in the registry + */ + + tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); + if ( !tdb_reg ) + { + tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + if ( !tdb_reg ) { + DEBUG(0,("init_registry: Failed to open registry %s (%s)\n", + lock_path("registry.tdb"), strerror(errno) )); + return False; + } + + DEBUG(10,("init_registry: Successfully created registry tdb\n")); + + /* create the registry here */ + if ( !init_registry_data() ) { + DEBUG(0,("init_registry: Failed to initiailize data in registry!\n")); + return False; + } + } + + local_pid = sys_getpid(); + + return True; +} + + + +/*********************************************************************** + Add subkey strings to the registry tdb under a defined key + fmt is the same format as tdb_pack except this function only supports + fstrings + + The full path to the registry key is used as database after the + \'s are converted to /'s. + ***********************************************************************/ + +BOOL regdb_store_reg_keys( char *keyname, char **subkeys, uint32 num_subkeys ) +{ + TDB_DATA kbuf, dbuf; + char *buffer, *tmpbuf; + int i = 0; + uint32 len, buflen; + BOOL ret = True; + + if ( !keyname ) + return False; + + /* allocate some initial memory */ + + buffer = malloc(sizeof(pstring)); + buflen = sizeof(pstring); + len = 0; + + /* store the number of subkeys */ + + len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys); + + /* pack all the strings */ + + for (i=0; i buflen ) { + /* allocate some extra space */ + if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) { + DEBUG(0,("store_reg_keys: Failed to realloc memory of size [%d]\n", len*2)); + ret = False; + goto done; + } + buffer = tmpbuf; + buflen = len*2; + + len = tdb_pack(buffer+len, buflen-len, "f", subkeys[i]); + } + } + + /* finally write out the data */ + + kbuf.dptr = keyname; + kbuf.dsize = strlen(keyname)+1; + dbuf.dptr = buffer; + dbuf.dsize = len; + if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) { + ret = False; + goto done; + } + +done: + SAFE_FREE( buffer ); + return ret; +} + +/*********************************************************************** + 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 + ***********************************************************************/ + +int regdb_fetch_reg_keys( char* key, char **subkeys ) +{ + pstring path; + uint32 num_items; + TDB_DATA dbuf; + char *buf; + uint32 buflen, len; + int i; + char *s; + + + pstrcpy( path, key ); + + /* convert to key format */ + pstring_sub( path, "\\", "/" ); + + dbuf = tdb_fetch_by_string( tdb_reg, path ); + + buf = dbuf.dptr; + buflen = dbuf.dsize; + + if ( !buf ) { + DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key)); + return 0; + } + + len = tdb_unpack( buf, buflen, "d", &num_items); + if (num_items) { + if ( (*subkeys = (char*)malloc(sizeof(fstring)*num_items)) == NULL ) { + DEBUG(0,("fetch_reg_keys: Failed to malloc memory for subkey array containing [%d] items!\n", + num_items)); + num_items = -1; + goto done; + } + } + + s = *subkeys; + for (i=0; iname, subkeys, num_subkeys ); - /* - * try to open first without creating so we can determine - * if we need to init the data in the registry - */ - - tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); - if ( !tdb_reg ) - { - tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if ( !tdb_reg ) { - DEBUG(0,("init_registry: Failed to open registry %s (%s)\n", - lock_path("registry.tdb"), strerror(errno) )); - return False; - } - - DEBUG(10,("init_registry: Successfully created registry tdb\n")); - - /* create the registry here */ - if ( !init_registry_data() ) { - DEBUG(0,("init_registry: Failed to initiailize data in registry!\n")); - return False; - } - } - - local_pid = sys_getpid(); - - return True; } /*********************************************************************** - Add subkey strings to the registry tdb under a defined key - fmt is the same format as tdb_pack except this function only supports - fstrings + High level wrapper function for storing registry values ***********************************************************************/ -BOOL store_reg_keys( char *keyname, char **subkeys, uint32 num_subkeys ) +BOOL store_reg_values( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 num_values ) { - TDB_DATA kbuf, dbuf; - char *buffer, *tmpbuf; - int i = 0; - uint32 len, buflen; - BOOL ret = True; - - if ( !keyname ) - return False; - - /* allocate some initial memory */ - - buffer = malloc(sizeof(pstring)); - buflen = sizeof(pstring); - len = 0; - - /* store the number of subkeys */ - - len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys); - - /* pack all the strings */ - - for (i=0; i buflen ) { - /* allocate some extra space */ - if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) { - DEBUG(0,("store_reg_keys: Failed to realloc memory of size [%d]\n", len*2)); - ret = False; - goto done; - } - buffer = tmpbuf; - buflen = len*2; - - len = tdb_pack(buffer+len, buflen-len, "f", subkeys[i]); - } - } - - /* finally write out the data */ - - kbuf.dptr = keyname; - kbuf.dsize = strlen(keyname)+1; - dbuf.dptr = buffer; - dbuf.dsize = len; - if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) { - ret = False; - goto done; - } - -done: - SAFE_FREE( buffer ); - return ret; + return True; } + /*********************************************************************** - 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 + High level wrapper function for enumerating registry subkeys ***********************************************************************/ -int fetch_reg_keys( char* key, char **subkeys ) +int fetch_reg_keys( REGISTRY_KEY *key, char **subkeys ) { - pstring path; - uint32 num_items; - TDB_DATA dbuf; - char *buf; - uint32 buflen, len; - int i; - char *s; - - - pstrcpy( path, key ); - - /* convert to key format */ - pstring_sub( path, "\\", "/" ); - - dbuf = tdb_fetch_by_string( tdb_reg, path ); - - buf = dbuf.dptr; - buflen = dbuf.dsize; - - if ( !buf ) { - DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key)); - return 0; - } + int num_subkeys; - len = tdb_unpack( buf, buflen, "d", &num_items); - if (num_items) { - if ( (*subkeys = (char*)malloc(sizeof(fstring)*num_items)) == NULL ) { - DEBUG(0,("fetch_reg_keys: Failed to malloc memory for subkey array containing [%d] items!\n", - num_items)); - num_items = -1; - goto done; - } - } - - s = *subkeys; - for (i=0; ihook && key->hook->ops && key->hook->ops->subkey_fn ) + num_subkeys = key->hook->ops->subkey_fn( key->name, subkeys ); + else + num_subkeys = regdb_fetch_reg_keys( key->name, subkeys ); -done: - SAFE_FREE(dbuf.dptr); - return num_items; + return num_subkeys; } /*********************************************************************** - count the number of subkeys dtored in the registry + High level wrapper function for retreiving a specific registry subkey + given and index. ***********************************************************************/ -int fetch_reg_keys_count( char* key ) +BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index ) { - pstring path; - uint32 num_items; - TDB_DATA dbuf; - char *buf; - uint32 buflen, len; - - - pstrcpy( path, key ); - - /* convert to key format */ - pstring_sub( path, "\\", "/" ); - - dbuf = tdb_fetch_by_string( tdb_reg, path ); - - buf = dbuf.dptr; - buflen = dbuf.dsize; - - if ( !buf ) { - DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key)); - return 0; - } - - len = tdb_unpack( buf, buflen, "d", &num_items); - - SAFE_FREE( buf ); + BOOL result; + + if ( key->hook && key->hook->ops && key->hook->ops->subkey_specific_fn ) + result = key->hook->ops->subkey_specific_fn( key->name, subkey, key_index ); + else + result = regdb_fetch_reg_keys_specific( key->name, subkey, key_index ); - return num_items; + return result; } + /*********************************************************************** - retreive a specific subkey specified by index. The subkey parameter - is assumed to be an fstring. + High level wrapper function for enumerating registry values ***********************************************************************/ -BOOL fetch_reg_keys_specific( char* key, char* subkey, uint32 key_index ) +int fetch_reg_values( REGISTRY_KEY *key, REGISTRY_VALUE **val ) { - int num_subkeys, i; - char *subkeys = NULL; - char *s; + int num_values; - num_subkeys = fetch_reg_keys( key, &subkeys ); - if ( num_subkeys == -1 ) - return False; - - s = subkeys; - for ( i=0; ihook && key->hook->ops && key->hook->ops->value_fn ) + num_values = key->hook->ops->value_fn( key->name, val ); + else + num_values = regdb_fetch_reg_values( key->name, val ); - /* go onto the next string */ - s += strlen(s) + 1; - } - - SAFE_FREE(subkeys); - - return True; + return num_values; } - - diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c new file mode 100644 index 0000000000..8144110d1f --- /dev/null +++ b/source3/registry/reg_printing.c @@ -0,0 +1,243 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald Carter 2002. + * + * 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 virtual views for printing information */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +#define MAX_TOP_LEVEL_KEYS 3 + +/* some symbolic indexes into the top_level_keys */ + +#define KEY_INDEX_ENVIR 0 +#define KEY_INDEX_FORMS 1 +#define KEY_INDEX_PRINTER 2 + +static char *top_level_keys[MAX_TOP_LEVEL_KEYS] = { + "Environments", + "Forms", + "Printers" +}; + +/********************************************************************** + It is safe to assume that every registry path passed into on of + the exported functions here begins with KEY_PRINTING else + these functions would have never been called. This is a small utility + function to strip the beginning of the path and make a copy that the + caller can modify. Note that the caller is responsible for releasing + the memory allocated here. + **********************************************************************/ + +static char* trim_reg_path( char *path ) +{ + char *p; + + p = path + strlen(KEY_PRINTING); + + if ( *p ) + return strdup(p); + else + return NULL; +} + +/********************************************************************** + handle enumeration of subkeys below KEY_PRINTING. + *********************************************************************/ + +static int handle_printing_subpath( char *key, char **subkeys, uint32 index ) +{ + int result = 0; + char *p, *base; + int i; + + + /* + * break off the first part of the path + * topmost base **must** be one of the strings + * in top_level_keys[] + */ + + base = key; + p = strchr( key, '\\' ); + if ( p ) + *p = '\0'; + + for ( i=0; i[%s]\n", key)); + + path = trim_reg_path( key ); + + /* check to see if we are dealing with the top level key */ + + if ( !path ) + top_level = True; + + if ( top_level ) { + if ( ! (*subkeys = malloc( sizeof(top_level_keys) )) ) + goto done; + + num_subkeys = MAX_TOP_LEVEL_KEYS; + memcpy( *subkeys, top_level_keys, sizeof(top_level_keys) ); + } + else + num_subkeys = handle_printing_subpath( path, subkeys, -1 ); + +done: + SAFE_FREE( path ); + return num_subkeys; +} + +/********************************************************************** + Count the registry subkey names given a registry path. + Caller is responsible for freeing memory to **subkey + *********************************************************************/ + +BOOL printing_subkey_specific( char *key, char** subkey, uint32 index ) +{ + char *path; + BOOL top_level = False; + BOOL result = False; + + DEBUG(10,("printing_subkey_specific: key=>[%s], index=>[%d]\n", key, index)); + + path = trim_reg_path( key ); + + /* check to see if we are dealing with the top level key */ + + if ( !path ) + top_level = True; + + + + if ( top_level ) { + + /* make sure the index is in range */ + + if ( !(index < MAX_TOP_LEVEL_KEYS) ) + goto done; + + if ( !(*subkey = malloc( strlen(top_level_keys[index])+1 )) ) + goto done; + + strncpy( *subkey, top_level_keys[index], strlen(top_level_keys[index])+1 ); + + result = True; + } + else { + if ( handle_printing_subpath( path, subkey, index ) != -1 ) + result = True; + } + +done: + SAFE_FREE( path ); + + return result; +} + +/********************************************************************** + Enumerate registry values given a registry path. + Caller is responsible for freeing memory + *********************************************************************/ + +int printing_value_info( char *key, REGISTRY_VALUE **val ) +{ + DEBUG(10,("printing_value_info: key=>[%s]\n", key)); + + return 0; +} + +/********************************************************************** + Stub function which always returns failure since we don't want + people storing printing information directly via regostry calls + (for now at least) + *********************************************************************/ + +BOOL printing_store_subkey( char *key, char **subkeys, uint32 num_subkeys ) +{ + return False; +} + +/********************************************************************** + Stub function which always returns failure since we don't want + people storing printing information directly via regostry calls + (for now at least) + *********************************************************************/ + +BOOL printing_store_value( char *key, REGISTRY_VALUE **val, uint32 num_values ) +{ + return False; +} + +/* + * Table of function pointers for accessing printing data + */ + +REGISTRY_OPS printing_ops = { + printing_subkey_info, + printing_subkey_specific, + printing_value_info, + printing_store_subkey, + printing_store_value +}; + -- cgit