r11060: merging new eventlog code from trunk
authorGerald Carter <jerry@samba.org>
Fri, 14 Oct 2005 16:07:00 +0000 (16:07 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:04:59 +0000 (11:04 -0500)
(This used to be commit 1bcf7e82ede63a851a244162a3b939373787b693)

source3/Makefile.in
source3/include/rpc_eventlog.h
source3/rpc_server/srv_eventlog_lib.c
source3/rpc_server/srv_eventlog_nt.c
source3/smbd/posix_acls.c
source3/utils/wr_eventlog.c [new file with mode: 0644]

index abb7085ff410dade67d08738c366c851a6a9b8d0..7664f71bc63dcce52d6dbfb048eaa3cc902b3dd1 100644 (file)
@@ -130,7 +130,7 @@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \
        bin/tdbtool@EXEEXT@
 BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
        bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \
-       bin/smbcquotas@EXEEXT@
+       bin/smbcquotas@EXEEXT@ bin/wr_eventlog@EXEEXT@
 
 TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \
        bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \
@@ -614,6 +614,9 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
                $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ)
 
+WR_EVENTLOG_OBJ        = utils/wr_eventlog.o rpc_server/srv_eventlog_lib.o \
+               $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) 
+
 TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) libsmb/nterr.o
 
 RPCTORTURE_OBJ = torture/rpctorture.o \
@@ -750,6 +753,8 @@ debug2html : SHOWFLAGS bin/debug2html@EXEEXT@
 
 smbfilter : SHOWFLAGS bin/smbfilter@EXEEXT@
 
+wr_eventlog: SHOWFLAGS bin/wr_eventlog@EXEEXT@
+
 talloctort : SHOWFLAGS bin/talloctort@EXEEXT@
 
 nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ @WINBIND_NSS@ \
@@ -759,7 +764,7 @@ wins : SHOWFLAGS @WINBIND_WINS_NSS@
 
 modules: SHOWFLAGS proto_exists $(MODULES)
 
-everything: all libsmbclient debug2html smbfilter talloctort modules torture \
+everything: all libsmbclient debug2html smbfilter talloctort modules torture wr_eventlog \
        $(EVERYTHING_PROGS)
 
 .SUFFIXES:
@@ -972,6 +977,10 @@ bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
 
+bin/wr_eventlog@EXEEXT@: $(WR_EVENTLOG_OBJ) @BUILD_POPT@ bin/.dummy
+       @echo Linking $@
+       @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(WR_EVENTLOG_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ 
+
 bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
index 9f968fb54e1b395e9b35ed002c560de7456bc069..c94b2fa8796fe29cd7e2a351bc2045e6f06c109a 100644 (file)
 #define EVENTLOG_AUDIT_FAILURE        0x0010
 
 /* Defines for TDB keys */
-#define  VN_oldest_entry  "INFO/oldest_entry"
-#define  VN_next_record   "INFO/next_record"
-#define  VN_version       "INFO/version"
-#define  VN_maxsize       "INFO/maxsize"
-#define  VN_retention     "INFO/retention"
+#define  EVT_OLDEST_ENTRY  "INFO/oldest_entry"
+#define  EVT_NEXT_RECORD   "INFO/next_record"
+#define  EVT_VERSION       "INFO/version"
+#define  EVT_MAXSIZE       "INFO/maxsize"
+#define  EVT_RETENTION     "INFO/retention"
+
+#define ELOG_APPL      "Application"
+#define ELOG_SYS       "System"
+#define ELOG_SEC       "Security"
 
 #define  EVENTLOG_DATABASE_VERSION_V1    1
 
index 3b7a32dac2114e54da3c7e52eb1873f6fecfe8ad..495ad8e58cbf42f9dcab3cc254ae1b0ab608bda7 100644 (file)
@@ -1,8 +1,8 @@
-
 /* 
  *  Unix SMB/CIFS implementation.
  *  Eventlog utility  routines
  *  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
 
 #include "includes.h"
 
+/* maintain a list of open eventlog tdbs with reference counts */
 
-/****************************************************************
-Init an Eventlog TDB, and return it. If null, something bad happened.
-****************************************************************/
-TDB_CONTEXT *init_eventlog_tdb( char *tdbfilename )
-{
-       TDB_CONTEXT *the_tdb;
-
-       unlink( tdbfilename );
+struct elog_open_tdb {
+       struct elog_open_tdb *prev, *next;
+       char *name;
+       TDB_CONTEXT *tdb;
+       int ref_count;
+};
 
-       the_tdb =
-               tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT,
-                             0664 );
-       if ( the_tdb == NULL ) {
-               DEBUG( 1, ( "Can't open tdb for [%s]\n", tdbfilename ) );
-               return NULL;
-       }
-       tdb_store_int32( the_tdb, VN_oldest_entry, 1 );
-       tdb_store_int32( the_tdb, VN_next_record, 1 );
+static struct elog_open_tdb *open_elog_list;
 
-       /* initialize with defaults, copy real values in here from registry */
-
-       tdb_store_int32( the_tdb, VN_maxsize, 0x80000 );
-       tdb_store_int32( the_tdb, VN_retention, 0x93A80 );
-
-       tdb_store_int32( the_tdb, VN_version, EVENTLOG_DATABASE_VERSION_V1 );
-       return the_tdb;
-}
+/********************************************************************
+ Init an Eventlog TDB, and return it. If null, something bad 
+ happened.
+********************************************************************/
 
