X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba.git;a=blobdiff_plain;f=source3%2Fregistry%2Freg_eventlog.c;h=6bedf4635ebdc536a2db80cae9693f56b1b5ed4a;hp=ccac7a190edf98bac0ea55805d24d2089f8b9c1f;hb=0fe1ff99a1aa6858ec0f1cfb1130b801238fc8e2;hpb=2e0cac8e3eb021aa8f5cad4ce8b72f98036af639 diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c index ccac7a190ed..6bedf4635eb 100644 --- a/source3/registry/reg_eventlog.c +++ b/source3/registry/reg_eventlog.c @@ -1,11 +1,14 @@ + /* * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Marcin Krzysztof Porwit 2005. + * Virtual Windows Registry Layer + * Copyright (C) Marcin Krzysztof Porwit 2005, + * Copyright (C) Brian Moran 2005. + * Copyright (C) Gerald (Jerry) Carter 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,289 +17,371 @@ * 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. + * along with this program; if not, see . */ - + #include "includes.h" +#include "registry.h" +#include "reg_backend_db.h" +#include "reg_eventlog.h" +#include "reg_objects.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY /********************************************************************** - handle enumeration of values AT KEY_EVENTLOG - *********************************************************************/ - -static int eventlog_topkey_values( char *key, REGVAL_CTR *val ) + for an eventlog, add in the default values +*********************************************************************/ + +bool eventlog_init_keys(void) { - int num_values = 0; - char *keystr, *key2 = NULL; - char *base, *new_path; - fstring evtlogname; - UNISTR2 data; - int iDisplayNameId; - int iMaxSize; - - /* - * TODO - callout to get these values... - */ - - if ( key ) - { - key2 = SMB_STRDUP( key ); - keystr = key2; - reg_split_path( keystr, &base, &new_path ); - - iDisplayNameId = 0x00000100; - iMaxSize= 0x00080000; - - fstrcpy( evtlogname, base ); - DEBUG(10,("eventlog_topkey_values: subkey root=> [%s] subkey path=>[%s]\n", base,new_path)); - - if ( !new_path ) - { - iDisplayNameId = 0x01; - regval_ctr_addvalue( val, "ErrorControl", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) ); - - init_unistr2( &data, "EventLog", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "DisplayName", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - num_values = regval_ctr_numvals( val ); - - - num_values = 0; + /* Find all of the eventlogs, add keys for each of them */ + const char **elogs = lp_eventlog_list(); + char *evtlogpath = NULL; + char *evtfilepath = NULL; + struct regsubkey_ctr *subkeys; + struct regval_ctr *values; + uint32 uiMaxSize; + uint32 uiRetention; + uint32 uiCategoryCount; + DATA_BLOB data; + TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; + + while (elogs && *elogs) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + regdb_fetch_keys(KEY_EVENTLOG, subkeys); + regsubkey_ctr_addkey( subkeys, *elogs ); + if ( !regdb_store_keys( KEY_EVENTLOG, subkeys ) ) { + TALLOC_FREE(subkeys); + return False; + } + TALLOC_FREE(subkeys); + + /* add in the key of form KEY_EVENTLOG/Application */ + DEBUG( 5, + ( "Adding key of [%s] to path of [%s]\n", *elogs, + KEY_EVENTLOG ) ); + + evtlogpath = talloc_asprintf(ctx, "%s\\%s", + KEY_EVENTLOG, *elogs); + if (!evtlogpath) { + return false; + } + /* add in the key of form KEY_EVENTLOG/Application/Application */ + DEBUG( 5, + ( "Adding key of [%s] to path of [%s]\n", *elogs, + evtlogpath ) ); + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + regdb_fetch_keys( evtlogpath, subkeys ); + regsubkey_ctr_addkey( subkeys, *elogs ); + + if ( !regdb_store_keys( evtlogpath, subkeys ) ) { + TALLOC_FREE(subkeys); + return False; + } + TALLOC_FREE( subkeys ); + + /* now add the values to the KEY_EVENTLOG/Application form key */ + + werr = regval_ctr_init(ctx, &values); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + DEBUG( 5, + ( "Storing values to eventlog path of [%s]\n", + evtlogpath ) ); + regdb_fetch_values( evtlogpath, values ); + + + if (!regval_ctr_key_exists(values, "MaxSize")) { + + /* assume we have none, add them all */ + + /* hard code some initial values */ + + /* uiDisplayNameId = 0x00000100; */ + uiMaxSize = 0x00080000; + uiRetention = 0x93A80; + + regval_ctr_addvalue(values, "MaxSize", REG_DWORD, + (uint8 *)&uiMaxSize, + sizeof(uint32)); + + regval_ctr_addvalue(values, "Retention", REG_DWORD, + (uint8 *)&uiRetention, + sizeof(uint32)); + + regval_ctr_addvalue_sz(values, "PrimaryModule", *elogs); + push_reg_sz(talloc_tos(), &data, *elogs); + + regval_ctr_addvalue(values, "Sources", REG_MULTI_SZ, + data.data, + data.length); + + evtfilepath = talloc_asprintf(ctx, + "%%SystemRoot%%\\system32\\config\\%s.tdb", + *elogs); + if (!evtfilepath) { + TALLOC_FREE(values); + } + push_reg_sz(talloc_tos(), &data, evtfilepath); + regval_ctr_addvalue(values, "File", REG_EXPAND_SZ, data.data, + data.length); + regdb_store_values(evtlogpath, values); + + } + + TALLOC_FREE(values); + + /* now do the values under KEY_EVENTLOG/Application/Application */ + TALLOC_FREE(evtlogpath); + evtlogpath = talloc_asprintf(ctx, "%s\\%s\\%s", + KEY_EVENTLOG, *elogs, *elogs); + if (!evtlogpath) { + return false; + } + + werr = regval_ctr_init(ctx, &values); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + DEBUG( 5, + ( "Storing values to eventlog path of [%s]\n", + evtlogpath)); + regdb_fetch_values(evtlogpath, values); + if (!regval_ctr_key_exists( values, "CategoryCount")) { + + /* hard code some initial values */ + + uiCategoryCount = 0x00000007; + regval_ctr_addvalue( values, "CategoryCount", + REG_DWORD, + (uint8 *) &uiCategoryCount, + sizeof( uint32 ) ); + push_reg_sz(talloc_tos(), &data, + "%SystemRoot%\\system32\\eventlog.dll"); + + regval_ctr_addvalue( values, "CategoryMessageFile", + REG_EXPAND_SZ, + data.data, + data.length); + regdb_store_values( evtlogpath, values ); + } + TALLOC_FREE(values); + elogs++; } - } - - SAFE_FREE( key2 ); - return num_values; -} -/********************************************************************** - handle enumeration of values below KEY_EVENTLOG\ - *********************************************************************/ - -static int eventlog_subkey_values( char *key, REGVAL_CTR *val ) -{ - int num_values = 0; - char *keystr, *key2 = NULL; - char *base, *new_path; - fstring evtlogname; - UNISTR2 data; - int iDisplayNameId; - int iMaxSize; - int iRetention; - - /* - * TODO - callout to get these values... - */ - - if ( !key ) - return num_values; - - key2 = SMB_STRDUP( key ); - keystr = key2; - reg_split_path( keystr, &base, &new_path ); - - iDisplayNameId = 0x00000100; - /* MaxSize is limited to 0xFFFF0000 (UINT_MAX - USHRT_MAX) as per MSDN documentation */ - iMaxSize= 0xFFFF0000; - /* records in the samba log are not overwritten */ - iRetention = 0xFFFFFFFF; - - fstrcpy( evtlogname, base ); - DEBUG(10,("eventlog_subpath_values_printer: eventlogname [%s]\n", base)); - DEBUG(10,("eventlog_subpath_values_printer: new_path [%s]\n", new_path)); - if ( !new_path ) - { -#if 0 - regval_ctr_addvalue( val, "DisplayNameId", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) ); - - init_unistr2( &data, "%SystemRoot%\\system32\\els.dll", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "DisplayNameFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); -#endif - regval_ctr_addvalue( val, "MaxSize", REG_DWORD, (char*)&iMaxSize, sizeof(int)); - regval_ctr_addvalue( val, "Retention", REG_DWORD, (char *)&iRetention, sizeof(int)); -#if 0 - init_unistr2( &data, lp_logfile(), UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "File", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); -#endif - init_unistr2( &data, base, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "PrimaryModule", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, base, UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "Sources", REG_MULTI_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - num_values = regval_ctr_numvals( val ); - - } - else - { - iDisplayNameId = 0x07; - regval_ctr_addvalue( val, "CategoryCount", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) ); - - init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE); - regval_ctr_addvalue( val, "CategoryMessageFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - num_values = regval_ctr_numvals( val ); - - num_values = 0; - } - - SAFE_FREE( key2 ); - return num_values; + return true; } +/********************************************************************* + for an eventlog, add in a source name. If the eventlog doesn't + exist (not in the list) do nothing. If a source for the log + already exists, change the information (remove, replace) +*********************************************************************/ -/********************************************************************** - It is safe to assume that every registry path passed into on of - the exported functions here begins with KEY_EVENTLOG 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_eventlog_reg_path( char *path ) +bool eventlog_add_source( const char *eventlog, const char *sourcename, + const char *messagefile ) { - char *p; - uint16 key_len = strlen(KEY_EVENTLOG); - - /* - * sanity check...this really should never be True. - * It is only here to prevent us from accessing outside - * the path buffer in the extreme case. - */ - - if ( strlen(path) < key_len ) { - DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path)); - DEBUG(0,("trim_reg_path: KEY_EVENTLOG => [%s]!\n", KEY_EVENTLOG)); - return NULL; + /* Find all of the eventlogs, add keys for each of them */ + /* need to add to the value KEY_EVENTLOG//Sources string (Creating if necessary) + need to add KEY of source to KEY_EVENTLOG// */ + + const char **elogs = lp_eventlog_list( ); + const char **wrklist, **wp; + char *evtlogpath = NULL; + struct regsubkey_ctr *subkeys; + struct regval_ctr *values; + struct regval_blob *rval; + int ii = 0; + bool already_in; + int i; + int numsources = 0; + TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; + DATA_BLOB blob; + + if (!elogs) { + return False; } - - - p = path + strlen( KEY_EVENTLOG ); - - if ( *p == '\\' ) - p++; - - if ( *p ) - return SMB_STRDUP(p); - else - return NULL; -} -/********************************************************************** - Enumerate registry subkey names given a registry path. - Caller is responsible for freeing memory to **subkeys - *********************************************************************/ -int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr ) -{ - char *path; - BOOL top_level = False; - int num_subkeys = 0; - const char **evtlog_list; - - path = trim_eventlog_reg_path( key ); - DEBUG(10,("eventlog_subkey_info: entire key=>[%s] SUBkey=>[%s]\n", key,path)); - - /* check to see if we are dealing with the top level key */ - num_subkeys = 0; - - if ( !path ) - top_level = True; - - evtlog_list = lp_eventlog_list(); - num_subkeys = 0; - - if ( top_level ) - { - /* todo - get the eventlog subkey values from the smb.conf file - for ( num_subkeys=0; num_subkeys[%s]\n",*evtlog_list)); - regsubkey_ctr_addkey( subkey_ctr, *evtlog_list); - evtlog_list++; - num_subkeys++; + + for ( i = 0; elogs[i]; i++ ) { + if ( strequal( elogs[i], eventlog ) ) + break; } - } - else - { - while (*evtlog_list && (0==num_subkeys) ) - { - if (0 == StrCaseCmp(path,*evtlog_list)) - { - DEBUG(10,("eventlog_subkey_info: Adding subkey [%s] for key =>[%s]\n",path,*evtlog_list)); - regsubkey_ctr_addkey( subkey_ctr, *evtlog_list); - num_subkeys = 1; - } - evtlog_list++; + + if ( !elogs[i] ) { + DEBUG( 0, + ( "Eventlog [%s] not found in list of valid event logs\n", + eventlog ) ); + return false; /* invalid named passed in */ } - - if (0==num_subkeys) - DEBUG(10,("eventlog_subkey_info: No match on SUBkey=>[%s]\n", path)); - } - - SAFE_FREE( path ); - return num_subkeys; -} -/********************************************************************** - Enumerate registry values given a registry path. - Caller is responsible for freeing memory - *********************************************************************/ + /* have to assume that the evenlog key itself exists at this point */ + /* add in a key of [sourcename] under the eventlog key */ -int eventlog_value_info( char *key, REGVAL_CTR *val ) -{ - char *path; - BOOL top_level = False; - int num_values = 0; - - DEBUG(10,("eventlog_value_info: key=>[%s]\n", key)); - - path = trim_eventlog_reg_path( key ); - - /* check to see if we are dealing with the top level key */ - - if ( !path ) - top_level = True; - if ( top_level ) - num_values = eventlog_topkey_values(path,val); - else - { - DEBUG(10,("eventlog_value_info: SUBkey=>[%s]\n", path)); - num_values = eventlog_subkey_values(path,val); + /* todo add to Sources */ + + werr = regval_ctr_init(ctx, &values); + if(!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" )); + return false; } - return num_values; -} -/********************************************************************** - Stub function which always returns failure since we don't want - people storing eventlog information directly via registry calls - (for now at least) - *********************************************************************/ -BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys ) -{ - return False; -} + evtlogpath = talloc_asprintf(ctx, "%s\\%s", KEY_EVENTLOG, eventlog); + if (!evtlogpath) { + TALLOC_FREE(values); + return false; + } -/********************************************************************** - Stub function which always returns failure since we don't want - people storing eventlog information directly via registry calls - (for now at least) - *********************************************************************/ -BOOL eventlog_store_value( char *key, REGVAL_CTR *val ) -{ - return False; -} + regdb_fetch_values( evtlogpath, values ); -/* - * Table of function pointers for accessing eventlog data - */ -REGISTRY_OPS eventlog_ops = { - eventlog_subkey_info, - eventlog_value_info, - eventlog_store_subkey, - eventlog_store_value -}; + + if ( !( rval = regval_ctr_getvalue( values, "Sources" ) ) ) { + DEBUG( 0, ( "No Sources value for [%s]!\n", eventlog ) ); + return False; + } + /* perhaps this adding a new string to a multi_sz should be a fn? */ + /* check to see if it's there already */ + + if ( regval_type(rval) != REG_MULTI_SZ ) { + DEBUG( 0, + ( "Wrong type for Sources, should be REG_MULTI_SZ\n" ) ); + return False; + } + /* convert to a 'regulah' chars to do some comparisons */ + + already_in = False; + wrklist = NULL; + dump_data(1, regval_data_p(rval), regval_size(rval)); + + blob = data_blob_const(regval_data_p(rval), regval_size(rval)); + if (!pull_reg_multi_sz(talloc_tos(), &blob, &wrklist)) { + return false; + } + + for (ii=0; wrklist[ii]; ii++) { + numsources++; + } + + if (numsources > 0) { + /* see if it's in there already */ + wp = wrklist; + + while (wp && *wp ) { + if ( strequal( *wp, sourcename ) ) { + DEBUG( 5, + ( "Source name [%s] already in list for [%s] \n", + sourcename, eventlog ) ); + already_in = True; + break; + } + wp++; + } + } else { + DEBUG( 3, + ( "Nothing in the sources list, this might be a problem\n" ) ); + } + + wp = wrklist; + + if ( !already_in ) { + /* make a new list with an additional entry; copy values, add another */ + wp = TALLOC_ARRAY(ctx, const char *, numsources + 2 ); + + if ( !wp ) { + DEBUG( 0, ( "talloc() failed \n" ) ); + return False; + } + memcpy( wp, wrklist, sizeof( char * ) * numsources ); + *( wp + numsources ) = ( char * ) sourcename; + *( wp + numsources + 1 ) = NULL; + if (!push_reg_multi_sz(ctx, &blob, wp)) { + return false; + } + dump_data( 1, blob.data, blob.length); + regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ, + blob.data, blob.length); + regdb_store_values( evtlogpath, values ); + data_blob_free(&blob); + } else { + DEBUG( 3, + ( "Source name [%s] found in existing list of sources\n", + sourcename ) ); + } + TALLOC_FREE(values); + TALLOC_FREE(wrklist); /* */ + + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + TALLOC_FREE(evtlogpath); + evtlogpath = talloc_asprintf(ctx, "%s\\%s", KEY_EVENTLOG, eventlog ); + if (!evtlogpath) { + TALLOC_FREE(subkeys); + return false; + } + + regdb_fetch_keys( evtlogpath, subkeys ); + + if ( !regsubkey_ctr_key_exists( subkeys, sourcename ) ) { + DEBUG( 5, + ( " Source name [%s] for eventlog [%s] didn't exist, adding \n", + sourcename, eventlog ) ); + regsubkey_ctr_addkey( subkeys, sourcename ); + if ( !regdb_store_keys( evtlogpath, subkeys ) ) + return False; + } + TALLOC_FREE(subkeys); + + /* at this point KEY_EVENTLOG// key is in there. Now need to add EventMessageFile */ + + /* now allocate room for the source's subkeys */ + + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + TALLOC_FREE(evtlogpath); + evtlogpath = talloc_asprintf(ctx, "%s\\%s\\%s", + KEY_EVENTLOG, eventlog, sourcename); + if (!evtlogpath) { + TALLOC_FREE(subkeys); + return false; + } + + regdb_fetch_keys( evtlogpath, subkeys ); + + /* now add the values to the KEY_EVENTLOG/Application form key */ + werr = regval_ctr_init(ctx, &values); + if (!W_ERROR_IS_OK(werr)) { + DEBUG( 0, ( "talloc() failure!\n" ) ); + return False; + } + DEBUG( 5, + ( "Storing EventMessageFile [%s] to eventlog path of [%s]\n", + messagefile, evtlogpath ) ); + + regdb_fetch_values( evtlogpath, values ); + + regval_ctr_addvalue_sz(values, "EventMessageFile", messagefile); + regdb_store_values( evtlogpath, values ); + + TALLOC_FREE(values); + + return True; +}