rpc_server/srv_eventlog_lib.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  Eventlog utility  routines
00004  *  Copyright (C) Marcin Krzysztof Porwit    2005,
00005  *  Copyright (C) Brian Moran                2005.
00006  *  Copyright (C) Gerald (Jerry) Carter      2005.
00007  *  
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *  
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *  
00018  *  You should have received a copy of the GNU General Public License
00019  *  along with this program; if not, write to the Free Software
00020  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021  */
00022 
00023 #include "includes.h"
00024 
00025 /* maintain a list of open eventlog tdbs with reference counts */
00026 
00027 static ELOG_TDB *open_elog_list;
00028 
00029 /********************************************************************
00030  Init an Eventlog TDB, and return it. If null, something bad 
00031  happened.
00032 ********************************************************************/
00033 
00034 TDB_CONTEXT *elog_init_tdb( char *tdbfilename )
00035 {
00036         TDB_CONTEXT *tdb;
00037 
00038         DEBUG(10,("elog_init_tdb: Initializing eventlog tdb (%s)\n",
00039                 tdbfilename));
00040 
00041         tdb = tdb_open_log( tdbfilename, 0, TDB_DEFAULT, 
00042                 O_RDWR|O_CREAT|O_TRUNC, 0660 );
00043 
00044         if ( !tdb ) {
00045                 DEBUG( 0, ( "Can't open tdb for [%s]\n", tdbfilename ) );
00046                 return NULL;
00047         }
00048 
00049         /* initialize with defaults, copy real values in here from registry */
00050 
00051         tdb_store_int32( tdb, EVT_OLDEST_ENTRY, 1 );
00052         tdb_store_int32( tdb, EVT_NEXT_RECORD, 1 );
00053         tdb_store_int32( tdb, EVT_MAXSIZE, 0x80000 );
00054         tdb_store_int32( tdb, EVT_RETENTION, 0x93A80 );
00055 
00056         tdb_store_int32( tdb, EVT_VERSION, EVENTLOG_DATABASE_VERSION_V1 );
00057 
00058         return tdb;
00059 }
00060 
00061 /********************************************************************
00062  make the tdb file name for an event log, given destination buffer 
00063  and size. Caller must free memory.
00064 ********************************************************************/
00065 
00066 char *elog_tdbname( const char *name )
00067 {
00068         fstring path;
00069         char *tdb_fullpath;
00070         char *eventlogdir = lock_path( "eventlog" );
00071         
00072         pstr_sprintf( path, "%s/%s.tdb", eventlogdir, name );
00073         strlower_m( path );
00074         tdb_fullpath = SMB_STRDUP( path );
00075         
00076         return tdb_fullpath;
00077 }
00078 
00079 
00080 /********************************************************************
00081  this function is used to count up the number of bytes in a 
00082  particular TDB
00083 ********************************************************************/
00084 
00085 struct trav_size_struct {
00086         int size;
00087         int rec_count;
00088 };
00089 
00090 static int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data,
00091                           void *state )
00092 {
00093         struct trav_size_struct  *tsize = state;
00094         
00095         tsize->size += data.dsize;
00096         tsize->rec_count++;
00097         
00098         return 0;
00099 }
00100 
00101 /********************************************************************
00102  returns the size of the eventlog, and if MaxSize is a non-null 
00103  ptr, puts the MaxSize there. This is purely a way not to have yet 
00104  another function that solely reads the maxsize of the eventlog. 
00105  Yeah, that's it.
00106 ********************************************************************/
00107 
00108 int elog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention )
00109 {
00110         struct trav_size_struct tsize;
00111         
00112         if ( !tdb )
00113                 return 0;
00114                 
00115         ZERO_STRUCT( tsize );
00116 
00117         tdb_traverse( tdb, eventlog_tdb_size_fn, &tsize );
00118 
00119         if ( MaxSize != NULL ) {
00120                 *MaxSize = tdb_fetch_int32( tdb, EVT_MAXSIZE );
00121         }
00122 
00123         if ( Retention != NULL ) {
00124                 *Retention = tdb_fetch_int32( tdb, EVT_RETENTION );
00125         }
00126 
00127         DEBUG( 1,
00128                ( "eventlog size: [%d] for [%d] records\n", tsize.size,
00129                  tsize.rec_count ) );
00130         return tsize.size;
00131 }
00132 
00133 /********************************************************************
00134  Discard early event logs until we have enough for 'needed' bytes...
00135  NO checking done beforehand to see that we actually need to do 
00136  this, and it's going to pluck records one-by-one. So, it's best 
00137  to determine that this needs to be done before doing it.  
00138 
00139  Setting whack_by_date to True indicates that eventlogs falling 
00140  outside of the retention range need to go...
00141  
00142  return True if we made enough room to accommodate needed bytes
00143 ********************************************************************/
00144 
00145 BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
00146                              BOOL whack_by_date )
00147 {
00148         int start_record, i, new_start;
00149         int end_record;
00150         int nbytes, reclen, len, Retention, MaxSize;
00151         int tresv1, trecnum, timegen, timewr;
00152         TDB_DATA key, ret;
00153         TALLOC_CTX *mem_ctx = NULL;
00154         time_t current_time, exp_time;
00155 
00156         /* discard some eventlogs */
00157 
00158         /* read eventlogs from oldest_entry -- there can't be any discontinuity in recnos,
00159            although records not necessarily guaranteed to have successive times */
00160         /* */
00161         mem_ctx = talloc_init( "make_way_for_eventlogs" );      /* Homage to BPG */
00162 
00163         if ( mem_ctx == NULL )
00164                 return False;   /* can't allocate memory indicates bigger problems */
00165         /* lock */
00166         tdb_lock_bystring_with_timeout( the_tdb, EVT_NEXT_RECORD, 1 );
00167         /* read */
00168         end_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
00169         start_record = tdb_fetch_int32( the_tdb, EVT_OLDEST_ENTRY );
00170         Retention = tdb_fetch_int32( the_tdb, EVT_RETENTION );
00171         MaxSize = tdb_fetch_int32( the_tdb, EVT_MAXSIZE );
00172 
00173         time( &current_time );
00174 
00175         /* calculate ... */
00176         exp_time = current_time - Retention;    /* discard older than exp_time */
00177 
00178         /* todo - check for sanity in next_record */
00179         nbytes = 0;
00180 
00181         DEBUG( 3,
00182                ( "MaxSize [%d] Retention [%d] Current Time [%d]  exp_time [%d]\n",
00183                  MaxSize, Retention, (uint32)current_time, (uint32)exp_time ) );
00184         DEBUG( 3,
00185                ( "Start Record [%d] End Record [%d]\n", start_record,
00186                  end_record ) );
00187 
00188         for ( i = start_record; i < end_record; i++ ) {
00189                 /* read a record, add the amt to nbytes */
00190                 key.dsize = sizeof( int32 );
00191                 key.dptr = ( char * ) ( int32 * ) & i;
00192                 ret = tdb_fetch( the_tdb, key );
00193                 if ( ret.dsize == 0 ) {
00194                         DEBUG( 8,
00195                                ( "Can't find a record for the key, record [%d]\n",
00196                                  i ) );
00197                         tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
00198                         return False;
00199                 }
00200                 nbytes += ret.dsize;    /* note this includes overhead */
00201 
00202                 len = tdb_unpack( ret.dptr, ret.dsize, "ddddd", &reclen,
00203                                   &tresv1, &trecnum, &timegen, &timewr );
00204                 if (len == -1) {
00205                         DEBUG( 10,("make_way_for_eventlogs: tdb_unpack failed.\n"));
00206                         tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
00207                         return False;
00208                 }
00209 
00210                 DEBUG( 8,
00211                        ( "read record %d, record size is [%d], total so far [%d]\n",
00212                          i, reclen, nbytes ) );
00213 
00214                 SAFE_FREE( ret.dptr );
00215 
00216                 /* note that other servers may just stop writing records when the size limit
00217                    is reached, and there are no records older than 'retention'. This doesn't 
00218                    like a very useful thing to do, so instead we whack (as in sleeps with the 
00219                    fishes) just enough records to fit the what we need.  This behavior could
00220                    be changed to 'match', if the need arises. */
00221 
00222                 if ( !whack_by_date && ( nbytes >= needed ) )
00223                         break;  /* done */
00224                 if ( whack_by_date && ( timegen >= exp_time ) )
00225                         break;  /* done */
00226         }
00227 
00228         DEBUG( 3,
00229                ( "nbytes [%d] needed [%d] start_record is [%d], should be set to [%d]\n",
00230                  nbytes, needed, start_record, i ) );
00231         /* todo - remove eventlog entries here and set starting record to start_record... */
00232         new_start = i;
00233         if ( start_record != new_start ) {
00234                 for ( i = start_record; i < new_start; i++ ) {
00235                         key.dsize = sizeof( int32 );
00236                         key.dptr = ( char * ) ( int32 * ) & i;
00237                         tdb_delete( the_tdb, key );
00238                 }
00239 
00240                 tdb_store_int32( the_tdb, EVT_OLDEST_ENTRY, new_start );
00241         }
00242         tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
00243         return True;
00244 }
00245 
00246 /********************************************************************
00247   some hygiene for an eventlog - see how big it is, and then 
00248   calculate how many bytes we need to remove                   
00249 ********************************************************************/
00250 
00251 BOOL prune_eventlog( TDB_CONTEXT * tdb )
00252 {
00253         int MaxSize, Retention, CalcdSize;
00254 
00255         if ( !tdb ) {
00256                 DEBUG( 4, ( "No eventlog tdb handle\n" ) );
00257                 return False;
00258         }
00259 
00260         CalcdSize = elog_tdb_size( tdb, &MaxSize, &Retention );
00261         DEBUG( 3,
00262                ( "Calculated size [%d] MaxSize [%d]\n", CalcdSize,
00263                  MaxSize ) );
00264 
00265         if ( CalcdSize > MaxSize ) {
00266                 return make_way_for_eventlogs( tdb, CalcdSize - MaxSize,
00267                                                False );
00268         }
00269 
00270         return make_way_for_eventlogs( tdb, 0, True );
00271 }
00272 
00273 /********************************************************************
00274 ********************************************************************/
00275 
00276 BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
00277 {
00278         int calcd_size;
00279         int MaxSize, Retention;
00280 
00281         /* see if we can write to the eventlog -- do a policy enforcement */
00282         if ( !tdb )
00283                 return False;   /* tdb is null, so we can't write to it */
00284 
00285 
00286         if ( needed < 0 )
00287                 return False;
00288         MaxSize = 0;
00289         Retention = 0;
00290 
00291         calcd_size = elog_tdb_size( tdb, &MaxSize, &Retention );
00292 
00293         if ( calcd_size <= MaxSize )
00294                 return True;    /* you betcha */
00295         if ( calcd_size + needed < MaxSize )
00296                 return True;
00297 
00298         if ( Retention == 0xffffffff ) {
00299                 return False;   /* see msdn - we can't write no room, discard */
00300         }
00301         /*
00302            note don't have to test, but always good to show intent, in case changes needed
00303            later
00304          */
00305 
00306         if ( Retention == 0x00000000 ) {
00307                 /* discard record(s) */
00308                 /* todo  - decide when to remove a bunch vs. just what we need... */
00309                 return make_way_for_eventlogs( tdb, calcd_size - MaxSize,
00310                                                True );
00311         }
00312 
00313         return make_way_for_eventlogs( tdb, calcd_size - MaxSize, False );
00314 }
00315 
00316 /*******************************************************************
00317 *******************************************************************/
00318 
00319 ELOG_TDB *elog_open_tdb( char *logname, BOOL force_clear )
00320 {
00321         TDB_CONTEXT *tdb = NULL;
00322         uint32 vers_id;
00323         ELOG_TDB *ptr;
00324         char *tdbfilename;
00325         pstring tdbpath;
00326         ELOG_TDB *tdb_node = NULL;
00327         char *eventlogdir;
00328 
00329         /* first see if we have an open context */
00330         
00331         for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
00332                 if ( strequal( ptr->name, logname ) ) {
00333                         ptr->ref_count++;
00334 
00335                         /* trick to alow clearing of the eventlog tdb.
00336                            The force_clear flag should imply that someone
00337                            has done a force close.  So make sure the tdb 
00338                            is NULL.  If this is a normal open, then just 
00339                            return the existing reference */
00340 
00341                         if ( force_clear ) {
00342                                 SMB_ASSERT( ptr->tdb == NULL );
00343                                 break;
00344                         }
00345                         else
00346                                 return ptr;
00347                 }
00348         }
00349         
00350         /* make sure that the eventlog dir exists */
00351         
00352         eventlogdir = lock_path( "eventlog" );
00353         if ( !directory_exist( eventlogdir, NULL ) )
00354                 mkdir( eventlogdir, 0755 );     
00355         
00356         /* get the path on disk */
00357         
00358         tdbfilename = elog_tdbname( logname );
00359         pstrcpy( tdbpath, tdbfilename );
00360         SAFE_FREE( tdbfilename );
00361 
00362         DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n", 
00363                 tdbpath, force_clear?"True":"False" ));
00364                 
00365         /* the tdb wasn't already open or this is a forced clear open */
00366 
00367         if ( !force_clear ) {
00368 
00369                 tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );      
00370                 if ( tdb ) {
00371                         vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
00372 
00373                         if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
00374                                 DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
00375                                         vers_id, tdbpath));
00376                                 tdb_close( tdb );
00377                                 tdb = elog_init_tdb( tdbpath );
00378                         }
00379                 }
00380         }
00381         
00382         if ( !tdb )
00383                 tdb = elog_init_tdb( tdbpath );
00384         
00385         /* if we got a valid context, then add it to the list */
00386         
00387         if ( tdb ) {
00388                 /* on a forced clear, just reset the tdb context if we already
00389                    have an open entry in the list */
00390 
00391                 if ( ptr ) {
00392                         ptr->tdb = tdb;
00393                         return ptr;
00394                 }
00395 
00396                 if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
00397                         DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
00398                         tdb_close( tdb );
00399                         return NULL;
00400                 }
00401                 
00402                 tdb_node->name = talloc_strdup( tdb_node, logname );
00403                 tdb_node->tdb = tdb;
00404                 tdb_node->ref_count = 1;
00405                 
00406                 DLIST_ADD( open_elog_list, tdb_node );
00407         }
00408 
00409         return tdb_node;
00410 }
00411 
00412 /*******************************************************************
00413  Wrapper to handle reference counts to the tdb
00414 *******************************************************************/
00415 
00416 int elog_close_tdb( ELOG_TDB *etdb, BOOL force_close )
00417 {
00418         TDB_CONTEXT *tdb;
00419 
00420         if ( !etdb )
00421                 return 0;
00422                 
00423         etdb->ref_count--;
00424         
00425         SMB_ASSERT( etdb->ref_count >= 0 );
00426 
00427         if ( etdb->ref_count == 0 ) {
00428                 tdb = etdb->tdb;
00429                 DLIST_REMOVE( open_elog_list, etdb );
00430                 TALLOC_FREE( etdb );
00431                 return tdb_close( tdb );
00432         }
00433         
00434         if ( force_close ) {
00435                 tdb = etdb->tdb;
00436                 etdb->tdb = NULL;
00437                 return tdb_close( tdb );
00438         }
00439 
00440         return 0;
00441 }
00442 
00443 
00444 /*******************************************************************
00445  write an eventlog entry. Note that we have to lock, read next 
00446  eventlog, increment, write, write the record, unlock 
00447  
00448  coming into this, ee has the eventlog record, and the auxilliary date 
00449  (computer name, etc.) filled into the other structure. Before packing 
00450  into a record, this routine will calc the appropriate padding, etc., 
00451  and then blast out the record in a form that can be read back in
00452 *******************************************************************/
00453  
00454 #define MARGIN 512
00455 
00456 int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
00457 {
00458         int32 next_record;
00459         uint8 *packed_ee;
00460         TALLOC_CTX *mem_ctx = NULL;
00461         TDB_DATA kbuf, ebuf;
00462         uint32 n_packed;
00463 
00464         if ( !ee )
00465                 return 0;
00466 
00467         mem_ctx = talloc_init( "write_eventlog_tdb" );
00468 
00469         if ( mem_ctx == NULL )
00470                 return 0;
00471 
00472         if ( !ee )
00473                 return 0;
00474         /* discard any entries that have bogus time, which usually indicates a bogus entry as well. */
00475         if ( ee->record.time_generated == 0 )
00476                 return 0;
00477 
00478         /* todo - check for sanity in next_record */
00479 
00480         fixup_eventlog_entry( ee );
00481 
00482         if ( !can_write_to_eventlog( the_tdb, ee->record.length ) ) {
00483                 DEBUG( 3, ( "Can't write to Eventlog, no room \n" ) );
00484                 talloc_destroy( mem_ctx );
00485                 return 0;
00486         }
00487 
00488         /* alloc mem for the packed version */
00489         packed_ee = (uint8 *)TALLOC( mem_ctx, ee->record.length + MARGIN );
00490         if ( !packed_ee ) {
00491                 talloc_destroy( mem_ctx );
00492                 return 0;
00493         }
00494 
00495         /* need to read the record number and insert it into the entry here */
00496 
00497         /* lock */
00498         tdb_lock_bystring_with_timeout( the_tdb, EVT_NEXT_RECORD, 1 );
00499         /* read */
00500         next_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
00501 
00502         n_packed =
00503                 tdb_pack( (char *)packed_ee, ee->record.length + MARGIN,
00504                           "ddddddwwwwddddddBBdBBBd", ee->record.length,
00505                           ee->record.reserved1, next_record,
00506                           ee->record.time_generated, ee->record.time_written,
00507                           ee->record.event_id, ee->record.event_type,
00508                           ee->record.num_strings, ee->record.event_category,
00509                           ee->record.reserved2,
00510                           ee->record.closing_record_number,
00511                           ee->record.string_offset,
00512                           ee->record.user_sid_length,
00513                           ee->record.user_sid_offset, ee->record.data_length,
00514                           ee->record.data_offset,
00515                           ee->data_record.source_name_len,
00516                           ee->data_record.source_name,
00517                           ee->data_record.computer_name_len,
00518                           ee->data_record.computer_name,
00519                           ee->data_record.sid_padding,
00520                           ee->record.user_sid_length, ee->data_record.sid,
00521                           ee->data_record.strings_len,
00522                           ee->data_record.strings,
00523                           ee->data_record.user_data_len,
00524                           ee->data_record.user_data,
00525                           ee->data_record.data_padding );
00526 
00527         /*DEBUG(3,("write_eventlog_tdb: packed into  %d\n",n_packed)); */
00528 
00529         /* increment the record count */
00530 
00531         kbuf.dsize = sizeof( int32 );
00532         kbuf.dptr = (char * ) & next_record;
00533 
00534         ebuf.dsize = n_packed;
00535         ebuf.dptr = (char *)packed_ee;
00536 
00537         if ( tdb_store( the_tdb, kbuf, ebuf, 0 ) ) {
00538                 /* DEBUG(1,("write_eventlog_tdb: Can't write record %d to eventlog\n",next_record)); */
00539                 tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
00540                 talloc_destroy( mem_ctx );
00541                 return 0;
00542         }
00543         next_record++;
00544         tdb_store_int32( the_tdb, EVT_NEXT_RECORD, next_record );
00545         tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
00546         talloc_destroy( mem_ctx );
00547         return ( next_record - 1 );
00548 }
00549 
00550 /*******************************************************************
00551  calculate the correct fields etc for an eventlog entry
00552 *******************************************************************/
00553 
00554 void fixup_eventlog_entry( Eventlog_entry * ee )
00555 {
00556         /* fix up the eventlog entry structure as necessary */
00557 
00558         ee->data_record.sid_padding =
00559                 ( ( 4 -
00560                     ( ( ee->data_record.source_name_len +
00561                         ee->data_record.computer_name_len ) % 4 ) ) % 4 );
00562         ee->data_record.data_padding =
00563                 ( 4 -
00564                   ( ( ee->data_record.strings_len +
00565                       ee->data_record.user_data_len ) % 4 ) ) % 4;
00566         ee->record.length = sizeof( Eventlog_record );
00567         ee->record.length += ee->data_record.source_name_len;
00568         ee->record.length += ee->data_record.computer_name_len;
00569         if ( ee->record.user_sid_length == 0 ) {
00570                 /* Should not pad to a DWORD boundary for writing out the sid if there is
00571                    no SID, so just propagate the padding to pad the data */
00572                 ee->data_record.data_padding += ee->data_record.sid_padding;
00573                 ee->data_record.sid_padding = 0;
00574         }
00575         /* DEBUG(10, ("sid_padding is [%d].\n", ee->data_record.sid_padding)); */
00576         /* DEBUG(10, ("data_padding is [%d].\n", ee->data_record.data_padding)); */
00577 
00578         ee->record.length += ee->data_record.sid_padding;
00579         ee->record.length += ee->record.user_sid_length;
00580         ee->record.length += ee->data_record.strings_len;
00581         ee->record.length += ee->data_record.user_data_len;
00582         ee->record.length += ee->data_record.data_padding;
00583         /* need another copy of length at the end of the data */
00584         ee->record.length += sizeof( ee->record.length );
00585 }
00586 
00587 /********************************************************************
00588  Note that it's a pretty good idea to initialize the Eventlog_entry 
00589  structure to zero's before calling parse_logentry on an batch of 
00590  lines that may resolve to a record.  ALSO, it's a good idea to 
00591  remove any linefeeds (that's EOL to you and me) on the lines 
00592  going in.
00593 ********************************************************************/
00594 
00595 BOOL parse_logentry( char *line, Eventlog_entry * entry, BOOL * eor )
00596 {
00597         char *start = NULL, *stop = NULL;
00598         pstring temp;
00599         int temp_len = 0;
00600 
00601         start = line;
00602 
00603         /* empty line signyfiying record delimeter, or we're at the end of the buffer */
00604         if ( start == NULL || strlen( start ) == 0 ) {
00605                 DEBUG( 6,
00606                        ( "parse_logentry: found end-of-record indicator.\n" ) );
00607                 *eor = True;
00608                 return True;
00609         }
00610         if ( !( stop = strchr( line, ':' ) ) ) {
00611                 return False;
00612         }
00613 
00614         DEBUG( 6, ( "parse_logentry: trying to parse [%s].\n", line ) );
00615 
00616         if ( 0 == strncmp( start, "LEN", stop - start ) ) {
00617                 /* This will get recomputed later anyway -- probably not necessary */
00618                 entry->record.length = atoi( stop + 1 );
00619         } else if ( 0 == strncmp( start, "RS1", stop - start ) ) {
00620                 /* For now all these reserved entries seem to have the same value,
00621                    which can be hardcoded to int(1699505740) for now */
00622                 entry->record.reserved1 = atoi( stop + 1 );
00623         } else if ( 0 == strncmp( start, "RCN", stop - start ) ) {
00624                 entry->record.record_number = atoi( stop + 1 );
00625         } else if ( 0 == strncmp( start, "TMG", stop - start ) ) {
00626                 entry->record.time_generated = atoi( stop + 1 );
00627         } else if ( 0 == strncmp( start, "TMW", stop - start ) ) {
00628                 entry->record.time_written = atoi( stop + 1 );
00629         } else if ( 0 == strncmp( start, "EID", stop - start ) ) {
00630                 entry->record.event_id = atoi( stop + 1 );
00631         } else if ( 0 == strncmp( start, "ETP", stop - start ) ) {
00632                 if ( strstr( start, "ERROR" ) ) {
00633                         entry->record.event_type = EVENTLOG_ERROR_TYPE;
00634                 } else if ( strstr( start, "WARNING" ) ) {
00635                         entry->record.event_type = EVENTLOG_WARNING_TYPE;
00636                 } else if ( strstr( start, "INFO" ) ) {
00637                         entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
00638                 } else if ( strstr( start, "AUDIT_SUCCESS" ) ) {
00639                         entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
00640                 } else if ( strstr( start, "AUDIT_FAILURE" ) ) {
00641                         entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
00642                 } else if ( strstr( start, "SUCCESS" ) ) {
00643                         entry->record.event_type = EVENTLOG_SUCCESS;
00644                 } else {
00645                         /* some other eventlog type -- currently not defined in MSDN docs, so error out */
00646                         return False;
00647                 }
00648         }
00649 
00650 /*
00651   else if(0 == strncmp(start, "NST", stop - start))
00652   {
00653   entry->record.num_strings = atoi(stop + 1);
00654   }
00655 */
00656         else if ( 0 == strncmp( start, "ECT", stop - start ) ) {
00657                 entry->record.event_category = atoi( stop + 1 );
00658         } else if ( 0 == strncmp( start, "RS2", stop - start ) ) {
00659                 entry->record.reserved2 = atoi( stop + 1 );
00660         } else if ( 0 == strncmp( start, "CRN", stop - start ) ) {
00661                 entry->record.closing_record_number = atoi( stop + 1 );
00662         } else if ( 0 == strncmp( start, "USL", stop - start ) ) {
00663                 entry->record.user_sid_length = atoi( stop + 1 );
00664         } else if ( 0 == strncmp( start, "SRC", stop - start ) ) {
00665                 memset( temp, 0, sizeof( temp ) );
00666                 stop++;
00667                 while ( isspace( stop[0] ) ) {
00668                         stop++;
00669                 }
00670                 temp_len = strlen( stop );
00671                 strncpy( temp, stop, temp_len );
00672                 rpcstr_push( ( void * ) ( entry->data_record.source_name ),
00673                              temp, sizeof( entry->data_record.source_name ),
00674                              STR_TERMINATE );
00675                 entry->data_record.source_name_len =
00676                         ( strlen_w( entry->data_record.source_name ) * 2 ) +
00677                         2;
00678         } else if ( 0 == strncmp( start, "SRN", stop - start ) ) {
00679                 memset( temp, 0, sizeof( temp ) );
00680                 stop++;
00681                 while ( isspace( stop[0] ) ) {
00682                         stop++;
00683                 }
00684                 temp_len = strlen( stop );
00685                 strncpy( temp, stop, temp_len );
00686                 rpcstr_push( ( void * ) ( entry->data_record.computer_name ),
00687                              temp, sizeof( entry->data_record.computer_name ),
00688                              STR_TERMINATE );
00689                 entry->data_record.computer_name_len =
00690                         ( strlen_w( entry->data_record.computer_name ) * 2 ) +
00691                         2;
00692         } else if ( 0 == strncmp( start, "SID", stop - start ) ) {
00693                 memset( temp, 0, sizeof( temp ) );
00694                 stop++;
00695                 while ( isspace( stop[0] ) ) {
00696                         stop++;
00697                 }
00698                 temp_len = strlen( stop );
00699                 strncpy( temp, stop, temp_len );
00700                 rpcstr_push( ( void * ) ( entry->data_record.sid ), temp,
00701                              sizeof( entry->data_record.sid ),
00702                              STR_TERMINATE );
00703                 entry->record.user_sid_length =
00704                         ( strlen_w( entry->data_record.sid ) * 2 ) + 2;
00705         } else if ( 0 == strncmp( start, "STR", stop - start ) ) {
00706                 /* skip past initial ":" */
00707                 stop++;
00708                 /* now skip any other leading whitespace */
00709                 while ( isspace( stop[0] ) ) {
00710                         stop++;
00711                 }
00712                 temp_len = strlen( stop );
00713                 memset( temp, 0, sizeof( temp ) );
00714                 strncpy( temp, stop, temp_len );
00715                 rpcstr_push( ( void * ) ( entry->data_record.strings +
00716                                           ( entry->data_record.strings_len / 2 ) ),
00717                              temp,
00718                              sizeof( entry->data_record.strings ) -
00719                              ( entry->data_record.strings_len / 2 ), STR_TERMINATE );
00720                 entry->data_record.strings_len += ( temp_len * 2 ) + 2;
00721                 entry->record.num_strings++;
00722         } else if ( 0 == strncmp( start, "DAT", stop - start ) ) {
00723                 /* skip past initial ":" */
00724                 stop++;
00725                 /* now skip any other leading whitespace */
00726                 while ( isspace( stop[0] ) ) {
00727                         stop++;
00728                 }
00729                 entry->data_record.user_data_len = strlen( stop );
00730                 memset( entry->data_record.user_data, 0,
00731                         sizeof( entry->data_record.user_data ) );
00732                 if ( entry->data_record.user_data_len > 0 ) {
00733                         /* copy no more than the first 1024 bytes */
00734                         if ( entry->data_record.user_data_len >
00735                              sizeof( entry->data_record.user_data ) )
00736                                 entry->data_record.user_data_len =
00737                                         sizeof( entry->data_record.
00738                                                 user_data );
00739                         memcpy( entry->data_record.user_data, stop,
00740                                 entry->data_record.user_data_len );
00741                 }
00742         } else {
00743                 /* some other eventlog entry -- not implemented, so dropping on the floor */
00744                 DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) );
00745                 /* For now return true so that we can keep on parsing this mess. Eventually
00746                    we will return False here. */
00747                 return True;
00748         }
00749         return True;
00750 }

Sambaに対してSat Aug 29 21:23:19 2009に生成されました。  doxygen 1.4.7