static bool get_num_records_hook( EVENTLOG_INFO * info ) { int next_record; int oldest_record; if ( !info->etdb ) { DEBUG( 10, ( "No open tdb for %s\n", info->logname ) ); return False; } /* lock the tdb since we have to get 2 records */ tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 ); next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD); oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY); tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD); DEBUG( 8, ( "Oldest Record %d; Next Record %d\n", oldest_record, next_record ) ); info->num_records = ( next_record - oldest_record ); info->oldest_entry = oldest_record; return True; }
NTSTATUS _eventlog_ReportEventW(pipes_struct *p, struct eventlog_ReportEventW *r) { NTSTATUS status; struct EVENTLOGRECORD record; EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle); if (!info) { return NT_STATUS_INVALID_HANDLE; } status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record); if (!NT_STATUS_IS_OK(status)) { return status; } status = evlog_push_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb), &record, r->out.record_number); if (!NT_STATUS_IS_OK(status)) { return status; } return NT_STATUS_OK; }
NTSTATUS _eventlog_OpenEventLogW(pipes_struct *p, struct eventlog_OpenEventLogW *r) { EVENTLOG_INFO *info; NTSTATUS result; DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n", r->in.servername->string, r->in.logname->string )); /* according to MSDN, if the logfile cannot be found, we should default to the "Application" log */ if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) ) return result; if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) { DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n", r->in.logname->string )); elog_close( p, r->out.handle ); return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info ))); sync_eventlog_params( info ); prune_eventlog( ELOG_TDB_CTX(info->etdb) ); return NT_STATUS_OK; }
static int elog_size( EVENTLOG_INFO *info ) { if ( !info || !info->etdb ) { DEBUG(0,("elog_size: Invalid info* structure!\n")); return 0; } return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL ); }
NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p, struct eventlog_ReadEventLogW *r) { EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle ); uint32_t num_records_read = 0; int bytes_left, record_number; uint32_t elog_read_type, elog_read_dir; if (!info) { return NT_STATUS_INVALID_HANDLE; } info->flags = r->in.flags; bytes_left = r->in.number_of_bytes; if (!info->etdb) { return NT_STATUS_ACCESS_DENIED; } /* check for valid flags. Can't use the sequential and seek flags together */ elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ); elog_read_dir = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ); if (r->in.flags == 0 || elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ)) { DEBUG(3,("_eventlog_ReadEventLogW: " "Invalid flags [0x%08x] for ReadEventLog\n", r->in.flags)); return NT_STATUS_INVALID_PARAMETER; } /* a sequential read should ignore the offset */ if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) { record_number = info->current_record; } else { record_number = r->in.offset; } if (r->in.number_of_bytes == 0) { struct EVENTLOGRECORD *e; e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb), record_number); if (!e) { return NT_STATUS_END_OF_FILE; } *r->out.real_size = e->Length; return NT_STATUS_BUFFER_TOO_SMALL; } while (bytes_left > 0) { DATA_BLOB blob; enum ndr_err_code ndr_err; struct EVENTLOGRECORD *e; e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb), record_number); if (!e) { break; } ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL, e, (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(EVENTLOGRECORD, e); } if (blob.length > r->in.number_of_bytes) { *r->out.real_size = blob.length; return NT_STATUS_BUFFER_TOO_SMALL; } if (*r->out.sent_size + blob.length > r->in.number_of_bytes) { break; } bytes_left -= blob.length; if (info->flags & EVENTLOG_FORWARDS_READ) { record_number++; } else { record_number--; } /* update the eventlog record pointer */ info->current_record = record_number; memcpy(&r->out.data[*(r->out.sent_size)], blob.data, blob.length); *(r->out.sent_size) += blob.length; num_records_read++; } if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) { return NT_STATUS_END_OF_FILE; } return NT_STATUS_OK; }
static bool sync_eventlog_params( EVENTLOG_INFO *info ) { char *path = NULL; uint32 uiMaxSize; uint32 uiRetention; struct registry_key *key; struct registry_value *value; WERROR wresult; char *elogname = info->logname; TALLOC_CTX *ctx = talloc_stackframe(); bool ret = false; DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); if ( !info->etdb ) { DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); goto done; } /* set resonable defaults. 512Kb on size and 1 week on time */ uiMaxSize = 0x80000; uiRetention = 604800; /* the general idea is to internally open the registry key and retrieve the values. That way we can continue to use the same fetch/store api that we use in srv_reg_nt.c */ path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname ); if (!path) { goto done; } wresult = reg_open_path(ctx, path, REG_KEY_READ, get_root_nt_token(), &key); if ( !W_ERROR_IS_OK( wresult ) ) { DEBUG( 4, ( "sync_eventlog_params: Failed to open key [%s] (%s)\n", path, win_errstr( wresult ) ) ); goto done; } wresult = reg_queryvalue(key, key, "Retention", &value); if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", win_errstr(wresult))); goto done; } uiRetention = value->v.dword; wresult = reg_queryvalue(key, key, "MaxSize", &value); if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"MaxSize\": %s\n", win_errstr(wresult))); goto done; } uiMaxSize = value->v.dword; tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); ret = true; done: TALLOC_FREE(ctx); return ret; }
static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename ) { FILE *f1; char *argfname; ELOG_TDB *etdb; /* fixed constants are bad bad bad */ char linein[1024]; bool is_eor; Eventlog_entry ee; int rcnum; f1 = stdin; if ( !f1 ) { printf( "Can't open STDIN\n" ); return -1; } if ( debugflag ) { printf( "Starting write for eventlog [%s]\n", argv[0] ); display_eventlog_names( ); } argfname = argv[0]; if ( !( etdb = elog_open_tdb( argfname, False ) ) ) { printf( "can't open the eventlog TDB (%s)\n", argfname ); return -1; } ZERO_STRUCT( ee ); /* MUST initialize between records */ while ( !feof( f1 ) ) { if (fgets( linein, sizeof( linein ) - 1, f1 ) == NULL) { break; } linein[strlen( linein ) - 1] = 0; /* whack the line delimiter */ if ( debugflag ) printf( "Read line [%s]\n", linein ); is_eor = False; parse_logentry( ( char * ) &linein, &ee, &is_eor ); /* should we do something with the return code? */ 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_CTX(etdb), &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 */ } } elog_close_tdb( etdb , False ); return 0; }
static bool sync_eventlog_params(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, EVENTLOG_INFO *info) { struct dcerpc_binding_handle *h = NULL; uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; struct policy_handle hive_hnd, key_hnd; uint32_t uiMaxSize = 0; uint32_t uiRetention = 0; char *path = NULL; NTSTATUS status; WERROR wresult = WERR_OK; char *elogname = info->logname; TALLOC_CTX *ctx; bool ret = false; ctx = talloc_stackframe(); if (ctx == NULL) { return false; } DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); if ( !info->etdb ) { DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); goto done; } /* set resonable defaults. 512Kb on size and 1 week on time */ uiMaxSize = 0x80000; uiRetention = 604800; /* the general idea is to internally open the registry key and retrieve the values. That way we can continue to use the same fetch/store api that we use in srv_reg_nt.c */ path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname); if (!path) { goto done; } status = dcerpc_winreg_int_hklm_openkey(ctx, get_session_info_system(), msg_ctx, &h, path, false, access_mask, &hive_hnd, &key_hnd, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n", path, nt_errstr(status))); goto done; } if ( !W_ERROR_IS_OK( wresult ) ) { DEBUG( 4, ( "sync_eventlog_params: Failed to open key [%s] (%s)\n", path, win_errstr( wresult ) ) ); goto done; } status = dcerpc_winreg_query_dword(ctx, h, &key_hnd, "Retention", &uiRetention, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", win_errstr(wresult))); goto done; } status = dcerpc_winreg_query_dword(ctx, h, &key_hnd, "MaxSize", &uiMaxSize, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"MaxSize\": %s\n", win_errstr(wresult))); goto done; } tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); ret = true; done: if (h != NULL) { WERROR ignore; if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore); } if (is_valid_policy_hnd(&hive_hnd)) { dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore); } } TALLOC_FREE(ctx); return ret; }
static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename ) { FILE *f1; char *argfname; ELOG_TDB *etdb; NTSTATUS status; /* fixed constants are bad bad bad */ char linein[1024]; bool is_eor; struct eventlog_Record_tdb ee; uint32_t record_number = 0; TALLOC_CTX *mem_ctx = talloc_tos(); f1 = stdin; if ( !f1 ) { printf( "Can't open STDIN\n" ); return -1; } if ( debugflag ) { printf( "Starting write for eventlog [%s]\n", argv[0] ); display_eventlog_names( ); } argfname = argv[0]; if ( !( etdb = elog_open_tdb( argfname, False, False ) ) ) { printf( "can't open the eventlog TDB (%s)\n", argfname ); return -1; } ZERO_STRUCT( ee ); /* MUST initialize between records */ while ( !feof( f1 ) ) { if (fgets( linein, sizeof( linein ) - 1, f1 ) == NULL) { break; } if ((strlen(linein) > 0) && (linein[strlen(linein)-1] == '\n')) { linein[strlen(linein)-1] = 0; } if ( debugflag ) printf( "Read line [%s]\n", linein ); is_eor = False; parse_logentry( mem_ctx, ( char * ) &linein, &ee, &is_eor ); /* should we do something with the return code? */ if ( is_eor ) { fixup_eventlog_record_tdb( &ee ); if ( opt_debug ) printf( "record number [%d], tg [%d] , tw [%d]\n", ee.record_number, (int)ee.time_generated, (int)ee.time_written ); if ( ee.time_generated != 0 ) { /* printf("Writing to the event log\n"); */ status = evlog_push_record_tdb( mem_ctx, ELOG_TDB_CTX(etdb), &ee, &record_number ); if ( !NT_STATUS_IS_OK(status) ) { printf( "Can't write to the event log: %s\n", nt_errstr(status) ); } else { if ( opt_debug ) printf( "Wrote record %d\n", record_number ); } } else { if ( opt_debug ) printf( "<null record>\n" ); } ZERO_STRUCT( ee ); /* MUST initialize between records */ } } elog_close_tdb( etdb , False ); return 0; }