-/* make the tdb file name for an event log, given destination buffer and size */
-char *mk_tdbfilename( char *dest_buffer, char *eventlog_name, int size_dest )
+TDB_CONTEXT *elog_init_tdb( char *tdbfilename )
 {
-       pstring ondisk_name;
-
-       if ( !dest_buffer )
-               return NULL;
+       TDB_CONTEXT *tdb;
 
-       pstrcpy( ondisk_name, "EV" );
-       pstrcat( ondisk_name, eventlog_name );
-       pstrcat( ondisk_name, ".tdb" );
+       DEBUG(10,("elog_init_tdb: Initializing eventlog tdb (%s)\n",
+               tdbfilename));
 
-       memset( dest_buffer, 0, size_dest );
+       tdb = tdb_open_log( tdbfilename, 0, TDB_DEFAULT, 
+               O_RDWR|O_CREAT|O_TRUNC, 0600 );
 
-       /* BAD things could happen if the dest_buffer is not large enough... */
-       if ( strlen( ondisk_name ) > size_dest ) {
-               DEBUG( 3, ( "Buffer not big enough for filename\n" ) );
+       if ( !tdb ) {
+               DEBUG( 0, ( "Can't open tdb for [%s]\n", tdbfilename ) );
                return NULL;
        }
 
-       strncpy( dest_buffer, ondisk_name, size_dest );
+       /* 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 );
+
+       tdb_store_int32( tdb, EVT_VERSION, EVENTLOG_DATABASE_VERSION_V1 );
 
-       return dest_buffer;
+       return tdb;
 }
 
+/********************************************************************
+ make the tdb file name for an event log, given destination buffer 
+ and size. Caller must free memory.
+********************************************************************/
 
-/* count the number of bytes in the TDB */
+char *elog_tdbname( const char *name )
+{
+       fstring path;
+       char *tdb_fullpath;
+       char *eventlogdir = lock_path( "eventlog" );
+       
+       pstr_sprintf( path, "%s/%s.tdb", eventlogdir, name );
+       strlower_m( path );
+       tdb_fullpath = SMB_STRDUP( path );
+       
+       return tdb_fullpath;
+}
 
-/* Arg! Static Globals! */
 
-static int eventlog_tdbcount;
-static int eventlog_tdbsize;
+/********************************************************************
+ this function is used to count up the number of bytes in a 
+ particular TDB
+********************************************************************/
+
+struct trav_size_struct {
+       int size;
+       int rec_count;
+};
 
-/* this function is used to count up the number of bytes in a particular TDB */
-int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data,
+static int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data,
                          void *state )
 {
-       eventlog_tdbsize += data.dsize;
-       eventlog_tdbcount++;
+       struct trav_size_struct  *tsize = state;
+       
+       tsize->size += data.dsize;
+       tsize->rec_count++;
+       
        return 0;
 }
 
-/* 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. Yeah, that's it.  */
+/********************************************************************
+ 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. 
+ Yeah, that's it.
+********************************************************************/
 
-int eventlog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention )
+int elog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention )
 {
+       struct trav_size_struct tsize;
+       
        if ( !tdb )
                return 0;
-       eventlog_tdbcount = 0;
-       eventlog_tdbsize = 0;
+               
+       ZERO_STRUCT( tsize );
 
-       tdb_traverse( tdb, eventlog_tdb_size_fn, NULL );
+       tdb_traverse( tdb, eventlog_tdb_size_fn, &tsize );
 
        if ( MaxSize != NULL ) {
-               *MaxSize = tdb_fetch_int32( tdb, VN_maxsize );
+               *MaxSize = tdb_fetch_int32( tdb, EVT_MAXSIZE );
        }
 
        if ( Retention != NULL ) {
-               *Retention = tdb_fetch_int32( tdb, VN_retention );
+               *Retention = tdb_fetch_int32( tdb, EVT_RETENTION );
        }
 
        DEBUG( 1,
-              ( "eventlog size: [%d] for [%d] records\n", eventlog_tdbsize,
-                eventlog_tdbcount ) );
-       return eventlog_tdbsize;
+              ( "eventlog size: [%d] for [%d] records\n", tsize.size,
+                tsize.rec_count ) );
+       return tsize.size;
 }
 
-
-/* 
-   Discard early event logs until we have enough for 'needed' bytes...
-   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.  
-
-   Setting whack_by_date to True indicates that eventlogs falling outside of the 
-   retention range need to go...
-
-*/
-
-/* return True if we made enough room to accommodate needed bytes */
+/********************************************************************
+ Discard early event logs until we have enough for 'needed' bytes...
+ 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.  
+
+ Setting whack_by_date to True indicates that eventlogs falling 
+ outside of the retention range need to go...
+ return True if we made enough room to accommodate needed bytes
+********************************************************************/
 
 BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
                             BOOL whack_by_date )
@@ -140,12 +155,9 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
        int start_record, i, new_start;
        int end_record;
        int nbytes, reclen, len, Retention, MaxSize;
-
        int tresv1, trecnum, timegen, timewr;
-
        TDB_DATA key, ret;
        TALLOC_CTX *mem_ctx = NULL;
-
        time_t current_time, exp_time;
 
        /* discard some eventlogs */
@@ -158,12 +170,12 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
        if ( mem_ctx == NULL )
                return False;   /* can't allocate memory indicates bigger problems */
        /* lock */
-       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
+       tdb_lock_bystring( the_tdb, EVT_NEXT_RECORD, 1 );
        /* read */
-       end_record = tdb_fetch_int32( the_tdb, VN_next_record );
-       start_record = tdb_fetch_int32( the_tdb, VN_oldest_entry );
-       Retention = tdb_fetch_int32( the_tdb, VN_retention );
-       MaxSize = tdb_fetch_int32( the_tdb, VN_maxsize );
+       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 );
 
        time( &current_time );
 
@@ -189,7 +201,7 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
                        DEBUG( 8,
                               ( "Can't find a record for the key, record [%d]\n",
                                 i ) );
-                       tdb_unlock_bystring( the_tdb, VN_next_record );
+                       tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
                        return False;
                }
                nbytes += ret.dsize;    /* note this includes overhead */
@@ -226,16 +238,16 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
                        tdb_delete( the_tdb, key );
                }
 
-               tdb_store_int32( the_tdb, VN_oldest_entry, new_start );
+               tdb_store_int32( the_tdb, EVT_OLDEST_ENTRY, new_start );
        }
-       tdb_unlock_bystring( the_tdb, VN_next_record );
+       tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
        return True;
 }
 
-/*
+/********************************************************************
   some hygiene for an eventlog - see how big it is, and then 
   calculate how many bytes we need to remove                   
-*/
+********************************************************************/
 
 BOOL prune_eventlog( TDB_CONTEXT * tdb )
 {
@@ -246,7 +258,7 @@ BOOL prune_eventlog( TDB_CONTEXT * tdb )
                return False;
        }
 
-       CalcdSize = eventlog_tdb_size( tdb, &MaxSize, &Retention );
+       CalcdSize = elog_tdb_size( tdb, &MaxSize, &Retention );
        DEBUG( 3,
               ( "Calculated size [%d] MaxSize [%d]\n", CalcdSize,
                 MaxSize ) );
@@ -259,6 +271,9 @@ BOOL prune_eventlog( TDB_CONTEXT * tdb )
        return make_way_for_eventlogs( tdb, 0, True );
 }
 
+/********************************************************************
+********************************************************************/
+
 BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
 {
        int calcd_size;
@@ -274,7 +289,7 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
        MaxSize = 0;
        Retention = 0;
 
-       calcd_size = eventlog_tdb_size( tdb, &MaxSize, &Retention );
+       calcd_size = elog_tdb_size( tdb, &MaxSize, &Retention );
 
        if ( calcd_size <= MaxSize )
                return True;    /* you betcha */
@@ -299,28 +314,128 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
        return make_way_for_eventlogs( tdb, calcd_size - MaxSize, False );
 }
 
