📄 srv_eventlog_nt.c
字号:
if ( !info->etdb ) { DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); return False; } /* 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 retreive the values. That way we can continue to use the same fetch/store api that we use in srv_reg_nt.c */ pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname ); wresult = regkey_open_internal( &keyinfo, path, get_root_nt_token( ), REG_KEY_READ ); if ( !W_ERROR_IS_OK( wresult ) ) { DEBUG( 4, ( "sync_eventlog_params: Failed to open key [%s] (%s)\n", path, dos_errstr( wresult ) ) ); return False; } if ( !( values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR ) ) ) { TALLOC_FREE( keyinfo ); DEBUG( 0, ( "control_eventlog_hook: talloc() failed!\n" ) ); return False; } fetch_reg_values( keyinfo, values ); if ( ( val = regval_ctr_getvalue( values, "Retention" ) ) != NULL ) uiRetention = IVAL( regval_data_p( val ), 0 ); if ( ( val = regval_ctr_getvalue( values, "MaxSize" ) ) != NULL ) uiMaxSize = IVAL( regval_data_p( val ), 0 ); regkey_close_internal( keyinfo ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); return True;}/******************************************************************** ********************************************************************/static Eventlog_entry *read_package_entry( prs_struct * ps, EVENTLOG_Q_READ_EVENTLOG * q_u, EVENTLOG_R_READ_EVENTLOG * r_u, Eventlog_entry * entry ){ uint8 *offset; Eventlog_entry *ee_new = NULL; ee_new = PRS_ALLOC_MEM( ps, Eventlog_entry, 1 ); if ( ee_new == NULL ) { return NULL; } entry->data_record.sid_padding = ( ( 4 - ( ( entry->data_record.source_name_len + entry->data_record.computer_name_len ) % 4 ) ) % 4 ); entry->data_record.data_padding = ( 4 - ( ( entry->data_record.strings_len + entry->data_record.user_data_len ) % 4 ) ) % 4; entry->record.length = sizeof( Eventlog_record ); entry->record.length += entry->data_record.source_name_len; entry->record.length += entry->data_record.computer_name_len; if ( entry->record.user_sid_length == 0 ) { /* Should not pad to a DWORD boundary for writing out the sid if there is no SID, so just propagate the padding to pad the data */ entry->data_record.data_padding += entry->data_record.sid_padding; entry->data_record.sid_padding = 0; } DEBUG( 10, ( "sid_padding is [%d].\n", entry->data_record.sid_padding ) ); DEBUG( 10, ( "data_padding is [%d].\n", entry->data_record.data_padding ) ); entry->record.length += entry->data_record.sid_padding; entry->record.length += entry->record.user_sid_length; entry->record.length += entry->data_record.strings_len; entry->record.length += entry->data_record.user_data_len; entry->record.length += entry->data_record.data_padding; /* need another copy of length at the end of the data */ entry->record.length += sizeof( entry->record.length ); DEBUG( 10, ( "entry->record.length is [%d].\n", entry->record.length ) ); entry->data = PRS_ALLOC_MEM( ps, uint8, entry->record.length - sizeof( Eventlog_record ) - sizeof( entry->record.length ) ); if ( entry->data == NULL ) { return NULL; } offset = entry->data; memcpy( offset, &( entry->data_record.source_name ), entry->data_record.source_name_len ); offset += entry->data_record.source_name_len; memcpy( offset, &( entry->data_record.computer_name ), entry->data_record.computer_name_len ); offset += entry->data_record.computer_name_len; /* SID needs to be DWORD-aligned */ offset += entry->data_record.sid_padding; entry->record.user_sid_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); memcpy( offset, &( entry->data_record.sid ), entry->record.user_sid_length ); offset += entry->record.user_sid_length; /* Now do the strings */ entry->record.string_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); memcpy( offset, &( entry->data_record.strings ), entry->data_record.strings_len ); offset += entry->data_record.strings_len; /* Now do the data */ entry->record.data_length = entry->data_record.user_data_len; entry->record.data_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); memcpy( offset, &( entry->data_record.user_data ), entry->data_record.user_data_len ); offset += entry->data_record.user_data_len; memcpy( &( ee_new->record ), &entry->record, sizeof( Eventlog_record ) ); memcpy( &( ee_new->data_record ), &entry->data_record, sizeof( Eventlog_data_record ) ); ee_new->data = entry->data; return ee_new;}/******************************************************************** ********************************************************************/static BOOL add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u, Eventlog_entry * ee_new ){ Eventlog_entry *insert_point; insert_point = r_u->entry; if ( NULL == insert_point ) { r_u->entry = ee_new; ee_new->next = NULL; } else { while ( ( NULL != insert_point->next ) ) { insert_point = insert_point->next; } ee_new->next = NULL; insert_point->next = ee_new; } r_u->num_records++; r_u->num_bytes_in_resp += ee_new->record.length; return True;}/******************************************************************** ********************************************************************/NTSTATUS _eventlog_open_eventlog( pipes_struct * p, EVENTLOG_Q_OPEN_EVENTLOG * q_u, EVENTLOG_R_OPEN_EVENTLOG * r_u ){ fstring servername, logname; EVENTLOG_INFO *info; NTSTATUS result; fstrcpy( servername, "" ); if ( q_u->servername.string ) { rpcstr_pull( servername, q_u->servername.string->buffer, sizeof( servername ), q_u->servername.string->uni_str_len * 2, 0 ); } fstrcpy( logname, "" ); if ( q_u->logname.string ) { rpcstr_pull( logname, q_u->logname.string->buffer, sizeof( logname ), q_u->logname.string->uni_str_len * 2, 0 ); } 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 ( !NT_STATUS_IS_OK( result = elog_open( p, logname, &r_u->handle )) ) return result; 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 NT_STATUS_INVALID_HANDLE; } DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info ))); sync_eventlog_params( info ); prune_eventlog( ELOG_TDB_CTX(info->etdb) ); return NT_STATUS_OK;}/******************************************************************** This call still needs some work ********************************************************************/NTSTATUS _eventlog_clear_eventlog( pipes_struct * p, EVENTLOG_Q_CLEAR_EVENTLOG * q_u, EVENTLOG_R_CLEAR_EVENTLOG * r_u ){ EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); pstring backup_file_name; if ( !info ) return NT_STATUS_INVALID_HANDLE; 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(8,( "_eventlog_clear_eventlog: Using [%s] as the backup " "file name for log [%s].", backup_file_name, info->logname ) ); } /* check for WRITE access to the file */ if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) ) return NT_STATUS_ACCESS_DENIED; /* Force a close and reopen */ elog_close_tdb( info->etdb, True ); become_root(); info->etdb = elog_open_tdb( info->logname, True ); unbecome_root(); if ( !info->etdb ) return NT_STATUS_ACCESS_DENIED; return NT_STATUS_OK;}/******************************************************************** ********************************************************************/NTSTATUS _eventlog_close_eventlog( pipes_struct * p, EVENTLOG_Q_CLOSE_EVENTLOG * q_u, EVENTLOG_R_CLOSE_EVENTLOG * r_u ){ return elog_close( p, &q_u->handle );}/******************************************************************** ********************************************************************/NTSTATUS _eventlog_read_eventlog( pipes_struct * p, EVENTLOG_Q_READ_EVENTLOG * q_u, EVENTLOG_R_READ_EVENTLOG * r_u ){ 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; uint32 elog_read_type, elog_read_dir; info->flags = q_u->flags; ps = &p->out_data.rdata; bytes_left = q_u->max_read_size; if ( !info->etdb ) return NT_STATUS_ACCESS_DENIED; /* check for valid flags. Can't use the sequential and seek flags together */ elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ); elog_read_dir = q_u->flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ); if ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ) ) { DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->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 = q_u->offset; while ( bytes_left > 0 ) { /* assume that when the record fetch fails, that we are done */ if ( !get_eventlog_record ( ps, ELOG_TDB_CTX(info->etdb), record_number, &entry ) ) break; 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 )) ) return NT_STATUS_NO_MEMORY; 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, r_u->num_bytes_in_resp, q_u->max_read_size ) ); if ( info->flags & EVENTLOG_FORWARDS_READ ) record_number++; else record_number--; /* update the eventlog record pointer */ info->current_record = record_number; } /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to say when there are no more records */ return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);}/******************************************************************** ********************************************************************/NTSTATUS _eventlog_get_oldest_entry( pipes_struct * p, EVENTLOG_Q_GET_OLDEST_ENTRY * q_u, EVENTLOG_R_GET_OLDEST_ENTRY * r_u ){ EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); if ( !( get_oldest_entry_hook( info ) ) ) return NT_STATUS_ACCESS_DENIED; r_u->oldest_entry = info->oldest_entry; return NT_STATUS_OK;}/******************************************************************** ********************************************************************/NTSTATUS _eventlog_get_num_records( pipes_struct * p, EVENTLOG_Q_GET_NUM_RECORDS * q_u, EVENTLOG_R_GET_NUM_RECORDS * r_u ){ EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); if ( !( get_num_records_hook( info ) ) ) return NT_STATUS_ACCESS_DENIED; r_u->num_records = info->num_records; return NT_STATUS_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -