00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_RPC_SRV
00027
00028 typedef struct {
00029 char *logname;
00030 ELOG_TDB *etdb;
00031 uint32 current_record;
00032 uint32 num_records;
00033 uint32 oldest_entry;
00034 uint32 flags;
00035 uint32 access_granted;
00036 } EVENTLOG_INFO;
00037
00038
00039
00040
00041 static void free_eventlog_info( void *ptr )
00042 {
00043 EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr;
00044
00045 if ( elog->etdb )
00046 elog_close_tdb( elog->etdb, False );
00047
00048 TALLOC_FREE( elog );
00049 }
00050
00051
00052
00053
00054 static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
00055 POLICY_HND * handle )
00056 {
00057 EVENTLOG_INFO *info;
00058
00059 if ( !find_policy_by_hnd( p, handle, (void **)(void *)&info ) ) {
00060 DEBUG( 2,
00061 ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
00062 return NULL;
00063 }
00064
00065 return info;
00066 }
00067
00068
00069
00070
00071 static BOOL elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
00072 {
00073 char *tdbname = elog_tdbname( info->logname );
00074 SEC_DESC *sec_desc;
00075 BOOL ret;
00076 NTSTATUS ntstatus;
00077
00078 if ( !tdbname )
00079 return False;
00080
00081
00082
00083 sec_desc = get_nt_acl_no_snum( info, tdbname );
00084 SAFE_FREE( tdbname );
00085
00086 if ( !sec_desc ) {
00087 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
00088 tdbname));
00089 return False;
00090 }
00091
00092
00093
00094 if ( geteuid() == sec_initial_uid() ) {
00095 DEBUG(5,("elog_check_access: using root's token\n"));
00096 token = get_root_nt_token();
00097 }
00098
00099
00100
00101 ret = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
00102 &info->access_granted, &ntstatus );
00103
00104 if ( sec_desc )
00105 TALLOC_FREE( sec_desc );
00106
00107 if ( !ret ) {
00108 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
00109 nt_errstr( ntstatus)));
00110 return False;
00111 }
00112
00113
00114
00115 return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
00116 }
00117
00118
00119
00120
00121 static BOOL elog_validate_logname( const char *name )
00122 {
00123 int i;
00124 const char **elogs = lp_eventlog_list();
00125
00126 if (!elogs) {
00127 return False;
00128 }
00129
00130 for ( i=0; elogs[i]; i++ ) {
00131 if ( strequal( name, elogs[i] ) )
00132 return True;
00133 }
00134
00135 return False;
00136 }
00137
00138
00139
00140
00141 static BOOL get_num_records_hook( EVENTLOG_INFO * info )
00142 {
00143 int next_record;
00144 int oldest_record;
00145
00146 if ( !info->etdb ) {
00147 DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
00148 return False;
00149 }
00150
00151
00152
00153 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
00154 next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
00155 oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
00156 tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
00157
00158 DEBUG( 8,
00159 ( "Oldest Record %d; Next Record %d\n", oldest_record,
00160 next_record ) );
00161
00162 info->num_records = ( next_record - oldest_record );
00163 info->oldest_entry = oldest_record;
00164
00165 return True;
00166 }
00167
00168
00169
00170
00171 static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info )
00172 {
00173
00174 return get_num_records_hook( info );
00175 }
00176
00177
00178
00179
00180 static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
00181 {
00182 EVENTLOG_INFO *elog;
00183
00184
00185
00186 if ( !elog_validate_logname( logname ) )
00187 return NT_STATUS_OBJECT_PATH_INVALID;
00188
00189 if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
00190 return NT_STATUS_NO_MEMORY;
00191
00192 elog->logname = talloc_strdup( elog, logname );
00193
00194
00195
00196
00197
00198
00199 become_root();
00200 elog->etdb = elog_open_tdb( elog->logname, False );
00201 unbecome_root();
00202
00203 if ( !elog->etdb ) {
00204
00205
00206
00207 if ( !strequal( logname, ELOG_APPL ) ) {
00208
00209 TALLOC_FREE( elog->logname );
00210
00211 elog->logname = talloc_strdup( elog, ELOG_APPL );
00212
00213
00214 if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
00215 TALLOC_FREE( elog );
00216 return NT_STATUS_ACCESS_DENIED;
00217 }
00218
00219 become_root();
00220 elog->etdb = elog_open_tdb( elog->logname, False );
00221 unbecome_root();
00222 }
00223
00224 if ( !elog->etdb ) {
00225 TALLOC_FREE( elog );
00226 return NT_STATUS_ACCESS_DENIED;
00227 }
00228 }
00229
00230
00231
00232 if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
00233 elog_close_tdb( elog->etdb, False );
00234 TALLOC_FREE( elog );
00235 return NT_STATUS_ACCESS_DENIED;
00236 }
00237
00238
00239
00240 if ( !create_policy_hnd
00241 ( p, hnd, free_eventlog_info, ( void * ) elog ) ) {
00242 free_eventlog_info( elog );
00243 return NT_STATUS_NO_MEMORY;
00244 }
00245
00246
00247
00248 if ( !get_oldest_entry_hook( elog ) ) {
00249 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
00250 "get any information on internal records!\n"));
00251 }
00252
00253 elog->current_record = elog->oldest_entry;
00254
00255 return NT_STATUS_OK;
00256 }
00257
00258
00259
00260
00261 static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd )
00262 {
00263 if ( !( close_policy_hnd( p, hnd ) ) ) {
00264 return NT_STATUS_INVALID_HANDLE;
00265 }
00266
00267 return NT_STATUS_OK;
00268 }
00269
00270
00271
00272
00273 static int elog_size( EVENTLOG_INFO *info )
00274 {
00275 if ( !info || !info->etdb ) {
00276 DEBUG(0,("elog_size: Invalid info* structure!\n"));
00277 return 0;
00278 }
00279
00280 return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
00281 }
00282
00283
00284
00285
00286
00287
00288 static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
00289 int recno, Eventlog_entry * ee )
00290 {
00291 TDB_DATA ret, key;
00292
00293 int srecno;
00294 int reclen;
00295 int len;
00296
00297 pstring *wpsource, *wpcomputer, *wpsid, *wpstrs, *puserdata;
00298
00299 key.dsize = sizeof( int32 );
00300
00301 srecno = recno;
00302 key.dptr = ( char * ) &srecno;
00303
00304 ret = tdb_fetch( tdb, key );
00305
00306 if ( ret.dsize == 0 ) {
00307 DEBUG( 8,
00308 ( "Can't find a record for the key, record %d\n",
00309 recno ) );
00310 return NULL;
00311 }
00312
00313 len = tdb_unpack( ret.dptr, ret.dsize, "d", &reclen );
00314
00315 DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno, len ) );
00316
00317 if ( !len )
00318 return NULL;
00319
00320
00321
00322 if ( !ee )
00323 return NULL;
00324
00325 len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd",
00326 &ee->record.length, &ee->record.reserved1,
00327 &ee->record.record_number,
00328 &ee->record.time_generated,
00329 &ee->record.time_written, &ee->record.event_id,
00330 &ee->record.event_type, &ee->record.num_strings,
00331 &ee->record.event_category, &ee->record.reserved2,
00332 &ee->record.closing_record_number,
00333 &ee->record.string_offset,
00334 &ee->record.user_sid_length,
00335 &ee->record.user_sid_offset,
00336 &ee->record.data_length, &ee->record.data_offset,
00337 &ee->data_record.source_name_len, &wpsource,
00338 &ee->data_record.computer_name_len, &wpcomputer,
00339 &ee->data_record.sid_padding,
00340 &ee->record.user_sid_length, &wpsid,
00341 &ee->data_record.strings_len, &wpstrs,
00342 &ee->data_record.user_data_len, &puserdata,
00343 &ee->data_record.data_padding );
00344 DEBUG( 10,
00345 ( "Read record %d, len in tdb was %d\n",
00346 ee->record.record_number, len ) );
00347
00348
00349
00350
00351 if ( wpcomputer )
00352 memcpy( ee->data_record.computer_name, wpcomputer,
00353 ee->data_record.computer_name_len );
00354 if ( wpsource )
00355 memcpy( ee->data_record.source_name, wpsource,
00356 ee->data_record.source_name_len );
00357
00358 if ( wpsid )
00359 memcpy( ee->data_record.sid, wpsid,
00360 ee->record.user_sid_length );
00361 if ( wpstrs )
00362 memcpy( ee->data_record.strings, wpstrs,
00363 ee->data_record.strings_len );
00364
00365
00366 if ( puserdata )
00367 memcpy( ee->data_record.user_data, puserdata,
00368 ee->data_record.user_data_len );
00369
00370 SAFE_FREE( wpcomputer );
00371 SAFE_FREE( wpsource );
00372 SAFE_FREE( wpsid );
00373 SAFE_FREE( wpstrs );
00374 SAFE_FREE( puserdata );
00375
00376 DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) );
00377 DEBUG( 10,
00378 ( "get_eventlog_record: computer_name %d is ",
00379 ee->data_record.computer_name_len ) );
00380 SAFE_FREE( ret.dptr );
00381 return ee;
00382 }
00383
00384
00385
00386
00387
00388
00389 static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
00390 {
00391 pstring path;
00392 uint32 uiMaxSize;
00393 uint32 uiRetention;
00394 REGISTRY_KEY *keyinfo;
00395 REGISTRY_VALUE *val;
00396 REGVAL_CTR *values;
00397 WERROR wresult;
00398 char *elogname = info->logname;
00399
00400 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
00401
00402 if ( !info->etdb ) {
00403 DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
00404 return False;
00405 }
00406
00407
00408 uiMaxSize = 0x80000;
00409 uiRetention = 604800;
00410
00411
00412
00413
00414
00415
00416 pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname );
00417
00418 wresult =
00419 regkey_open_internal( &keyinfo, path, get_root_nt_token( ),
00420 REG_KEY_READ );
00421
00422 if ( !W_ERROR_IS_OK( wresult ) ) {
00423 DEBUG( 4,
00424 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
00425 path, dos_errstr( wresult ) ) );
00426 return False;
00427 }
00428
00429 if ( !( values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR ) ) ) {
00430 TALLOC_FREE( keyinfo );
00431 DEBUG( 0, ( "control_eventlog_hook: talloc() failed!\n" ) );
00432
00433 return False;
00434 }
00435 fetch_reg_values( keyinfo, values );
00436
00437 if ( ( val = regval_ctr_getvalue( values, "Retention" ) ) != NULL )
00438 uiRetention = IVAL( regval_data_p( val ), 0 );
00439
00440 if ( ( val = regval_ctr_getvalue( values, "MaxSize" ) ) != NULL )
00441 uiMaxSize = IVAL( regval_data_p( val ), 0 );
00442
00443 regkey_close_internal( keyinfo );
00444
00445 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
00446 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
00447
00448 return True;
00449 }
00450
00451
00452
00453
00454 static Eventlog_entry *read_package_entry( prs_struct * ps,
00455 EVENTLOG_Q_READ_EVENTLOG * q_u,
00456 EVENTLOG_R_READ_EVENTLOG * r_u,
00457 Eventlog_entry * entry )
00458 {
00459 uint8 *offset;
00460 Eventlog_entry *ee_new = NULL;
00461
00462 ee_new = PRS_ALLOC_MEM( ps, Eventlog_entry, 1 );
00463 if ( ee_new == NULL ) {
00464 return NULL;
00465 }
00466
00467 entry->data_record.sid_padding =
00468 ( ( 4 -
00469 ( ( entry->data_record.source_name_len +
00470 entry->data_record.computer_name_len ) % 4 ) ) % 4 );
00471 entry->data_record.data_padding =
00472 ( 4 -
00473 ( ( entry->data_record.strings_len +
00474 entry->data_record.user_data_len ) % 4 ) ) % 4;
00475 entry->record.length = sizeof( Eventlog_record );
00476 entry->record.length += entry->data_record.source_name_len;
00477 entry->record.length += entry->data_record.computer_name_len;
00478 if ( entry->record.user_sid_length == 0 ) {
00479
00480
00481 entry->data_record.data_padding +=
00482 entry->data_record.sid_padding;
00483 entry->data_record.sid_padding = 0;
00484 }
00485 DEBUG( 10,
00486 ( "sid_padding is [%d].\n", entry->data_record.sid_padding ) );
00487 DEBUG( 10,
00488 ( "data_padding is [%d].\n",
00489 entry->data_record.data_padding ) );
00490
00491 entry->record.length += entry->data_record.sid_padding;
00492 entry->record.length += entry->record.user_sid_length;
00493 entry->record.length += entry->data_record.strings_len;
00494 entry->record.length += entry->data_record.user_data_len;
00495 entry->record.length += entry->data_record.data_padding;
00496
00497 entry->record.length += sizeof( entry->record.length );
00498 DEBUG( 10,
00499 ( "entry->record.length is [%d].\n", entry->record.length ) );
00500 entry->data =
00501 PRS_ALLOC_MEM( ps, uint8,
00502 entry->record.length -
00503 sizeof( Eventlog_record ) -
00504 sizeof( entry->record.length ) );
00505 if ( entry->data == NULL ) {
00506 return NULL;
00507 }
00508 offset = entry->data;
00509 memcpy( offset, &( entry->data_record.source_name ),
00510 entry->data_record.source_name_len );
00511 offset += entry->data_record.source_name_len;
00512 memcpy( offset, &( entry->data_record.computer_name ),
00513 entry->data_record.computer_name_len );
00514 offset += entry->data_record.computer_name_len;
00515
00516 offset += entry->data_record.sid_padding;
00517 entry->record.user_sid_offset =
00518 sizeof( Eventlog_record ) + ( offset - entry->data );
00519 memcpy( offset, &( entry->data_record.sid ),
00520 entry->record.user_sid_length );
00521 offset += entry->record.user_sid_length;
00522
00523 entry->record.string_offset =
00524 sizeof( Eventlog_record ) + ( offset - entry->data );
00525 memcpy( offset, &( entry->data_record.strings ),
00526 entry->data_record.strings_len );
00527 offset += entry->data_record.strings_len;
00528
00529 entry->record.data_length = entry->data_record.user_data_len;
00530 entry->record.data_offset =
00531 sizeof( Eventlog_record ) + ( offset - entry->data );
00532 memcpy( offset, &( entry->data_record.user_data ),
00533 entry->data_record.user_data_len );
00534 offset += entry->data_record.user_data_len;
00535
00536 memcpy( &( ee_new->record ), &entry->record,
00537 sizeof( Eventlog_record ) );
00538 memcpy( &( ee_new->data_record ), &entry->data_record,
00539 sizeof( Eventlog_data_record ) );
00540 ee_new->data = entry->data;
00541
00542 return ee_new;
00543 }
00544
00545
00546
00547
00548 static BOOL add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u,
00549 Eventlog_entry * ee_new )
00550 {
00551 Eventlog_entry *insert_point;
00552
00553 insert_point = r_u->entry;
00554
00555 if ( NULL == insert_point ) {
00556 r_u->entry = ee_new;
00557 ee_new->next = NULL;
00558 } else {
00559 while ( ( NULL != insert_point->next ) ) {
00560 insert_point = insert_point->next;
00561 }
00562 ee_new->next = NULL;
00563 insert_point->next = ee_new;
00564 }
00565 r_u->num_records++;
00566 r_u->num_bytes_in_resp += ee_new->record.length;
00567
00568 return True;
00569 }
00570
00571
00572
00573
00574 NTSTATUS _eventlog_open_eventlog( pipes_struct * p,
00575 EVENTLOG_Q_OPEN_EVENTLOG * q_u,
00576 EVENTLOG_R_OPEN_EVENTLOG * r_u )
00577 {
00578 fstring servername, logname;
00579 EVENTLOG_INFO *info;
00580 NTSTATUS result;
00581
00582 fstrcpy( servername, "" );
00583 if ( q_u->servername.string ) {
00584 rpcstr_pull( servername, q_u->servername.string->buffer,
00585 sizeof( servername ),
00586 q_u->servername.string->uni_str_len * 2, 0 );
00587 }
00588
00589 fstrcpy( logname, "" );
00590 if ( q_u->logname.string ) {
00591 rpcstr_pull( logname, q_u->logname.string->buffer,
00592 sizeof( logname ),
00593 q_u->logname.string->uni_str_len * 2, 0 );
00594 }
00595
00596 DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
00597 servername, logname ));
00598
00599
00600
00601
00602 if ( !NT_STATUS_IS_OK( result = elog_open( p, logname, &r_u->handle )) )
00603 return result;
00604
00605 if ( !(info = find_eventlog_info_by_hnd( p, &r_u->handle )) ) {
00606 DEBUG(0,("_eventlog_open_eventlog: eventlog (%s) opened but unable to find handle!\n",
00607 logname ));
00608 elog_close( p, &r_u->handle );
00609 return NT_STATUS_INVALID_HANDLE;
00610 }
00611
00612 DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info )));
00613
00614 sync_eventlog_params( info );
00615 prune_eventlog( ELOG_TDB_CTX(info->etdb) );
00616
00617 return NT_STATUS_OK;
00618 }
00619
00620
00621
00622
00623
00624 NTSTATUS _eventlog_clear_eventlog( pipes_struct * p,
00625 EVENTLOG_Q_CLEAR_EVENTLOG * q_u,
00626 EVENTLOG_R_CLEAR_EVENTLOG * r_u )
00627 {
00628 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
00629 pstring backup_file_name;
00630
00631 if ( !info )
00632 return NT_STATUS_INVALID_HANDLE;
00633
00634 pstrcpy( backup_file_name, "" );
00635 if ( q_u->backupfile.string ) {
00636 rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer,
00637 sizeof( backup_file_name ),
00638 q_u->backupfile.string->uni_str_len * 2, 0 );
00639
00640 DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
00641 "file name for log [%s].",
00642 backup_file_name, info->logname ) );
00643 }
00644
00645
00646
00647 if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) )
00648 return NT_STATUS_ACCESS_DENIED;
00649
00650
00651
00652 elog_close_tdb( info->etdb, True );
00653 become_root();
00654 info->etdb = elog_open_tdb( info->logname, True );
00655 unbecome_root();
00656
00657 if ( !info->etdb )
00658 return NT_STATUS_ACCESS_DENIED;
00659
00660 return NT_STATUS_OK;
00661 }
00662
00663
00664
00665
00666 NTSTATUS _eventlog_close_eventlog( pipes_struct * p,
00667 EVENTLOG_Q_CLOSE_EVENTLOG * q_u,
00668 EVENTLOG_R_CLOSE_EVENTLOG * r_u )
00669 {
00670 return elog_close( p, &q_u->handle );
00671 }
00672
00673
00674
00675
00676 NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
00677 EVENTLOG_Q_READ_EVENTLOG * q_u,
00678 EVENTLOG_R_READ_EVENTLOG * r_u )
00679 {
00680 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
00681 Eventlog_entry entry, *ee_new;
00682 uint32 num_records_read = 0;
00683 prs_struct *ps;
00684 int bytes_left, record_number;
00685 uint32 elog_read_type, elog_read_dir;
00686
00687 if (info == NULL) {
00688 return NT_STATUS_INVALID_HANDLE;
00689 }
00690
00691 info->flags = q_u->flags;
00692 ps = &p->out_data.rdata;
00693
00694 bytes_left = q_u->max_read_size;
00695
00696 if ( !info->etdb )
00697 return NT_STATUS_ACCESS_DENIED;
00698
00699
00700
00701 elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
00702 elog_read_dir = q_u->flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
00703
00704 if ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ)
00705 || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ) )
00706 {
00707 DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->flags));
00708 return NT_STATUS_INVALID_PARAMETER;
00709 }
00710
00711
00712
00713 if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ )
00714 record_number = info->current_record;
00715 else
00716 record_number = q_u->offset;
00717
00718 while ( bytes_left > 0 ) {
00719
00720
00721
00722 if ( !get_eventlog_record ( ps, ELOG_TDB_CTX(info->etdb), record_number, &entry ) )
00723 break;
00724
00725 DEBUG( 8, ( "Retrieved record %d\n", record_number ) );
00726
00727
00728
00729 if ( !(ee_new = read_package_entry( ps, q_u, r_u,&entry )) )
00730 return NT_STATUS_NO_MEMORY;
00731
00732 if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) {
00733 r_u->bytes_in_next_record = ee_new->record.length;
00734
00735
00736
00737 bytes_left = 0;
00738 break;
00739 }
00740
00741 add_record_to_resp( r_u, ee_new );
00742 bytes_left -= ee_new->record.length;
00743 ZERO_STRUCT( entry );
00744 num_records_read = r_u->num_records - num_records_read;
00745
00746 DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
00747 "of [%d] records using [%d] bytes out of a max of [%d].\n",
00748 num_records_read, r_u->num_records,
00749 r_u->num_bytes_in_resp,
00750 q_u->max_read_size ) );
00751
00752 if ( info->flags & EVENTLOG_FORWARDS_READ )
00753 record_number++;
00754 else
00755 record_number--;
00756
00757
00758
00759 info->current_record = record_number;
00760 }
00761
00762
00763
00764
00765 return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);
00766 }
00767
00768
00769
00770
00771 NTSTATUS _eventlog_get_oldest_entry( pipes_struct * p,
00772 EVENTLOG_Q_GET_OLDEST_ENTRY * q_u,
00773 EVENTLOG_R_GET_OLDEST_ENTRY * r_u )
00774 {
00775 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
00776
00777 if (info == NULL) {
00778 return NT_STATUS_INVALID_HANDLE;
00779 }
00780
00781 if ( !( get_oldest_entry_hook( info ) ) )
00782 return NT_STATUS_ACCESS_DENIED;
00783
00784 r_u->oldest_entry = info->oldest_entry;
00785
00786 return NT_STATUS_OK;
00787 }
00788
00789
00790
00791
00792 NTSTATUS _eventlog_get_num_records( pipes_struct * p,
00793 EVENTLOG_Q_GET_NUM_RECORDS * q_u,
00794 EVENTLOG_R_GET_NUM_RECORDS * r_u )
00795 {
00796 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
00797
00798 if (info == NULL) {
00799 return NT_STATUS_INVALID_HANDLE;
00800 }
00801
00802 if ( !( get_num_records_hook( info ) ) )
00803 return NT_STATUS_ACCESS_DENIED;
00804
00805 r_u->num_records = info->num_records;
00806
00807 return NT_STATUS_OK;
00808 }