1/* 2 * Unix SMB/CIFS implementation. 3 * RPC Pipe client / server routines 4 * Copyright (C) Gerald Carter 2002. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21/* Implementation of registry frontend view functions. */ 22 23#include "includes.h" 24 25#undef DBGC_CLASS 26#define DBGC_CLASS DBGC_RPC_SRV 27 28extern REGISTRY_OPS printing_ops; 29extern REGISTRY_OPS regdb_ops; /* these are the default */ 30 31/* array of REGISTRY_HOOK's which are read into a tree for easy access */ 32 33 34REGISTRY_HOOK reg_hooks[] = { 35 { KEY_PRINTING, &printing_ops }, 36 { NULL, NULL } 37}; 38 39 40/*********************************************************************** 41 Open the registry database and initialize the REGISTRY_HOOK cache 42 ***********************************************************************/ 43 44BOOL init_registry( void ) 45{ 46 int i; 47 48 if ( !init_registry_db() ) { 49 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n")); 50 return False; 51 } 52 53 /* build the cache tree of registry hooks */ 54 55 reghook_cache_init(); 56 57 for ( i=0; reg_hooks[i].keyname; i++ ) { 58 if ( !reghook_cache_add(®_hooks[i]) ) 59 return False; 60 } 61 62 if ( DEBUGLEVEL >= 20 ) 63 reghook_dump_cache(20); 64 65 return True; 66} 67 68 69 70 71/*********************************************************************** 72 High level wrapper function for storing registry subkeys 73 ***********************************************************************/ 74 75BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) 76{ 77 if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn ) 78 return key->hook->ops->store_subkeys_fn( key->name, subkeys ); 79 else 80 return False; 81 82} 83 84/*********************************************************************** 85 High level wrapper function for storing registry values 86 ***********************************************************************/ 87 88BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) 89{ 90 if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn ) 91 return key->hook->ops->store_values_fn( key->name, val ); 92 else 93 return False; 94} 95 96 97/*********************************************************************** 98 High level wrapper function for enumerating registry subkeys 99 Initialize the TALLOC_CTX if necessary 100 ***********************************************************************/ 101 102int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ) 103{ 104 int result = -1; 105 106 if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn ) 107 result = key->hook->ops->subkey_fn( key->name, subkey_ctr ); 108 109 return result; 110} 111 112/*********************************************************************** 113 retreive a specific subkey specified by index. Caller is 114 responsible for freeing memory 115 ***********************************************************************/ 116 117BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index ) 118{ 119 static REGSUBKEY_CTR ctr; 120 static pstring save_path; 121 static BOOL ctr_init = False; 122 char *s; 123 124 *subkey = NULL; 125 126 /* simple caching for performance; very basic heuristic */ 127 128 if ( !ctr_init ) { 129 DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name)); 130 ZERO_STRUCTP( &ctr ); 131 regsubkey_ctr_init( &ctr ); 132 133 pstrcpy( save_path, key->name ); 134 135 if ( fetch_reg_keys( key, &ctr) == -1 ) 136 return False; 137 138 ctr_init = True; 139 } 140 /* clear the cache when key_index == 0 or the path has changed */ 141 else if ( !key_index || StrCaseCmp( save_path, key->name) ) { 142 143 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name)); 144 145 regsubkey_ctr_destroy( &ctr ); 146 regsubkey_ctr_init( &ctr ); 147 148 pstrcpy( save_path, key->name ); 149 150 if ( fetch_reg_keys( key, &ctr) == -1 ) 151 return False; 152 } 153 154 if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) ) 155 return False; 156 157 *subkey = SMB_STRDUP( s ); 158 159 return True; 160} 161 162 163/*********************************************************************** 164 High level wrapper function for enumerating registry values 165 Initialize the TALLOC_CTX if necessary 166 ***********************************************************************/ 167 168int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) 169{ 170 int result = -1; 171 172 if ( key->hook && key->hook->ops && key->hook->ops->value_fn ) 173 result = key->hook->ops->value_fn( key->name, val ); 174 175 return result; 176} 177 178 179/*********************************************************************** 180 retreive a specific subkey specified by index. Caller is 181 responsible for freeing memory 182 ***********************************************************************/ 183 184BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index ) 185{ 186 static REGVAL_CTR ctr; 187 static pstring save_path; 188 static BOOL ctr_init = False; 189 REGISTRY_VALUE *v; 190 191 *val = NULL; 192 193 /* simple caching for performance; very basic heuristic */ 194 195 if ( !ctr_init ) { 196 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name)); 197 198 ZERO_STRUCTP( &ctr ); 199 regval_ctr_init( &ctr ); 200 201 pstrcpy( save_path, key->name ); 202 203 if ( fetch_reg_values( key, &ctr) == -1 ) 204 return False; 205 206 ctr_init = True; 207 } 208 /* clear the cache when val_index == 0 or the path has changed */ 209 else if ( !val_index || StrCaseCmp(save_path, key->name) ) { 210 211 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name)); 212 213 regval_ctr_destroy( &ctr ); 214 regval_ctr_init( &ctr ); 215 216 pstrcpy( save_path, key->name ); 217 218 if ( fetch_reg_values( key, &ctr) == -1 ) 219 return False; 220 } 221 222 if ( !(v = regval_ctr_specific_value( &ctr, val_index )) ) 223 return False; 224 225 *val = dup_registry_value( v ); 226 227 return True; 228} 229 230/*********************************************************************** 231 Utility function for splitting the base path of a registry path off 232 by setting base and new_path to the apprapriate offsets withing the 233 path. 234 235 WARNING!! Does modify the original string! 236 ***********************************************************************/ 237 238BOOL reg_split_path( char *path, char **base, char **new_path ) 239{ 240 char *p; 241 242 *new_path = *base = NULL; 243 244 if ( !path) 245 return False; 246 247 *base = path; 248 249 p = strchr( path, '\\' ); 250 251 if ( p ) { 252 *p = '\0'; 253 *new_path = p+1; 254 } 255 256 return True; 257} 258 259 260 261