-TDB_CONTEXT *open_eventlog_tdb( char *tdbfilename )
+/*******************************************************************
+*******************************************************************/
+
+TDB_CONTEXT *elog_open_tdb( char *logname )
 {
-       TDB_CONTEXT *the_tdb;
+       TDB_CONTEXT *tdb;
+       uint32 vers_id;
+       struct elog_open_tdb *ptr;
+       char *tdbfilename;
+       pstring tdbpath;
+       struct elog_open_tdb *tdb_node;
+       char *eventlogdir;
+
+       /* first see if we have an open context */
+       
+       for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
+               if ( strequal( ptr->name, logname ) ) {
+                       ptr->ref_count++;
+                       return ptr->tdb;                
+               }
+       }
+       
+       /* make sure that the eventlog dir exists */
+       
+       eventlogdir = lock_path( "eventlog" );
+       if ( !directory_exist( eventlogdir, NULL ) )
+               mkdir( eventlogdir, 0755 );     
+       
+       /* get the path on disk */
+       
+       tdbfilename = elog_tdbname( logname );
+       pstrcpy( tdbpath, tdbfilename );
+       SAFE_FREE( tdbfilename );
+
+       DEBUG(7,("elog_open_tdb: Opening %s...\n", tdbpath ));
+
+       tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );      
+       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 );
+               }
+       }
+       else {
+               tdb = elog_init_tdb( tdbpath );
+       }
+       
+       /* if we got a valid context, then add it to the list */
+       
+       if ( tdb ) {
+               if ( !(tdb_node = TALLOC_ZERO_P( NULL, struct elog_open_tdb )) ) {
+                       DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
+                       tdb_close( tdb );
+                       return NULL;
+               }
+               
+               tdb_node->name = talloc_strdup( tdb_node, logname );
+               tdb_node->tdb = tdb;
+               tdb_node->ref_count = 1;
+               
+               DLIST_ADD( open_elog_list, tdb_node );
+       }
+
+       return tdb;
+}
+
+/*******************************************************************
+ Wrapper to handle reference counts to the tdb
+*******************************************************************/
 
-       the_tdb =
-               tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDONLY,0664 );
-       if ( the_tdb == NULL ) {
-               return init_eventlog_tdb( tdbfilename );
+int elog_close_tdb( TDB_CONTEXT *tdb )
+{
+       struct elog_open_tdb *ptr;
+
+       if ( !tdb )
+               return 0;
+               
+       /* See if we can just decrement the ref_count.
+          Just compare pointer values (not names ) */
+       
+       for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
+               if ( tdb == ptr->tdb ) {
+                       ptr->ref_count--;
+                       break;
+               }
        }
-       if ( EVENTLOG_DATABASE_VERSION_V1 !=
-            tdb_fetch_int32( the_tdb, VN_version ) ) {
-               tdb_close( the_tdb );
-               return init_eventlog_tdb( tdbfilename );
+       
+       /* if we have a NULL pointer; it means we are trying to 
+          close a tdb not in the list of open eventlogs */
+          
+       SMB_ASSERT( ptr != NULL );
+       if ( !ptr )
+               return tdb_close( tdb );
+       
+       SMB_ASSERT( ptr->ref_count >= 0 );
+
+       if ( ptr->ref_count == 0 ) {
+               DLIST_REMOVE( open_elog_list, ptr );
+               TALLOC_FREE( ptr );
+               return tdb_close( tdb );
        }
-       return the_tdb;
+
+       return 0;
 }
 
-/* write an eventlog entry. Note that we have to lock, read next eventlog, increment, write, write the record, unlock */
 
-/* coming into this, ee has the eventlog record, and the auxilliary date (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 */
+/*******************************************************************
+ write an eventlog entry. Note that we have to lock, read next 
+ eventlog, increment, write, write the record, unlock 
+ coming into this, ee has the eventlog record, and the auxilliary date 
+ (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
+*******************************************************************/
+#define MARGIN 512
+
 int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
 {
        int32 next_record;
@@ -343,8 +458,6 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
        if ( ee->record.time_generated == 0 )
                return 0;
 
-#define MARGIN 512
-
        /* todo - check for sanity in next_record */
 
        fixup_eventlog_entry( ee );
@@ -365,9 +478,9 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
        /* need to read the record number and insert it into the entry here */
 
        /* lock */
-       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
+       tdb_lock_bystring( the_tdb, EVT_NEXT_RECORD, 1 );
        /* read */
-       next_record = tdb_fetch_int32( the_tdb, VN_next_record );
+       next_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
 
        n_packed =
                tdb_pack( packed_ee, ee->record.length + MARGIN,
@@ -406,18 +519,20 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
 
        if ( tdb_store( the_tdb, kbuf, ebuf, 0 ) ) {
                /* DEBUG(1,("write_eventlog_tdb: Can't write record %d to eventlog\n",next_record)); */
-               tdb_unlock_bystring( the_tdb, VN_next_record );
+               tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
                talloc_destroy( mem_ctx );
                return 0;
        }
        next_record++;
-       tdb_store_int32( the_tdb, VN_next_record, next_record );
-       tdb_unlock_bystring( the_tdb, VN_next_record );
+       tdb_store_int32( the_tdb, EVT_NEXT_RECORD, next_record );
+       tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
        talloc_destroy( mem_ctx );
        return ( next_record - 1 );
 }
 
-/* calculate the correct fields etc for an eventlog entry */
+/*******************************************************************
+ calculate the correct fields etc for an eventlog entry
+*******************************************************************/
 
 void fixup_eventlog_entry( Eventlog_entry * ee )
 {
@@ -453,10 +568,11 @@ void fixup_eventlog_entry( Eventlog_entry * ee )
 }
 
 /********************************************************************
-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 going in.
-
+ 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 
+ going in.
 ********************************************************************/
 
 BOOL parse_logentry( char *line, Eventlog_entry * entry, BOOL * eor )
index d3b350f233c01cbfbe00b8213ca304c439260d80..577ec48482a2258b0cbe273ba5d267d2b318d2ef 100644 (file)
 #undef  DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
-
-typedef struct {
-       pstring logname;        /* rather than alloc on the fly what we need... (memory is cheap now) */
-       pstring tdbfname;
-       TDB_CONTEXT *log_tdb;   /* the pointer to the TDB_CONTEXT */
-} EventlogTDBInfo;
-
-static int nlogs;
-static EventlogTDBInfo *ttdb = NULL;
-static TALLOC_CTX *mem_ctx = NULL;
-
 typedef struct {
        char *logname;
-       char *servername;
+       TDB_CONTEXT *tdb;
        uint32 num_records;
        uint32 oldest_entry;
        uint32 flags;
-} EventlogInfo;
+       uint32 access_granted;
+} EVENTLOG_INFO;
 
+/********************************************************************
+ ********************************************************************/
 
+static void free_eventlog_info( void *ptr )
+{
+       EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr;
+       
+       if ( elog->tdb )
+               elog_close_tdb( elog->tdb );
+       
+       TALLOC_FREE( elog );
+}
 
-#if 0 /* UNUSED */
 /********************************************************************
  ********************************************************************/
-void test_eventlog_tdb( TDB_CONTEXT * the_tdb )
+
+static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
+                                               POLICY_HND * handle )
 {
-       Eventlog_entry ee;
-
-       int i = 0;
-
-       memset( &ee, 0, sizeof( Eventlog_entry ) );
-
-       if ( !the_tdb )
-               return;
-
-       for ( i = 0; i < 100; i++ ) {
-               ee.record.length = sizeof( ee.record );
-               memset( &ee.data_record, 0, sizeof( ee.data_record ) );
-               ee.record.reserved1 = 0xBEEFDEAD;
-               ee.record.record_number = 1000 - i;     /* should get substituted */
-               ee.record.time_generated = 0;
-               ee.record.time_written = 0;
-               ee.record.event_id = 500;
-               ee.record.event_type = 300;
-               ee.record.num_strings = 0;
-               ee.record.event_category = 0;
-               ee.record.reserved2 = ( i << 8 ) | i;
-               ee.record.closing_record_number = -1;
-               ee.record.string_offset = 0;
-               ee.record.user_sid_length = 0;
-               ee.record.user_sid_offset = 0;
-               ee.record.data_length = 0;
-               ee.record.data_offset = 0;
-
-               rpcstr_push( ( void * ) ( ee.data_record.source_name ),
-                            "SystemLog",
-                            sizeof( ee.data_record.source_name ),
-                            STR_TERMINATE );
-               ee.data_record.source_name_len =
-                       ( strlen_w( ee.data_record.source_name ) * 2 ) + 2;
-
-               rpcstr_push( ( void * ) ( ee.data_record.computer_name ),
-                            "DMLINUX",
-                            sizeof( ee.data_record.computer_name ),
-                            STR_TERMINATE );
-
-               ee.data_record.computer_name_len =
-                       ( strlen_w( ee.data_record.computer_name ) * 2 ) + 2;
-
-               write_eventlog_tdb( the_tdb, &ee );
+       EVENTLOG_INFO *info;
+
+       if ( !find_policy_by_hnd( p, handle, ( void ** ) &info ) ) {
+               DEBUG( 2,
+                      ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
+               return NULL;
        }
+
+       return info;
 }
-#endif /* UNUSED */
 
 /********************************************************************
- ********************************************************************/
+********************************************************************/
 
-static void refresh_eventlog_tdb_table( void )
+static BOOL elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
 {
-       const char **elogs = lp_eventlog_list(  );
-       int i, j;
+       char *tdbname = elog_tdbname( info->logname );
+       SEC_DESC *sec_desc;
+       BOOL ret;
+       NTSTATUS ntstatus;
+       
+       if ( !tdbname ) 
+               return False;
+       
+       /* get the security descriptor for the file */
+       
+       sec_desc = get_nt_acl_no_snum( info, tdbname );
+       SAFE_FREE( tdbname );
+       
+       if ( !sec_desc ) {
+               DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n", 
+                       tdbname));
+               return False;
+       }
+       
+       /* run the check, try for the max allowed */
+       
+       ret = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
+               &info->access_granted, &ntstatus );
+               
+       if ( sec_desc )
+               TALLOC_FREE( sec_desc );
+               
+       if ( !ret ) {
+               DEBUG(8,("elog_check_access: se_access_check() return %s\n",
+                       nt_errstr( ntstatus)));
+               return False;
+       }
+       
+       /* we have to have READ permission for a successful open */
+       
+       return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
+}
 
