2009-01-15 22:01:30 +03:00
/*
2005-10-06 21:48:03 +04:00
* Unix SMB / CIFS implementation .
* Eventlog utility routines
* Copyright ( C ) Marcin Krzysztof Porwit 2005 ,
2005-10-14 20:07:00 +04:00
* Copyright ( C ) Brian Moran 2005.
2005-10-06 21:48:03 +04:00
* Copyright ( C ) Gerald ( Jerry ) Carter 2005.
2009-01-16 14:48:11 +03:00
* Copyright ( C ) Guenther Deschner 2009.
2009-01-15 22:01:30 +03:00
*
2005-10-06 21:48:03 +04:00
* 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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2005-10-06 21:48:03 +04:00
* ( at your option ) any later version .
2009-01-15 22:01:30 +03:00
*
2005-10-06 21:48:03 +04:00
* 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 .
2009-01-15 22:01:30 +03:00
*
2005-10-06 21:48:03 +04:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2005-10-06 21:48:03 +04:00
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-05-06 13:42:52 +04:00
# include "lib/eventlog/eventlog.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-05-05 13:25:29 +04:00
# include "util_tdb.h"
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
/* maintain a list of open eventlog tdbs with reference counts */
2005-10-06 21:48:03 +04:00
2005-11-17 23:08:59 +03:00
static ELOG_TDB * open_elog_list ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
/********************************************************************
2009-01-15 22:01:30 +03:00
Init an Eventlog TDB , and return it . If null , something bad
2005-10-14 20:07:00 +04:00
happened .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
TDB_CONTEXT * elog_init_tdb ( char * tdbfilename )
2005-10-06 21:48:03 +04:00
{
2005-10-14 20:07:00 +04:00
TDB_CONTEXT * tdb ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
DEBUG ( 10 , ( " elog_init_tdb: Initializing eventlog tdb (%s) \n " ,
tdbfilename ) ) ;
2005-10-06 21:48:03 +04:00
2009-01-15 22:01:30 +03:00
tdb = tdb_open_log ( tdbfilename , 0 , TDB_DEFAULT ,
2006-05-01 22:54:53 +04:00
O_RDWR | O_CREAT | O_TRUNC , 0660 ) ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
if ( ! tdb ) {
DEBUG ( 0 , ( " Can't open tdb for [%s] \n " , tdbfilename ) ) ;
2005-10-06 21:48:03 +04:00
return NULL ;
}
2005-10-14 20:07:00 +04:00
/* initialize with defaults, copy real values in here from registry */
tdb_store_int32 ( tdb , EVT_OLDEST_ENTRY , 1 ) ;
tdb_store_int32 ( tdb , EVT_NEXT_RECORD , 1 ) ;
tdb_store_int32 ( tdb , EVT_MAXSIZE , 0x80000 ) ;
tdb_store_int32 ( tdb , EVT_RETENTION , 0x93A80 ) ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
tdb_store_int32 ( tdb , EVT_VERSION , EVENTLOG_DATABASE_VERSION_V1 ) ;
return tdb ;
2005-10-06 21:48:03 +04:00
}
2005-10-14 20:07:00 +04:00
/********************************************************************
2009-01-15 22:01:30 +03:00
make the tdb file name for an event log , given destination buffer
2005-10-14 20:07:00 +04:00
and size . Caller must free memory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-27 22:22:58 +03:00
char * elog_tdbname ( TALLOC_CTX * ctx , const char * name )
2005-10-14 20:07:00 +04:00
{
2010-03-18 01:16:53 +03:00
char * path ;
char * file ;
char * tdbname ;
2018-08-16 11:51:44 +03:00
path = state_path ( talloc_tos ( ) , " eventlog " ) ;
2007-11-27 22:22:58 +03:00
if ( ! path ) {
return NULL ;
}
2010-03-18 01:16:53 +03:00
file = talloc_asprintf_strlower_m ( path , " %s.tdb " , name ) ;
if ( ! file ) {
talloc_free ( path ) ;
return NULL ;
}
2014-11-02 22:21:24 +03:00
tdbname = talloc_asprintf ( ctx , " %s/%s " , path , file ) ;
2010-03-18 01:16:53 +03:00
if ( ! tdbname ) {
talloc_free ( path ) ;
return NULL ;
}
2014-11-06 13:32:45 +03:00
talloc_free ( path ) ;
2010-03-18 01:16:53 +03:00
return tdbname ;
2005-10-14 20:07:00 +04:00
}
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
/********************************************************************
2009-01-15 22:01:30 +03:00
this function is used to count up the number of bytes in a
2005-10-14 20:07:00 +04:00
particular TDB
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
struct trav_size_struct {
int size ;
int rec_count ;
} ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
static int eventlog_tdb_size_fn ( TDB_CONTEXT * tdb , TDB_DATA key , TDB_DATA data ,
2005-10-06 21:48:03 +04:00
void * state )
{
2006-07-30 20:36:56 +04:00
struct trav_size_struct * tsize = ( struct trav_size_struct * ) state ;
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
tsize - > size + = data . dsize ;
tsize - > rec_count + + ;
2009-01-15 22:01:30 +03:00
2005-10-06 21:48:03 +04:00
return 0 ;
}
2005-10-14 20:07:00 +04:00
/********************************************************************
2009-01-15 22:01:30 +03:00
returns the size of the eventlog , and if MaxSize is a non - null
ptr , puts the MaxSize there . This is purely a way not to have yet
another function that solely reads the maxsize of the eventlog .
2005-10-14 20:07:00 +04:00
Yeah , that ' s it .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
int elog_tdb_size ( TDB_CONTEXT * tdb , int * MaxSize , int * Retention )
2005-10-06 21:48:03 +04:00
{
2005-10-14 20:07:00 +04:00
struct trav_size_struct tsize ;
2009-01-15 22:01:30 +03:00
2005-10-06 21:48:03 +04:00
if ( ! tdb )
return 0 ;
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
ZERO_STRUCT ( tsize ) ;
2005-10-06 21:48:03 +04:00
2005-10-14 20:07:00 +04:00
tdb_traverse ( tdb , eventlog_tdb_size_fn , & tsize ) ;
2005-10-06 21:48:03 +04:00
if ( MaxSize ! = NULL ) {
2005-10-14 20:07:00 +04:00
* MaxSize = tdb_fetch_int32 ( tdb , EVT_MAXSIZE ) ;
2005-10-06 21:48:03 +04:00
}
if ( Retention ! = NULL ) {
2005-10-14 20:07:00 +04:00
* Retention = tdb_fetch_int32 ( tdb , EVT_RETENTION ) ;
2005-10-06 21:48:03 +04:00
}
DEBUG ( 1 ,
2005-10-14 20:07:00 +04:00
( " eventlog size: [%d] for [%d] records \n " , tsize . size ,
tsize . rec_count ) ) ;
return tsize . size ;
2005-10-06 21:48:03 +04:00
}
2005-10-14 20:07:00 +04:00
/********************************************************************
Discard early event logs until we have enough for ' needed ' bytes . . .
2009-01-15 22:01:30 +03:00
NO checking done beforehand to see that we actually need to do
this , and it ' s going to pluck records one - by - one . So , it ' s best
to determine that this needs to be done before doing it .
2005-10-14 20:07:00 +04:00
2009-01-15 22:01:30 +03:00
Setting whack_by_date to True indicates that eventlogs falling
2005-10-14 20:07:00 +04:00
outside of the retention range need to go . . .
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
return True if we made enough room to accommodate needed bytes
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
2008-11-20 03:49:03 +03:00
static bool make_way_for_eventlogs ( TDB_CONTEXT * the_tdb , int32_t needed ,
2008-01-30 00:08:37 +03:00
bool whack_by_date )
2005-10-06 21:48:03 +04:00
{
2008-11-20 03:49:03 +03:00
int32_t start_record , i , new_start ;
int32_t end_record ;
int32_t reclen , tresv1 , trecnum , timegen , timewr ;
int nbytes , len , Retention , MaxSize ;
2005-10-06 21:48:03 +04:00
TDB_DATA key , ret ;
time_t current_time , exp_time ;
/* discard some eventlogs */
/* read eventlogs from oldest_entry -- there can't be any discontinuity in recnos,
although records not necessarily guaranteed to have successive times */
/* */
/* lock */
2006-04-17 15:49:06 +04:00
tdb_lock_bystring_with_timeout ( the_tdb , EVT_NEXT_RECORD , 1 ) ;
2005-10-06 21:48:03 +04:00
/* read */
2005-10-14 20:07:00 +04:00
end_record = tdb_fetch_int32 ( the_tdb , EVT_NEXT_RECORD ) ;
start_record = tdb_fetch_int32 ( the_tdb , EVT_OLDEST_ENTRY ) ;
Retention = tdb_fetch_int32 ( the_tdb , EVT_RETENTION ) ;
MaxSize = tdb_fetch_int32 ( the_tdb , EVT_MAXSIZE ) ;
2005-10-06 21:48:03 +04:00
time ( & current_time ) ;
/* calculate ... */
exp_time = current_time - Retention ; /* discard older than exp_time */
/* todo - check for sanity in next_record */
nbytes = 0 ;
DEBUG ( 3 ,
2008-11-20 03:49:03 +03:00
( " MaxSize [%d] Retention [%d] Current Time [%u] exp_time [%u] \n " ,
MaxSize , Retention , ( unsigned int ) current_time , ( unsigned int ) exp_time ) ) ;
2005-10-06 21:48:03 +04:00
DEBUG ( 3 ,
2008-11-20 03:49:03 +03:00
( " Start Record [%u] End Record [%u] \n " ,
( unsigned int ) start_record ,
( unsigned int ) end_record ) ) ;
2005-10-06 21:48:03 +04:00
for ( i = start_record ; i < end_record ; i + + ) {
/* read a record, add the amt to nbytes */
2008-11-20 03:49:03 +03:00
key . dsize = sizeof ( int32_t ) ;
key . dptr = ( unsigned char * ) & i ;
2015-03-12 17:23:17 +03:00
ret = tdb_fetch ( the_tdb , key ) ;
2005-10-06 21:48:03 +04:00
if ( ret . dsize = = 0 ) {
DEBUG ( 8 ,
( " Can't find a record for the key, record [%d] \n " ,
i ) ) ;
2005-10-14 20:07:00 +04:00
tdb_unlock_bystring ( the_tdb , EVT_NEXT_RECORD ) ;
2005-10-06 21:48:03 +04:00
return False ;
}
nbytes + = ret . dsize ; /* note this includes overhead */
len = tdb_unpack ( ret . dptr , ret . dsize , " ddddd " , & reclen ,
& tresv1 , & trecnum , & timegen , & timewr ) ;
2006-06-27 04:42:24 +04:00
if ( len = = - 1 ) {
DEBUG ( 10 , ( " make_way_for_eventlogs: tdb_unpack failed. \n " ) ) ;
tdb_unlock_bystring ( the_tdb , EVT_NEXT_RECORD ) ;
2008-11-20 03:49:03 +03:00
SAFE_FREE ( ret . dptr ) ;
2006-06-27 04:42:24 +04:00
return False ;
}
2005-10-06 21:48:03 +04:00
DEBUG ( 8 ,
2008-11-20 03:49:03 +03:00
( " read record %u, record size is [%d], total so far [%d] \n " ,
( unsigned int ) i , reclen , nbytes ) ) ;
2005-10-06 21:48:03 +04:00
SAFE_FREE ( ret . dptr ) ;
/* note that other servers may just stop writing records when the size limit
2009-01-15 22:01:30 +03:00
is reached , and there are no records older than ' retention ' . This doesn ' t
like a very useful thing to do , so instead we whack ( as in sleeps with the
2005-10-06 21:48:03 +04:00
fishes ) just enough records to fit the what we need . This behavior could
be changed to ' match ' , if the need arises . */
if ( ! whack_by_date & & ( nbytes > = needed ) )
break ; /* done */
if ( whack_by_date & & ( timegen > = exp_time ) )
break ; /* done */
}
DEBUG ( 3 ,
2008-11-20 03:49:03 +03:00
( " nbytes [%d] needed [%d] start_record is [%u], should be set to [%u] \n " ,
nbytes , needed , ( unsigned int ) start_record , ( unsigned int ) i ) ) ;
2005-10-06 21:48:03 +04:00
/* todo - remove eventlog entries here and set starting record to start_record... */
new_start = i ;
if ( start_record ! = new_start ) {
for ( i = start_record ; i < new_start ; i + + ) {
2008-11-20 03:49:03 +03:00
key . dsize = sizeof ( int32_t ) ;
key . dptr = ( unsigned char * ) & i ;
2005-10-06 21:48:03 +04:00
tdb_delete ( the_tdb , key ) ;
}
2005-10-14 20:07:00 +04:00
tdb_store_int32 ( the_tdb , EVT_OLDEST_ENTRY , new_start ) ;
2005-10-06 21:48:03 +04:00
}
2005-10-14 20:07:00 +04:00
tdb_unlock_bystring ( the_tdb , EVT_NEXT_RECORD ) ;
2005-10-06 21:48:03 +04:00
return True ;
}
2005-10-14 20:07:00 +04:00
/********************************************************************
2009-01-15 22:01:30 +03:00
some hygiene for an eventlog - see how big it is , and then
calculate how many bytes we need to remove
2005-10-14 20:07:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
2007-10-19 04:40:25 +04:00
bool prune_eventlog ( TDB_CONTEXT * tdb )
2005-10-06 21:48:03 +04:00
{
int MaxSize , Retention , CalcdSize ;
if ( ! tdb ) {
DEBUG ( 4 , ( " No eventlog tdb handle \n " ) ) ;
return False ;
}
2005-10-14 20:07:00 +04:00
CalcdSize = elog_tdb_size ( tdb , & MaxSize , & Retention ) ;
2005-10-06 21:48:03 +04:00
DEBUG ( 3 ,
( " Calculated size [%d] MaxSize [%d] \n " , CalcdSize ,
MaxSize ) ) ;
if ( CalcdSize > MaxSize ) {
return make_way_for_eventlogs ( tdb , CalcdSize - MaxSize ,
False ) ;
}
return make_way_for_eventlogs ( tdb , 0 , True ) ;
}
2005-10-14 20:07:00 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-03 22:48:43 +03:00
static bool can_write_to_eventlog ( TDB_CONTEXT * tdb , int32_t needed )
2005-10-06 21:48:03 +04:00
{
int calcd_size ;
int MaxSize , Retention ;
/* see if we can write to the eventlog -- do a policy enforcement */
if ( ! tdb )
return False ; /* tdb is null, so we can't write to it */
if ( needed < 0 )
return False ;
MaxSize = 0 ;
Retention = 0 ;
2005-10-14 20:07:00 +04:00
calcd_size = elog_tdb_size ( tdb , & MaxSize , & Retention ) ;
2005-10-06 21:48:03 +04:00
if ( calcd_size < = MaxSize )
return True ; /* you betcha */
if ( calcd_size + needed < MaxSize )
return True ;
if ( Retention = = 0xffffffff ) {
return False ; /* see msdn - we can't write no room, discard */
}
/*
note don ' t have to test , but always good to show intent , in case changes needed
later
*/
if ( Retention = = 0x00000000 ) {
/* discard record(s) */
/* todo - decide when to remove a bunch vs. just what we need... */
return make_way_for_eventlogs ( tdb , calcd_size - MaxSize ,
True ) ;
}
return make_way_for_eventlogs ( tdb , calcd_size - MaxSize , False ) ;
}
2005-10-14 20:07:00 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-02 16:00:01 +03:00
ELOG_TDB * elog_open_tdb ( const char * logname , bool force_clear , bool read_only )
2005-10-14 20:07:00 +04:00
{
2005-11-17 23:08:59 +03:00
TDB_CONTEXT * tdb = NULL ;
2008-11-20 03:49:03 +03:00
uint32_t vers_id ;
2005-11-17 23:08:59 +03:00
ELOG_TDB * ptr ;
2007-11-27 22:22:58 +03:00
char * tdbpath = NULL ;
2005-11-17 23:08:59 +03:00
ELOG_TDB * tdb_node = NULL ;
2005-10-14 20:07:00 +04:00
char * eventlogdir ;
2007-11-27 22:22:58 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2012-12-13 20:50:55 +04:00
bool ok ;
2005-10-14 20:07:00 +04:00
2009-01-22 21:46:14 +03:00
/* check for invalid options */
if ( force_clear & & read_only ) {
DEBUG ( 1 , ( " elog_open_tdb: Invalid flags \n " ) ) ;
return NULL ;
}
2005-10-14 20:07:00 +04:00
/* first see if we have an open context */
2007-11-27 22:22:58 +03:00
2005-10-14 20:07:00 +04:00
for ( ptr = open_elog_list ; ptr ; ptr = ptr - > next ) {
if ( strequal ( ptr - > name , logname ) ) {
ptr - > ref_count + + ;
2005-11-17 23:08:59 +03:00
2023-07-05 12:16:18 +03:00
/* trick to allow clearing of the eventlog tdb.
2005-11-17 23:08:59 +03:00
The force_clear flag should imply that someone
2009-01-15 22:01:30 +03:00
has done a force close . So make sure the tdb
is NULL . If this is a normal open , then just
2005-11-17 23:08:59 +03:00
return the existing reference */
if ( force_clear ) {
SMB_ASSERT ( ptr - > tdb = = NULL ) ;
break ;
}
else
return ptr ;
2005-10-14 20:07:00 +04:00
}
}
2007-11-27 22:22:58 +03:00
2005-10-14 20:07:00 +04:00
/* make sure that the eventlog dir exists */
2007-11-27 22:22:58 +03:00
2018-08-16 11:51:44 +03:00
eventlogdir = state_path ( talloc_tos ( ) , " eventlog " ) ;
2014-11-02 22:21:24 +03:00
if ( eventlogdir = = NULL ) {
return NULL ;
}
2014-07-27 21:18:09 +04:00
ok = directory_create_or_exist ( eventlogdir , 0755 ) ;
2014-11-02 22:21:24 +03:00
TALLOC_FREE ( eventlogdir ) ;
2012-12-13 20:50:55 +04:00
if ( ! ok ) {
return NULL ;
}
2007-11-27 22:22:58 +03:00
2005-10-14 20:07:00 +04:00
/* get the path on disk */
2007-11-27 22:22:58 +03:00
tdbpath = elog_tdbname ( ctx , logname ) ;
if ( ! tdbpath ) {
return NULL ;
}
DEBUG ( 7 , ( " elog_open_tdb: Opening %s...(force_clear == %s) \n " ,
2005-11-17 23:08:59 +03:00
tdbpath , force_clear ? " True " : " False " ) ) ;
2007-11-27 22:22:58 +03:00
2005-11-17 23:08:59 +03:00
/* the tdb wasn't already open or this is a forced clear open */
2005-10-14 20:07:00 +04:00
2005-11-17 23:08:59 +03:00
if ( ! force_clear ) {
2005-10-14 20:07:00 +04:00
2009-01-22 21:46:14 +03:00
tdb = tdb_open_log ( tdbpath , 0 , TDB_DEFAULT , read_only ? O_RDONLY : O_RDWR , 0 ) ;
2005-11-17 23:08:59 +03:00
if ( tdb ) {
vers_id = tdb_fetch_int32 ( tdb , EVT_VERSION ) ;
if ( vers_id ! = EVENTLOG_DATABASE_VERSION_V1 ) {
DEBUG ( 1 , ( " elog_open_tdb: Invalid version [%d] on file [%s]. \n " ,
vers_id , tdbpath ) ) ;
tdb_close ( tdb ) ;
tdb = elog_init_tdb ( tdbpath ) ;
}
2005-10-14 20:07:00 +04:00
}
}
2009-01-15 22:01:30 +03:00
2005-11-17 23:08:59 +03:00
if ( ! tdb )
2005-10-14 20:07:00 +04:00
tdb = elog_init_tdb ( tdbpath ) ;
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
/* if we got a valid context, then add it to the list */
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
if ( tdb ) {
2005-11-17 23:08:59 +03:00
/* on a forced clear, just reset the tdb context if we already
have an open entry in the list */
if ( ptr ) {
ptr - > tdb = tdb ;
return ptr ;
}
2011-06-07 05:44:43 +04:00
if ( ! ( tdb_node = talloc_zero ( NULL , ELOG_TDB ) ) ) {
2005-10-14 20:07:00 +04:00
DEBUG ( 0 , ( " elog_open_tdb: talloc() failure! \n " ) ) ;
tdb_close ( tdb ) ;
return NULL ;
}
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
tdb_node - > name = talloc_strdup ( tdb_node , logname ) ;
tdb_node - > tdb = tdb ;
tdb_node - > ref_count = 1 ;
2009-01-15 22:01:30 +03:00
2005-10-14 20:07:00 +04:00
DLIST_ADD ( open_elog_list , tdb_node ) ;
}
2005-11-17 23:08:59 +03:00
return tdb_node ;
2005-10-14 20:07:00 +04:00
}
/*******************************************************************
Wrapper to handle reference counts to the tdb
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
int elog_close_tdb ( ELOG_TDB * etdb , bool force_close )
2005-10-06 21:48:03 +04:00
{
2005-11-17 23:08:59 +03:00
TDB_CONTEXT * tdb ;
2005-10-06 21:48:03 +04:00
2005-11-17 23:08:59 +03:00
if ( ! etdb )
2005-10-14 20:07:00 +04:00
return 0 ;
2009-01-15 22:01:30 +03:00
2005-11-17 23:08:59 +03:00
etdb - > ref_count - - ;
2009-01-15 22:01:30 +03:00
2005-11-17 23:08:59 +03:00
SMB_ASSERT ( etdb - > ref_count > = 0 ) ;
if ( etdb - > ref_count = = 0 ) {
tdb = etdb - > tdb ;
DLIST_REMOVE ( open_elog_list , etdb ) ;
TALLOC_FREE ( etdb ) ;
2005-10-14 20:07:00 +04:00
return tdb_close ( tdb ) ;
2005-11-17 23:08:59 +03:00
}
2009-01-15 22:01:30 +03:00
2005-11-17 23:08:59 +03:00
if ( force_close ) {
tdb = etdb - > tdb ;
etdb - > tdb = NULL ;
2005-10-14 20:07:00 +04:00
return tdb_close ( tdb ) ;
2005-10-06 21:48:03 +04:00
}
2005-10-14 20:07:00 +04:00
return 0 ;
2005-10-06 21:48:03 +04:00
}
/********************************************************************
2009-01-15 22:01:30 +03:00
Note that it ' s a pretty good idea to initialize the Eventlog_entry
structure to zero ' s before calling parse_logentry on an batch of
lines that may resolve to a record . ALSO , it ' s a good idea to
remove any linefeeds ( that ' s EOL to you and me ) on the lines
2005-10-14 20:07:00 +04:00
going in .
2005-10-06 21:48:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-02 19:24:28 +03:00
bool parse_logentry ( TALLOC_CTX * mem_ctx , char * line , struct eventlog_Record_tdb * entry , bool * eor )
2005-10-06 21:48:03 +04:00
{
char * start = NULL , * stop = NULL ;
start = line ;
2023-07-06 01:49:11 +03:00
/* empty line signifying record delimiter, or we're at the end of the buffer */
2005-10-06 21:48:03 +04:00
if ( start = = NULL | | strlen ( start ) = = 0 ) {
DEBUG ( 6 ,
( " parse_logentry: found end-of-record indicator. \n " ) ) ;
* eor = True ;
return True ;
}
if ( ! ( stop = strchr ( line , ' : ' ) ) ) {
return False ;
}
DEBUG ( 6 , ( " parse_logentry: trying to parse [%s]. \n " , line ) ) ;
if ( 0 = = strncmp ( start , " LEN " , stop - start ) ) {
/* This will get recomputed later anyway -- probably not necessary */
2009-02-02 19:24:28 +03:00
entry - > size = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " RS1 " , stop - start ) ) {
/* For now all these reserved entries seem to have the same value,
which can be hardcoded to int ( 1699505740 ) for now */
2009-02-02 19:24:28 +03:00
entry - > reserved = talloc_strdup ( mem_ctx , " eLfL " ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " RCN " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > record_number = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " TMG " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > time_generated = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " TMW " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > time_written = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " EID " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_id = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " ETP " , stop - start ) ) {
if ( strstr ( start , " ERROR " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_ERROR_TYPE ;
2005-10-06 21:48:03 +04:00
} else if ( strstr ( start , " WARNING " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_WARNING_TYPE ;
2005-10-06 21:48:03 +04:00
} else if ( strstr ( start , " INFO " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_INFORMATION_TYPE ;
2005-10-06 21:48:03 +04:00
} else if ( strstr ( start , " AUDIT_SUCCESS " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_AUDIT_SUCCESS ;
2005-10-06 21:48:03 +04:00
} else if ( strstr ( start , " AUDIT_FAILURE " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_AUDIT_FAILURE ;
2005-10-06 21:48:03 +04:00
} else if ( strstr ( start , " SUCCESS " ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_type = EVENTLOG_SUCCESS ;
2005-10-06 21:48:03 +04:00
} else {
/* some other eventlog type -- currently not defined in MSDN docs, so error out */
return False ;
}
}
/*
else if ( 0 = = strncmp ( start , " NST " , stop - start ) )
{
2009-02-02 19:24:28 +03:00
entry - > num_of_strings = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
}
*/
else if ( 0 = = strncmp ( start , " ECT " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > event_category = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " RS2 " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > reserved_flags = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " CRN " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > closing_record_number = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " USL " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
entry - > sid_length = atoi ( stop + 1 ) ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " SRC " , stop - start ) ) {
stop + + ;
while ( isspace ( stop [ 0 ] ) ) {
stop + + ;
}
2009-02-02 19:24:28 +03:00
entry - > source_name_len = strlen_m_term ( stop ) ;
entry - > source_name = talloc_strdup ( mem_ctx , stop ) ;
if ( entry - > source_name_len = = ( uint32_t ) - 1 | |
entry - > source_name = = NULL ) {
2007-11-27 22:22:58 +03:00
return false ;
}
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " SRN " , stop - start ) ) {
stop + + ;
while ( isspace ( stop [ 0 ] ) ) {
stop + + ;
}
2009-02-02 19:24:28 +03:00
entry - > computer_name_len = strlen_m_term ( stop ) ;
entry - > computer_name = talloc_strdup ( mem_ctx , stop ) ;
if ( entry - > computer_name_len = = ( uint32_t ) - 1 | |
entry - > computer_name = = NULL ) {
2007-11-27 22:22:58 +03:00
return false ;
}
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " SID " , stop - start ) ) {
2009-02-02 19:24:28 +03:00
smb_ucs2_t * dummy = NULL ;
2005-10-06 21:48:03 +04:00
stop + + ;
while ( isspace ( stop [ 0 ] ) ) {
stop + + ;
}
2009-02-02 19:24:28 +03:00
entry - > sid_length = rpcstr_push_talloc ( mem_ctx ,
& dummy ,
2007-11-27 22:22:58 +03:00
stop ) ;
2009-02-05 18:36:44 +03:00
if ( entry - > sid_length = = ( uint32_t ) - 1 ) {
return false ;
}
2009-02-02 19:24:28 +03:00
entry - > sid = data_blob_talloc ( mem_ctx , dummy , entry - > sid_length ) ;
2009-02-05 18:36:44 +03:00
if ( entry - > sid . data = = NULL ) {
2007-11-27 22:22:58 +03:00
return false ;
}
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " STR " , stop - start ) ) {
2007-11-27 22:22:58 +03:00
size_t tmp_len ;
2014-11-14 16:12:26 +03:00
size_t num_of_strings ;
2005-10-06 21:48:03 +04:00
/* skip past initial ":" */
stop + + ;
/* now skip any other leading whitespace */
2007-11-27 22:22:58 +03:00
while ( isspace ( stop [ 0 ] ) ) {
2005-10-06 21:48:03 +04:00
stop + + ;
}
2009-02-02 19:24:28 +03:00
tmp_len = strlen_m_term ( stop ) ;
if ( tmp_len = = ( size_t ) - 1 ) {
2007-11-27 22:22:58 +03:00
return false ;
}
2009-02-14 20:01:20 +03:00
num_of_strings = entry - > num_of_strings ;
2009-02-02 19:24:28 +03:00
if ( ! add_string_to_array ( mem_ctx , stop , & entry - > strings ,
2009-02-14 20:01:20 +03:00
& num_of_strings ) ) {
2007-11-27 22:22:58 +03:00
return false ;
}
2009-02-14 20:01:20 +03:00
if ( num_of_strings > 0xffff ) {
return false ;
}
entry - > num_of_strings = num_of_strings ;
2009-02-02 19:24:28 +03:00
entry - > strings_len + = tmp_len ;
2005-10-06 21:48:03 +04:00
} else if ( 0 = = strncmp ( start , " DAT " , stop - start ) ) {
/* skip past initial ":" */
stop + + ;
/* now skip any other leading whitespace */
while ( isspace ( stop [ 0 ] ) ) {
stop + + ;
}
2009-02-02 19:24:28 +03:00
entry - > data_length = strlen_m ( stop ) ;
entry - > data = data_blob_talloc ( mem_ctx , stop , entry - > data_length ) ;
if ( ! entry - > data . data ) {
2007-11-27 22:22:58 +03:00
return false ;
2005-10-06 21:48:03 +04:00
}
} else {
/* some other eventlog entry -- not implemented, so dropping on the floor */
DEBUG ( 10 , ( " Unknown entry [%s]. Ignoring. \n " , line ) ) ;
/* For now return true so that we can keep on parsing this mess. Eventually
we will return False here . */
2007-11-27 22:22:58 +03:00
return true ;
2005-10-06 21:48:03 +04:00
}
2007-11-27 22:22:58 +03:00
return true ;
2005-10-06 21:48:03 +04:00
}
2009-01-15 22:28:30 +03:00
2009-02-04 12:01:38 +03:00
/*******************************************************************
calculate the correct fields etc for an eventlog entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
size_t fixup_eventlog_record_tdb ( struct eventlog_Record_tdb * r )
{
size_t size = 56 ; /* static size of integers before buffers start */
r - > source_name_len = strlen_m_term ( r - > source_name ) * 2 ;
r - > computer_name_len = strlen_m_term ( r - > computer_name ) * 2 ;
r - > strings_len = ndr_size_string_array ( r - > strings ,
r - > num_of_strings , LIBNDR_FLAG_STR_NULLTERM ) * 2 ;
/* fix up the eventlog entry structure as necessary */
r - > sid_padding = ( ( 4 - ( ( r - > source_name_len + r - > computer_name_len ) % 4 ) ) % 4 ) ;
r - > padding = ( 4 - ( ( r - > strings_len + r - > data_length ) % 4 ) ) % 4 ;
if ( r - > sid_length = = 0 ) {
/* Should not pad to a DWORD boundary for writing out the sid if there is
no SID , so just propagate the padding to pad the data */
r - > padding + = r - > sid_padding ;
r - > sid_padding = 0 ;
}
size + = r - > source_name_len ;
size + = r - > computer_name_len ;
size + = r - > sid_padding ;
size + = r - > sid_length ;
size + = r - > strings_len ;
size + = r - > data_length ;
size + = r - > padding ;
/* need another copy of length at the end of the data */
size + = sizeof ( r - > size ) ;
r - > size = size ;
return size ;
}
2009-01-15 22:28:30 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct eventlog_Record_tdb * evlog_pull_record_tdb ( TALLOC_CTX * mem_ctx ,
TDB_CONTEXT * tdb ,
uint32_t record_number )
{
struct eventlog_Record_tdb * r ;
TDB_DATA data , key ;
int32_t srecno ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
srecno = record_number ;
key . dptr = ( unsigned char * ) & srecno ;
key . dsize = sizeof ( int32_t ) ;
2015-03-12 17:23:17 +03:00
data = tdb_fetch ( tdb , key ) ;
2009-01-15 22:28:30 +03:00
if ( data . dsize = = 0 ) {
DEBUG ( 8 , ( " evlog_pull_record_tdb: "
" Can't find a record for the key, record %d \n " ,
record_number ) ) ;
return NULL ;
}
r = talloc_zero ( mem_ctx , struct eventlog_Record_tdb ) ;
if ( ! r ) {
goto done ;
}
blob = data_blob_const ( data . dptr , data . dsize ) ;
2010-05-10 02:42:06 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , r ,
2009-01-15 22:28:30 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_eventlog_Record_tdb ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 10 , ( " evlog_pull_record_tdb: failed to decode record %d \n " ,
record_number ) ) ;
TALLOC_FREE ( r ) ;
goto done ;
}
if ( DEBUGLEVEL > = 10 ) {
NDR_PRINT_DEBUG ( eventlog_Record_tdb , r ) ;
}
DEBUG ( 10 , ( " evlog_pull_record_tdb: retrieved entry for record %d \n " ,
record_number ) ) ;
done :
SAFE_FREE ( data . dptr ) ;
return r ;
}
2009-01-21 21:36:19 +03:00
2009-02-03 15:09:59 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct EVENTLOGRECORD * evlog_pull_record ( TALLOC_CTX * mem_ctx ,
TDB_CONTEXT * tdb ,
uint32_t record_number )
{
struct eventlog_Record_tdb * t ;
struct EVENTLOGRECORD * r ;
NTSTATUS status ;
r = talloc_zero ( mem_ctx , struct EVENTLOGRECORD ) ;
if ( ! r ) {
return NULL ;
}
t = evlog_pull_record_tdb ( r , tdb , record_number ) ;
if ( ! t ) {
talloc_free ( r ) ;
return NULL ;
}
status = evlog_tdb_entry_to_evt_entry ( r , t , r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( r ) ;
return NULL ;
}
2010-05-10 02:42:06 +04:00
r - > Length = r - > Length2 = ndr_size_EVENTLOGRECORD ( r , 0 ) ;
2009-02-03 15:09:59 +03:00
return r ;
}
2009-01-21 21:36:19 +03:00
/********************************************************************
write an eventlog entry . Note that we have to lock , read next
eventlog , increment , write , write the record , unlock
2023-07-05 12:16:18 +03:00
coming into this , ee has the eventlog record , and the auxiliary date
2009-01-21 21:36:19 +03:00
( computer name , etc . ) filled into the other structure . Before packing
into a record , this routine will calc the appropriate padding , etc . ,
and then blast out the record in a form that can be read back in
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS evlog_push_record_tdb ( TALLOC_CTX * mem_ctx ,
TDB_CONTEXT * tdb ,
struct eventlog_Record_tdb * r ,
uint32_t * record_number )
{
TDB_DATA kbuf , ebuf ;
DATA_BLOB blob ;
enum ndr_err_code ndr_err ;
int ret ;
if ( ! r ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! can_write_to_eventlog ( tdb , r - > size ) ) {
return NT_STATUS_EVENTLOG_CANT_START ;
}
/* need to read the record number and insert it into the entry here */
/* lock */
ret = tdb_lock_bystring_with_timeout ( tdb , EVT_NEXT_RECORD , 1 ) ;
2011-06-20 13:10:33 +04:00
if ( ret ! = 0 ) {
2009-01-21 21:36:19 +03:00
return NT_STATUS_LOCK_NOT_GRANTED ;
}
/* read */
r - > record_number = tdb_fetch_int32 ( tdb , EVT_NEXT_RECORD ) ;
2010-05-10 02:42:06 +04:00
ndr_err = ndr_push_struct_blob ( & blob , mem_ctx , r ,
2009-01-21 21:36:19 +03:00
( ndr_push_flags_fn_t ) ndr_push_eventlog_Record_tdb ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
tdb_unlock_bystring ( tdb , EVT_NEXT_RECORD ) ;
return ndr_map_error2ntstatus ( ndr_err ) ;
}
/* increment the record count */
kbuf . dsize = sizeof ( int32_t ) ;
kbuf . dptr = ( uint8_t * ) & r - > record_number ;
ebuf . dsize = blob . length ;
ebuf . dptr = blob . data ;
ret = tdb_store ( tdb , kbuf , ebuf , 0 ) ;
2011-06-20 13:10:31 +04:00
if ( ret ! = 0 ) {
2009-01-21 21:36:19 +03:00
tdb_unlock_bystring ( tdb , EVT_NEXT_RECORD ) ;
return NT_STATUS_EVENTLOG_FILE_CORRUPT ;
}
ret = tdb_store_int32 ( tdb , EVT_NEXT_RECORD , r - > record_number + 1 ) ;
2011-06-20 13:10:31 +04:00
if ( ret ! = 0 ) {
2009-01-21 21:36:19 +03:00
tdb_unlock_bystring ( tdb , EVT_NEXT_RECORD ) ;
return NT_STATUS_EVENTLOG_FILE_CORRUPT ;
}
tdb_unlock_bystring ( tdb , EVT_NEXT_RECORD ) ;
if ( record_number ) {
* record_number = r - > record_number ;
}
return NT_STATUS_OK ;
}
2009-01-29 17:11:39 +03:00
2009-02-03 15:08:44 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS evlog_push_record ( TALLOC_CTX * mem_ctx ,
TDB_CONTEXT * tdb ,
struct EVENTLOGRECORD * r ,
uint32_t * record_number )
{
struct eventlog_Record_tdb * t ;
NTSTATUS status ;
t = talloc_zero ( mem_ctx , struct eventlog_Record_tdb ) ;
if ( ! t ) {
return NT_STATUS_NO_MEMORY ;
}
status = evlog_evt_entry_to_tdb_entry ( t , r , t ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( t ) ;
return status ;
}
status = evlog_push_record_tdb ( mem_ctx , tdb , t , record_number ) ;
talloc_free ( t ) ;
return status ;
}
2009-01-29 17:11:39 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS evlog_evt_entry_to_tdb_entry ( TALLOC_CTX * mem_ctx ,
const struct EVENTLOGRECORD * e ,
struct eventlog_Record_tdb * t )
{
uint32_t i ;
ZERO_STRUCTP ( t ) ;
t - > size = e - > Length ;
t - > reserved = e - > Reserved ;
t - > record_number = e - > RecordNumber ;
t - > time_generated = e - > TimeGenerated ;
t - > time_written = e - > TimeWritten ;
t - > event_id = e - > EventID ;
t - > event_type = e - > EventType ;
t - > num_of_strings = e - > NumStrings ;
t - > event_category = e - > EventCategory ;
t - > reserved_flags = e - > ReservedFlags ;
t - > closing_record_number = e - > ClosingRecordNumber ;
t - > stringoffset = e - > StringOffset ;
t - > sid_length = e - > UserSidLength ;
t - > sid_offset = e - > UserSidOffset ;
t - > data_length = e - > DataLength ;
t - > data_offset = e - > DataOffset ;
t - > source_name_len = 2 * strlen_m_term ( e - > SourceName ) ;
t - > source_name = talloc_strdup ( mem_ctx , e - > SourceName ) ;
NT_STATUS_HAVE_NO_MEMORY ( t - > source_name ) ;
t - > computer_name_len = 2 * strlen_m_term ( e - > Computername ) ;
t - > computer_name = talloc_strdup ( mem_ctx , e - > Computername ) ;
NT_STATUS_HAVE_NO_MEMORY ( t - > computer_name ) ;
/* t->sid_padding; */
if ( e - > UserSidLength > 0 ) {
2018-12-09 14:15:05 +03:00
struct dom_sid_buf sid_str ;
2009-01-29 17:11:39 +03:00
smb_ucs2_t * dummy = NULL ;
2018-12-09 14:15:05 +03:00
t - > sid_length = rpcstr_push_talloc (
mem_ctx ,
& dummy ,
dom_sid_str_buf ( & e - > UserSid , & sid_str ) ) ;
2009-01-29 17:11:39 +03:00
if ( t - > sid_length = = - 1 ) {
return NT_STATUS_NO_MEMORY ;
}
t - > sid = data_blob_talloc ( mem_ctx , ( uint8_t * ) dummy , t - > sid_length ) ;
NT_STATUS_HAVE_NO_MEMORY ( t - > sid . data ) ;
}
t - > strings = talloc_array ( mem_ctx , const char * , e - > NumStrings ) ;
for ( i = 0 ; i < e - > NumStrings ; i + + ) {
t - > strings [ i ] = talloc_strdup ( t - > strings , e - > Strings [ i ] ) ;
NT_STATUS_HAVE_NO_MEMORY ( t - > strings [ i ] ) ;
}
t - > strings_len = 2 * ndr_size_string_array ( t - > strings , t - > num_of_strings , LIBNDR_FLAG_STR_NULLTERM ) ;
t - > data = data_blob_talloc ( mem_ctx , e - > Data , e - > DataLength ) ;
/* t->padding = r->Pad; */
return NT_STATUS_OK ;
}
2009-02-04 20:31:04 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS evlog_tdb_entry_to_evt_entry ( TALLOC_CTX * mem_ctx ,
const struct eventlog_Record_tdb * t ,
struct EVENTLOGRECORD * e )
{
uint32_t i ;
ZERO_STRUCTP ( e ) ;
e - > Length = t - > size ;
e - > Reserved = t - > reserved ;
e - > RecordNumber = t - > record_number ;
e - > TimeGenerated = t - > time_generated ;
e - > TimeWritten = t - > time_written ;
e - > EventID = t - > event_id ;
e - > EventType = t - > event_type ;
e - > NumStrings = t - > num_of_strings ;
e - > EventCategory = t - > event_category ;
e - > ReservedFlags = t - > reserved_flags ;
e - > ClosingRecordNumber = t - > closing_record_number ;
e - > StringOffset = t - > stringoffset ;
e - > UserSidLength = t - > sid_length ;
e - > UserSidOffset = t - > sid_offset ;
e - > DataLength = t - > data_length ;
e - > DataOffset = t - > data_offset ;
e - > SourceName = talloc_strdup ( mem_ctx , t - > source_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( e - > SourceName ) ;
e - > Computername = talloc_strdup ( mem_ctx , t - > computer_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( e - > Computername ) ;
if ( t - > sid_length > 0 ) {
2018-04-05 11:12:41 +03:00
char * sid_str = NULL ;
2009-02-04 20:31:04 +03:00
size_t len ;
if ( ! convert_string_talloc ( mem_ctx , CH_UTF16 , CH_UNIX ,
t - > sid . data , t - > sid . length ,
2011-03-24 02:59:41 +03:00
( void * ) & sid_str , & len ) ) {
2009-02-04 20:31:04 +03:00
return NT_STATUS_INVALID_SID ;
}
if ( len > 0 ) {
2018-04-05 11:11:16 +03:00
bool ok = string_to_sid ( & e - > UserSid , sid_str ) ;
if ( ! ok ) {
return NT_STATUS_INVALID_SID ;
}
2009-02-04 20:31:04 +03:00
}
2018-04-05 11:12:41 +03:00
TALLOC_FREE ( sid_str ) ;
2009-02-04 20:31:04 +03:00
}
e - > Strings = talloc_array ( mem_ctx , const char * , t - > num_of_strings ) ;
for ( i = 0 ; i < t - > num_of_strings ; i + + ) {
e - > Strings [ i ] = talloc_strdup ( e - > Strings , t - > strings [ i ] ) ;
NT_STATUS_HAVE_NO_MEMORY ( e - > Strings [ i ] ) ;
}
e - > Data = ( uint8_t * ) talloc_memdup ( mem_ctx , t - > data . data , t - > data_length ) ;
e - > Pad = talloc_strdup ( mem_ctx , " " ) ;
NT_STATUS_HAVE_NO_MEMORY ( e - > Pad ) ;
e - > Length2 = t - > size ;
return NT_STATUS_OK ;
}
2009-04-08 19:15:15 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS evlog_convert_tdb_to_evt ( TALLOC_CTX * mem_ctx ,
ELOG_TDB * etdb ,
DATA_BLOB * blob_p ,
uint32_t * num_records_p )
{
NTSTATUS status = NT_STATUS_OK ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
uint32_t num_records = 0 ;
struct EVENTLOG_EVT_FILE evt ;
uint32_t count = 1 ;
size_t endoffset = 0 ;
ZERO_STRUCT ( evt ) ;
while ( 1 ) {
struct eventlog_Record_tdb * r ;
struct EVENTLOGRECORD e ;
r = evlog_pull_record_tdb ( mem_ctx , etdb - > tdb , count ) ;
if ( ! r ) {
break ;
}
status = evlog_tdb_entry_to_evt_entry ( mem_ctx , r , & e ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-05-10 02:42:06 +04:00
endoffset + = ndr_size_EVENTLOGRECORD ( & e , 0 ) ;
2009-04-08 19:15:15 +04:00
ADD_TO_ARRAY ( mem_ctx , struct EVENTLOGRECORD , e , & evt . records , & num_records ) ;
count + + ;
}
evt . hdr . StartOffset = 0x30 ;
evt . hdr . EndOffset = evt . hdr . StartOffset + endoffset ;
evt . hdr . CurrentRecordNumber = count ;
evt . hdr . OldestRecordNumber = 1 ;
evt . hdr . MaxSize = tdb_fetch_int32 ( etdb - > tdb , EVT_MAXSIZE ) ;
evt . hdr . Flags = 0 ;
evt . hdr . Retention = tdb_fetch_int32 ( etdb - > tdb , EVT_RETENTION ) ;
if ( DEBUGLEVEL > = 10 ) {
NDR_PRINT_DEBUG ( EVENTLOGHEADER , & evt . hdr ) ;
}
evt . eof . BeginRecord = 0x30 ;
evt . eof . EndRecord = evt . hdr . StartOffset + endoffset ;
evt . eof . CurrentRecordNumber = evt . hdr . CurrentRecordNumber ;
evt . eof . OldestRecordNumber = evt . hdr . OldestRecordNumber ;
if ( DEBUGLEVEL > = 10 ) {
NDR_PRINT_DEBUG ( EVENTLOGEOF , & evt . eof ) ;
}
2010-05-10 02:42:06 +04:00
ndr_err = ndr_push_struct_blob ( & blob , mem_ctx , & evt ,
2009-04-08 19:15:15 +04:00
( ndr_push_flags_fn_t ) ndr_push_EVENTLOG_EVT_FILE ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
status = ndr_map_error2ntstatus ( ndr_err ) ;
goto done ;
}
* blob_p = blob ;
* num_records_p = num_records ;
done :
return status ;
}