-       if ( !elogs )
-               return;
+/********************************************************************
+ ********************************************************************/
 
-       if ( !mem_ctx ) {
-               mem_ctx = talloc_init( "refresh_eventlog_tdb_table" );
+static BOOL elog_validate_logname( const char *name )
+{
+       int i;
+       const char **elogs = lp_eventlog_list();
+       
+       for ( i=0; elogs[i]; i++ ) {
+               if ( strequal( name, elogs[i] ) )
+                       return True;
        }
+       
+       return False;
+}
 
-       if ( !mem_ctx ) {
-               DEBUG( 1, ( "Can't allocate memory\n" ) );
-               return;
-       }
+/********************************************************************
+ ********************************************************************/
 
-       /* count them */
-       for ( i = 0; elogs[i]; i++ ) {
-       }
-       /* number of logs in i */
-       DEBUG( 10, ( "Number of eventlogs %d\n", i ) );
-       /* check to see if we need to adjust our tables */
-
-       if ( ( ttdb != NULL ) ) {
-               if ( i != nlogs ) {
-                       /* refresh the table, by closing and reconstructing */
-                       DEBUG( 10, ( "Closing existing table \n" ) );
-                       for ( j = 0; j < nlogs; j++ ) {
-                               tdb_close( ttdb[j].log_tdb );
-                       }
-                       TALLOC_FREE( ttdb );
-                       ttdb = NULL;
-               } else {        /* i == nlogs */
-
-                       for ( j = 0; j < nlogs; j++ ) {
-                               if ( StrCaseCmp( ttdb[j].logname, elogs[i] ) ) {
-                                       /* something changed, have to discard */
-                                       DEBUG( 10,
-                                              ( "Closing existing table \n" ) );
-                                       for ( j = 0; j < nlogs; j++ ) {
-                                               tdb_close( ttdb[j].log_tdb );
-                                       }
-                                       TALLOC_FREE( ttdb );
-                                       ttdb = NULL;
-                                       break;
-                               }
+static WERROR elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
+{
+       EVENTLOG_INFO *elog;
+       
+       /* first thing is to validate the eventlog name */
+       
+       if ( !elog_validate_logname( logname ) )
+               return WERR_OBJECT_PATH_INVALID;
+       
+       if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
+               return WERR_NOMEM;
+               
+       elog->logname = talloc_strdup( elog, logname );
+       
+       /* Open the tdb first (so that we can create any new tdbs if necessary).
+          We have to do this as root and then use an internal access check 
+          on the file permissions since you can only have a tdb open once
+          in a single process */
+
+       become_root();
+       elog->tdb = elog_open_tdb( elog->logname );
+       unbecome_root();
+
+       if ( !elog->tdb ) {
+               /* according to MSDN, if the logfile cannot be found, we should
+                 default to the "Application" log */
+       
+               if ( !strequal( logname, ELOG_APPL ) ) {
+               
+                       TALLOC_FREE( elog->logname );
+                       
+                       elog->logname = talloc_strdup( elog, ELOG_APPL );                       
+
+                       /* do the access check */
+                       if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
+                               TALLOC_FREE( elog );
+                               return WERR_ACCESS_DENIED;
                        }
+       
+                       become_root();
+                       elog->tdb = elog_open_tdb( elog->logname );
+                       unbecome_root();
+               }       
+               
+               if ( !elog->tdb ) {
+                       TALLOC_FREE( elog );
+                       return WERR_ACCESS_DENIED;      /* ??? */               
                }
        }
+       
+       /* now do the access check.  Close the tdb if we fail here */
 
-       /* note that this might happen because of above */
-       if ( ( i > 0 ) && ( ttdb == NULL ) ) {
-               /* alloc the room */
-               DEBUG( 10, ( "Creating the table\n" ) );
-               ttdb = TALLOC( mem_ctx, sizeof( EventlogTDBInfo ) * i );
-               if ( !ttdb ) {
-                       DEBUG( 10,
-                              ( "Can't allocate table for tdb handles \n" ) );
-                       return;
-               }
-               for ( j = 0; j < i; j++ ) {
-                       pstrcpy( ttdb[j].tdbfname,
-                                lock_path( mk_tdbfilename
-                                           ( ttdb[j].tdbfname,
-                                             ( char * ) elogs[j],
-                                             sizeof( pstring ) ) ) );
-                       pstrcpy( ttdb[j].logname, elogs[j] );
-                       DEBUG( 10, ( "Opening tdb for %s\n", elogs[j] ) );
-                       ttdb[j].log_tdb =
-                               open_eventlog_tdb( ttdb[j].tdbfname );
-               }
+       if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
+               elog_close_tdb( elog->tdb );
+               TALLOC_FREE( elog );
+               return WERR_ACCESS_DENIED;
+       }
+       
+       /* create the policy handle */
+       
+       if ( !create_policy_hnd
+            ( p, hnd, free_eventlog_info, ( void * ) elog ) ) {
+               free_eventlog_info( elog );
+               return WERR_NOMEM;
        }
-       nlogs = i;
+
+       return WERR_OK;
 }
 
 /********************************************************************
  ********************************************************************/
 
-TDB_CONTEXT *tdb_of( char *eventlog_name )
+static WERROR elog_close( pipes_struct *p, POLICY_HND *hnd )
 {
-       int i;
-
-       if ( !eventlog_name )
-               return NULL;
+        if ( !( close_policy_hnd( p, hnd ) ) ) {
+                return WERR_BADFID;
+        }
 
-       if ( !ttdb ) {
-               DEBUG( 10, ( "Refreshing list of eventlogs\n" ) );
-               refresh_eventlog_tdb_table(  );
-
-               if ( !ttdb ) {
-                       DEBUG( 10,
-                              ( "eventlog tdb table is NULL after a refresh!\n" ) );
-                       return NULL;
-               }
-       }
+       return WERR_OK;
+}
 
-       DEBUG( 10, ( "Number of eventlogs %d\n", nlogs ) );
+/*******************************************************************
+ *******************************************************************/
 
-       for ( i = 0; i < nlogs; i++ ) {
-               if ( strequal( eventlog_name, ttdb[i].logname ) ) 
-                       return ttdb[i].log_tdb;
+static int elog_size( EVENTLOG_INFO *info )
+{
+       if ( !info || !info->tdb ) {
+               DEBUG(0,("elog_size: Invalid info* structure!\n"));
+               return 0;
        }
 
-       return NULL;
+       return elog_tdb_size( info->tdb, NULL, NULL );
 }
 
-
 /********************************************************************
   For the given tdb, get the next eventlog record into the passed 
   Eventlog_entry.  returns NULL if it can't get the record for some reason.
@@ -314,37 +323,12 @@ Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
        return ee;
 }
 
-/********************************************************************
- ********************************************************************/
-
-static void free_eventlog_info( void *ptr )
-{
-       TALLOC_FREE( ptr );
-}
-
-/********************************************************************
- ********************************************************************/
-
-static EventlogInfo *find_eventlog_info_by_hnd( pipes_struct * p,
-                                               POLICY_HND * handle )
-{
-       EventlogInfo *info;
-
-       if ( !find_policy_by_hnd( p, handle, ( void ** ) &info ) ) {
-               DEBUG( 2,
-                      ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
-               return NULL;
-       }
-
-       return info;
-}
-
 /********************************************************************
  note that this can only be called AFTER the table is constructed, 
  since it uses the table to find the tdb handle
  ********************************************************************/
 
-static BOOL sync_eventlog_params( const char *elogname )
+static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
 {
        pstring path;
        uint32 uiMaxSize;
@@ -353,14 +337,12 @@ static BOOL sync_eventlog_params( const char *elogname )
        REGISTRY_VALUE *val;
        REGVAL_CTR *values;
        WERROR wresult;
-       TDB_CONTEXT *the_tdb;
-
-       the_tdb = tdb_of( ( char * ) elogname );
+       char *elogname = info->logname;
 
        DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
 
-       if ( !the_tdb ) {
-               DEBUG( 4, ( "Can't open tdb for %s\n", elogname ) );
+       if ( !info->tdb ) {
+               DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
                return False;
        }
        /* set resonable defaults.  512Kb on size and 1 week on time */
@@ -402,112 +384,52 @@ static BOOL sync_eventlog_params( const char *elogname )
 
        regkey_close_internal( keyinfo );
 
-       tdb_store_int32( the_tdb, VN_maxsize, uiMaxSize );
-       tdb_store_int32( the_tdb, VN_retention, uiRetention );
-
-       return True;
-}
-
-/********************************************************************
- ********************************************************************/
+       tdb_store_int32( info->tdb, EVT_MAXSIZE, uiMaxSize );
+       tdb_store_int32( info->tdb, EVT_RETENTION, uiRetention );
 
-static BOOL open_eventlog_hook( EventlogInfo * info )
-{
        return True;
 }
 
 /********************************************************************
 ********************************************************************/
 
-/**
- * Callout to get the number of records in the specified event log
- * 
- *   smbrun calling convention --
- *     INPUT: <get_num_records_cmd> <log name> <policy handle>
- *     OUTPUT: A single line with a single integer containing the number of
- *             entries in the log. If there are no entries in the log, return 0.
- */
-
-
-static BOOL get_num_records_hook( EventlogInfo * info )
+static BOOL get_num_records_hook( EVENTLOG_INFO * info )
 {
-
-       TDB_CONTEXT *the_tdb = NULL;
        int next_record;
        int oldest_record;
 
-
-       the_tdb = tdb_of( info->logname );
-
-       if ( !the_tdb ) {
-               DEBUG( 10, ( "Can't find tdb for %s\n", info->logname ) );
-               info->num_records = 0;
+       if ( !info->tdb ) {
+               DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
                return False;
        }
 
-       /* lock */
-       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
-
-
-       /* read */
-       next_record = tdb_fetch_int32( the_tdb, VN_next_record );
-       oldest_record = tdb_fetch_int32( the_tdb, VN_oldest_entry );
-
+       /* lock the tdb since we have to get 2 records */
 
+       tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 );
+       next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD);
+       oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY);
+       tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD);
 
        DEBUG( 8,
-              ( "Oldest Record %d Next Record %d\n", oldest_record,
+              ( "Oldest Record %d; Next Record %d\n", oldest_record,
                 next_record ) );
 
        info->num_records = ( next_record - oldest_record );
        info->oldest_entry = oldest_record;
-       tdb_unlock_bystring( the_tdb, VN_next_record );
-
 
        return True;
-
-
 }
 
 /********************************************************************
  ********************************************************************/
 
-/**
- * Callout to find the oldest record in the log
- * 
- *   smbrun calling convention --
- *     INPUT: <oldest_entry_cmd> <log name> <policy handle>
- *     OUTPUT: If there are entries in the event log, the index of the
- *             oldest entry. Must be 1 or greater.
- *             If there are no entries in the log, returns a 0
- */
-
-static BOOL get_oldest_entry_hook( EventlogInfo * info )
+static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info )
 {
 
        /* it's the same thing */
        return get_num_records_hook( info );
 }
 
-
-/********************************************************************
- ********************************************************************/
-
-/**
- * Callout to close the specified event log
- * 
- *   smbrun calling convention --
- *     INPUT: <close_cmd> <log name> <policy handle>
- *     OUTPUT: the string "SUCCESS" if the command succeeded
- *             no such string if there was a failure.
- */
-
-static BOOL close_eventlog_hook( EventlogInfo * info )
-{
-
-       return True;
-}
-
 /********************************************************************
  ********************************************************************/
 
@@ -628,69 +550,6 @@ static BOOL add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u,
        return True;
 }
 
-/********************************************************************
- ********************************************************************/
-
-/**
- * Callout to clear (and optionally backup) a specified event log
- *
- *   smbrun calling convention --
- *     INPUT:  <clear_eventlog_cmd> <log name> <policy handle>
- *     OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
- *             Otherwise it is assumed to have failed
- *
- *     INPUT:  <clear_eventlog_cmd> <log name> <backup file> <policy handle>
- *     OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
- *             Otherwise it is assumed to have failed
- *             The given log is copied to that location on the server. See comments for
- *               eventlog_io_q_clear_eventlog for info about odd file name behavior
- */
-static BOOL clear_eventlog_hook( EventlogInfo * info,
-                                pstring backup_file_name )
-{
-
-       int i;
-
-
-       if ( !info )
-               return False;
-       DEBUG( 3, ( "There are %d event logs\n", nlogs ) );
-       for ( i = 0; i < nlogs; i++ ) {
-               DEBUG( 3,
-                      ( "Comparing Eventlog %s,  %s\n", info->logname,
-                        ttdb[i].logname ) );
-               if ( !StrCaseCmp( info->logname, ttdb[i].logname ) ) {
-                       /* close the current one, reinit */
-                       tdb_close( ttdb[i].log_tdb );
-                       DEBUG( 3,
-                              ( "Closing Eventlog %s, file-on-disk %s\n",
-                                info->logname, ttdb[i].tdbfname ) );
-                       ttdb[i].log_tdb =
-                               init_eventlog_tdb( ttdb[i].tdbfname );
-                       return True;
-               }
-       }
-
-       return False;           /* not found */
-       /* TODO- do something with the backup file name */
-
-}
-
-/*******************************************************************
- *******************************************************************/
-
-static int eventlog_size( char *eventlog_name )
-{
-       TDB_CONTEXT *tdb;
-
-       if ( !eventlog_name )
-               return 0;
-       tdb = tdb_of( eventlog_name );
-       if ( !tdb )
-               return 0;
-       return eventlog_tdb_size( tdb, NULL, NULL );
-}
-
 /********************************************************************
  ********************************************************************/
 
@@ -698,83 +557,81 @@ WERROR _eventlog_open_eventlog( pipes_struct * p,
                                EVENTLOG_Q_OPEN_EVENTLOG * q_u,
                                EVENTLOG_R_OPEN_EVENTLOG * r_u )
 {
-       EventlogInfo *info = NULL;
-       fstring str;
-
-       if ( !( info = TALLOC_ZERO_P( NULL, EventlogInfo ) ) )
-               return WERR_NOMEM;
+       fstring servername, logname;
+       EVENTLOG_INFO *info;
+       WERROR wresult;
 
-       fstrcpy( str, global_myname(  ) );
+       fstrcpy( servername, "" );
        if ( q_u->servername.string ) {
-               rpcstr_pull( str, q_u->servername.string->buffer,
-                            sizeof( str ),
+               rpcstr_pull( servername, q_u->servername.string->buffer,
+                            sizeof( servername ),
                             q_u->servername.string->uni_str_len * 2, 0 );
        }
 
-       info->servername = talloc_strdup( info, str );
-
-       fstrcpy( str, "Application" );
+       fstrcpy( logname, "" );
        if ( q_u->logname.string ) {
-               rpcstr_pull( str, q_u->logname.string->buffer,
-                            sizeof( str ),
+               rpcstr_pull( logname, q_u->logname.string->buffer,
+                            sizeof( logname ),
                             q_u->logname.string->uni_str_len * 2, 0 );
        }
-
-       info->logname = talloc_strdup( info, str );
-
-       DEBUG( 1,
-              ( "Size of %s is %d\n", info->logname,
-                eventlog_size( info->logname ) ) );
-
-
-
-       DEBUG( 10,
-              ( "_eventlog_open_eventlog: Using [%s] as the server name.\n",
-                info->servername ) );
-       DEBUG( 10,
-              ( "_eventlog_open_eventlog: Using [%s] as the source log file.\n",
-                info->logname ) );
-
-
-       if ( !create_policy_hnd
-            ( p, &r_u->handle, free_eventlog_info, ( void * ) info ) ) {
-               free_eventlog_info( info );
-               return WERR_NOMEM;
+       
+       DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
+               servername, logname ));
+               
+       /* according to MSDN, if the logfile cannot be found, we should
+         default to the "Application" log */
+         
+       if ( !W_ERROR_IS_OK( wresult = elog_open( p, logname, &r_u->handle )) )
+               return wresult;
+
+       if ( !(info = find_eventlog_info_by_hnd( p, &r_u->handle )) ) {
+               DEBUG(0,("_eventlog_open_eventlog: eventlog (%s) opened but unable to find handle!\n",
+                       logname ));
+               elog_close( p, &r_u->handle );
+               return WERR_BADFID;
        }
 
-       if ( !open_eventlog_hook( info ) ) {
-               close_policy_hnd( p, &r_u->handle );
-               return WERR_BADFILE;
-       }
+       DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info )));
 
-       sync_eventlog_params( info->logname );
-       prune_eventlog( tdb_of( info->logname ) );
+       sync_eventlog_params( info );
+       prune_eventlog( info->tdb );
 
        return WERR_OK;
 }
 
 /********************************************************************
+ This call still needs some work
  ********************************************************************/
 
 WERROR _eventlog_clear_eventlog( pipes_struct * p,
                                 EVENTLOG_Q_CLEAR_EVENTLOG * q_u,
                                 EVENTLOG_R_CLEAR_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
+       EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
        pstring backup_file_name;
 
-       pstrcpy( backup_file_name, "" );
+       if ( !info )
+               return WERR_BADFID;
 
-       if ( q_u->backupfile.string )
-               unistr2_to_ascii( backup_file_name, q_u->backupfile.string,
-                                 sizeof( backup_file_name ) );
+       pstrcpy( backup_file_name, "" );
+       if ( q_u->backupfile.string ) {
+               rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer,
+                            sizeof( backup_file_name ),
+                            q_u->backupfile.string->uni_str_len * 2, 0 );
+       }
 
-       DEBUG( 10,
+       DEBUG( 8,
               ( "_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
                 backup_file_name, info->logname ) );
 
-       if ( !( clear_eventlog_hook( info, backup_file_name ) ) )
-               return WERR_BADFILE;
+#if 0 
+       /* close the current one, reinit */
+
+       tdb_close( info->tdb ); 
+
+       if ( !(info->tdb = elog_init_tdb( ttdb[i].tdbfname )) )
+               return WERR_ACCESS_DENIED;
+#endif
 
        return WERR_OK;
 }
@@ -786,16 +643,7 @@ WERROR _eventlog_close_eventlog( pipes_struct * p,
                                 EVENTLOG_Q_CLOSE_EVENTLOG * q_u,
                                 EVENTLOG_R_CLOSE_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
-
-       if ( !( close_eventlog_hook( info ) ) )
-               return WERR_BADFILE;
-
-       if ( !( close_policy_hnd( p, &q_u->handle ) ) ) {
-               return WERR_BADFID;
-       }
-
-       return WERR_OK;
+       return elog_close( p, &q_u->handle );
 }
 
 /********************************************************************
@@ -805,56 +653,55 @@ WERROR _eventlog_read_eventlog( pipes_struct * p,
                                EVENTLOG_Q_READ_EVENTLOG * q_u,
                                EVENTLOG_R_READ_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
+       EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
        Eventlog_entry entry, *ee_new;
 
        uint32 num_records_read = 0;
        prs_struct *ps;
        int bytes_left, record_number;
-       TDB_CONTEXT *the_tdb;
-
+       TDB_CONTEXT *tdb;
 
        info->flags = q_u->flags;
        ps = &p->out_data.rdata;
 
-
        bytes_left = q_u->max_read_size;
-       the_tdb = tdb_of( info->logname );
-       if ( !the_tdb ) {
-               /* todo handle the error */
-
+       tdb = info->tdb;
+       if ( !tdb ) {
+               return WERR_EVENTLOG_FILE_CORRUPT;
        }
-       /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */
 
+       /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */
 
        record_number = q_u->offset;
 
        while ( bytes_left > 0 ) {
                if ( get_eventlog_record
-                    ( ps, the_tdb, record_number, &entry ) ) {
+                    ( ps, tdb, record_number, &entry ) ) {
                        DEBUG( 8,
                               ( "Retrieved record %d\n", record_number ) );
+                              
                        /* Now see if there is enough room to add */
-                       if ( ( ee_new =
-                              read_package_entry( ps, q_u, r_u,
-                                                  &entry ) ) == NULL ) {
+                       ee_new = read_package_entry( ps, q_u, r_u,&entry );
+                       if ( !ee_new )
                                return WERR_NOMEM;
 
-                       }
-
                        if ( r_u->num_bytes_in_resp + ee_new->record.length >
                             q_u->max_read_size ) {
                                r_u->bytes_in_next_record =
                                        ee_new->record.length;
+                                       
                                /* response would be too big to fit in client-size buffer */
+                               
                                bytes_left = 0;
                                break;
                        }
+                       
                        add_record_to_resp( r_u, ee_new );
                        bytes_left -= ee_new->record.length;
                        ZERO_STRUCT( entry );
                        num_records_read =
                                r_u->num_records - num_records_read;
+                               
                        DEBUG( 10,
                               ( "_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
                                 num_records_read, r_u->num_records,
@@ -866,13 +713,12 @@ WERROR _eventlog_read_eventlog( pipes_struct * p,
                }
 
 
-               if ( info->flags & EVENTLOG_FORWARDS_READ ) {
+               if ( info->flags & EVENTLOG_FORWARDS_READ )
                        record_number++;
-               } else {
+               else
                        record_number--;
-               }
-
        }
+       
        return WERR_OK;
 }
 
@@ -883,7 +729,7 @@ WERROR _eventlog_get_oldest_entry( pipes_struct * p,
                                   EVENTLOG_Q_GET_OLDEST_ENTRY * q_u,
                                   EVENTLOG_R_GET_OLDEST_ENTRY * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
+       EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
 
        if ( !( get_oldest_entry_hook( info ) ) )
                return WERR_BADFILE;
@@ -900,7 +746,7 @@ WERROR _eventlog_get_num_records( pipes_struct * p,
                                  EVENTLOG_Q_GET_NUM_RECORDS * q_u,
                                  EVENTLOG_R_GET_NUM_RECORDS * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
+       EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
 
        if ( !( get_num_records_hook( info ) ) )
                return WERR_BADFILE;
index 818bf95b3f9e7542ab15fc5e7aaaf2cc7d7a531a..ffb1698394464e6d23921da7a655d5a0964cb921 100644 (file)
@@ -4182,3 +4182,58 @@ BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_ST
        /* Finally check other write access. */
        return (psbuf->st_mode & S_IWOTH) ? True : False;
 }
+
+/********************************************************************
+ Pull the NT ACL from a file on disk or the OpenEventlog() access
+ check.  Caller is responsible for freeing the returned security
+ descriptor via TALLOC_FREE().  This is designed for dealing with 
+ user space access checks in smbd outside of the VFS.  For example,
+ checking access rights in OpenEventlog().
+ Assume we are dealing with files (for now)
+********************************************************************/
+
+SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
+{
+       SEC_DESC *psd, *ret_sd;
+       size_t sd_size;
+       connection_struct conn;
+       files_struct finfo;
+       struct fd_handle fh;
+       fstring path;
+       pstring filename;
+       
+       ZERO_STRUCT( conn );
+       conn.service = -1;
+       
+       if ( !(conn.mem_ctx = talloc_init( "novfs_get_nt_acl" )) ) {
+               DEBUG(0,("novfs_get_nt_acl: talloc() failed!\n"));
+               return NULL;
+       }
+       
+       fstrcpy( path, "/" );
+       string_set(&conn.connectpath, path);
+       
+       if (!smbd_vfs_init(&conn)) {
+               DEBUG(0,("novfs_get_nt_acl: Unable to create a fake connection struct!\n"));
+               return NULL;
+        }
+       
+       ZERO_STRUCT( finfo );
+       ZERO_STRUCT( fh );
+       
+       finfo.fnum = -1;
+       finfo.conn = &conn;
+       finfo.fh = &fh;
+       finfo.fh->fd = -1;
+       pstrcpy( filename, fname );
+       finfo.fsp_name = filename;
+       
+       sd_size = get_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd );
+       
+       ret_sd = dup_sec_desc( ctx, psd );
+       
+       conn_free_internal( &conn );
+       
+       return ret_sd;
+}
diff --git a/source3/utils/wr_eventlog.c b/source3/utils/wr_eventlog.c
new file mode 100644 (file)
index 0000000..bb3c1bc
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Samba Unix/Linux SMB client utility 
+ * Write Eventlog records to a tdb
+ *
+ * Copyright (C) Brian Moran                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.
+ */
+
+
+#include "includes.h"
+
+#undef  DBGC_CLASS
+#define DBGC_CLASS DBGC_UTIL_EVENTLOG
+
+Eventlog_entry ee;
+
+extern int optind;
+extern char *optarg;
+
+int opt_debug = 0;
+
+static void usage( char *s )
+{
+       printf( "\nUsage: %s [-d] [-h] <Eventlog Name>\n", s );
+       printf( "\t-d\tturn debug on\n" );
+       printf( "\t-h\tdisplay help\n\n" );
+}
+
+static void display_eventlog_names( void )
+{
+       const char **elogs;
+       int i;
+
+       elogs = lp_eventlog_list(  );
+       printf( "Active eventlog names (from smb.conf):\n" );
+       printf( "--------------------------------------\n" );
+       for ( i = 0; elogs[i]; i++ ) {
+               printf( "\t%s\n", elogs[i] );
+       }
+}
+
+int main( int argc, char *argv[] )
+{
+       FILE *f1;
+
+       /* fixed constants are bad bad bad  */
+       pstring linein;
+       BOOL is_eor;
+       int pret, opt;
+       int rcnum;
+       char *argfname, *exename;
+       char *tdbname;
+
+
+       TDB_CONTEXT *elog_tdb;
+
+       opt_debug = 0;          /* todo set this from getopts */
+
+
+       lp_load( dyn_CONFIGFILE, True, False, False );
+
+       exename = argv[0];
+
+       while ( ( opt = getopt( argc, argv, "dh" ) ) != -1 ) {
+               switch ( opt ) {
+               case 'h':
+                       usage( argv[0] );
+                       display_eventlog_names(  );
+                       exit( 0 );
+                       break;
+
+               case 'd':
+                       opt_debug = 1;
+                       break;
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if ( argc < 1 ) {
+               usage( exename );
+               exit( 1 );
+       }
+
+
+
+       f1 = stdin;
+
+       if ( !f1 ) {
+               printf( "Can't open STDIN\n" );
+               return -1;
+       }
+
+
+       if ( opt_debug ) {
+               printf( "Starting %s for eventlog [%s]\n", exename, argv[0] );
+               display_eventlog_names(  );
+       }
+
+       argfname = argv[0];
+
+       if ( !(elog_tdb = elog_open_tdb( argfname ) ) ) {
+               printf( "can't open the eventlog TDB (%s)\n", tdbname );
+               return -1;
+       }
+
+       ZERO_STRUCT( ee );      /* MUST initialize between records */
+
+       while ( !feof( f1 ) ) {
+               fgets( linein, sizeof( linein ) - 1, f1 );
+               linein[strlen( linein ) - 1] = 0;       /* whack the line delimiter */
+
+               if ( opt_debug )
+                       printf( "Read line [%s]\n", linein );
+
+               is_eor = False;
+
+               pret = parse_logentry( ( char * ) &linein, &ee, &is_eor );
+
+               if ( is_eor ) {
+                       fixup_eventlog_entry( &ee );
+
+                       if ( opt_debug )
+                               printf( "record number [%d], tg [%d] , tw [%d]\n", 
+                                       ee.record.record_number, 
+                                       ee.record.time_generated, 
+                                       ee.record.time_written );
+
+                       if ( ee.record.time_generated != 0 ) {
+
+                               /* printf("Writing to the event log\n"); */
+
+                               rcnum = write_eventlog_tdb( elog_tdb, &ee ); 
+                               if ( !rcnum ) {
+                                       printf( "Can't write to the event log\n" );
+                               } else {
+                                       if ( opt_debug )
+                                               printf( "Wrote record %d\n",
+                                                       rcnum );
+                               }
+                       } else {
+                               if ( opt_debug )
+                                       printf( "<null record>\n" );
+                       }
+                       ZERO_STRUCT( ee );      /* MUST initialize between records */
+               }
+       }
+
+       tdb_close( elog_tdb );
+
+       return 0;
+}