* Copyright (C) Marcin Krzysztof Porwit 2005,
* Copyright (C) Brian Moran 2005,
* Copyright (C) Gerald (Jerry) Carter 2005.
+ * Copyright (C) Guenther Deschner 2009.
*
* 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
*/
#include "includes.h"
+#include "../librpc/gen_ndr/srv_eventlog.h"
+#include "lib/eventlog/eventlog.h"
+#include "registry.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
********************************************************************/
static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
- POLICY_HND * handle )
+ struct policy_handle * handle )
{
EVENTLOG_INFO *info;
static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
{
char *tdbname = elog_tdbname(talloc_tos(), info->logname );
- SEC_DESC *sec_desc;
+ struct security_descriptor *sec_desc;
+ struct security_ace *ace;
NTSTATUS status;
if ( !tdbname )
return False;
}
+ ace = talloc_zero(sec_desc, struct security_ace);
+ if (ace == NULL) {
+ TALLOC_FREE(sec_desc);
+ return false;
+ }
+
+ ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+ ace->flags = 0;
+ ace->access_mask = REG_KEY_ALL;
+ ace->trustee = global_sid_System;
+
+ status = security_descriptor_dacl_add(sec_desc, ace);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(sec_desc);
+ return false;
+ }
+
/* root free pass */
if ( geteuid() == sec_initial_uid() ) {
- DEBUG(5,("elog_check_access: using root's token\n"));
- token = get_root_nt_token();
+ DEBUG(5,("elog_check_access: running as root, using system token\n"));
+ token = get_system_token();
}
/* run the check, try for the max allowed */
status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
&info->access_granted);
- if ( sec_desc )
- TALLOC_FREE( sec_desc );
+ TALLOC_FREE(sec_desc);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(8,("elog_check_access: se_access_check() return %s\n",
/* we have to have READ permission for a successful open */
- return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
+ return ( info->access_granted & SEC_FILE_READ_DATA );
}
/********************************************************************
/********************************************************************
********************************************************************/
-static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
+static NTSTATUS elog_open( pipes_struct * p, const char *logname, struct policy_handle *hnd )
{
EVENTLOG_INFO *elog;
/* first thing is to validate the eventlog name */
-
+
if ( !elog_validate_logname( logname ) )
return NT_STATUS_OBJECT_PATH_INVALID;
in a single process */
become_root();
- elog->etdb = elog_open_tdb( elog->logname, False );
+ elog->etdb = elog_open_tdb( elog->logname, False, False );
unbecome_root();
if ( !elog->etdb ) {
}
become_root();
- elog->etdb = elog_open_tdb( elog->logname, False );
+ elog->etdb = elog_open_tdb( elog->logname, False, False );
unbecome_root();
}
/********************************************************************
********************************************************************/
-static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd )
+static NTSTATUS elog_close( pipes_struct *p, struct policy_handle *hnd )
{
if ( !( close_policy_hnd( p, hnd ) ) ) {
return NT_STATUS_INVALID_HANDLE;
return elog_tdb_size( ELOG_TDB_CTX(info->etdb), 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.
- ********************************************************************/
-
-static Eventlog_entry *get_eventlog_record(TALLOC_CTX *mem_ctx,
- TDB_CONTEXT *tdb,
- int recno)
-{
- Eventlog_entry *ee = NULL;
- TDB_DATA ret, key;
-
- int32_t srecno;
- int32_t reclen;
- int len;
-
- char *wpsource = NULL;
- char *wpcomputer = NULL;
- char *wpsid = NULL;
- char *wpstrs = NULL;
- char *puserdata = NULL;
-
- key.dsize = sizeof(int32_t);
-
- srecno = recno;
- key.dptr = (unsigned char *)&srecno;
-
- ret = tdb_fetch( tdb, key );
-
- if ( ret.dsize == 0 ) {
- DEBUG( 8,
- ( "Can't find a record for the key, record %d\n",
- recno ) );
- return NULL;
- }
-
- len = tdb_unpack( ret.dptr, ret.dsize, "d", &reclen );
-
- DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno, len ) );
-
- if ( !len )
- return NULL;
-
- ee = TALLOC_ARRAY(mem_ctx, Eventlog_entry, 1);
- if (!ee) {
- return NULL;
- }
- ZERO_STRUCTP(ee);
-
- len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd",
- &ee->record.length, &ee->record.reserved1,
- &ee->record.record_number,
- &ee->record.time_generated,
- &ee->record.time_written, &ee->record.event_id,
- &ee->record.event_type, &ee->record.num_strings,
- &ee->record.event_category, &ee->record.reserved2,
- &ee->record.closing_record_number,
- &ee->record.string_offset,
- &ee->record.user_sid_length,
- &ee->record.user_sid_offset,
- &ee->record.data_length, &ee->record.data_offset,
- &ee->data_record.source_name_len, &wpsource,
- &ee->data_record.computer_name_len, &wpcomputer,
- &ee->data_record.sid_padding,
- &ee->record.user_sid_length, &wpsid,
- &ee->data_record.strings_len, &wpstrs,
- &ee->data_record.user_data_len, &puserdata,
- &ee->data_record.data_padding );
- DEBUG( 10,
- ( "Read record %d, len in tdb was %d\n",
- ee->record.record_number, len ) );
-
- /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
- into it's 2nd argment for 'B' */
-
- if (wpcomputer) {
- ee->data_record.computer_name = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpcomputer, ee->data_record.computer_name_len);
- if (!ee->data_record.computer_name) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
- if (wpsource) {
- ee->data_record.source_name = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpsource, ee->data_record.source_name_len);
- if (!ee->data_record.source_name) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- if (wpsid) {
- ee->data_record.sid = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpsid, ee->record.user_sid_length);
- if (!ee->data_record.sid) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
- if (wpstrs) {
- ee->data_record.strings = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpstrs, ee->data_record.strings_len);
- if (!ee->data_record.strings) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- if (puserdata) {
- ee->data_record.user_data = (char *)TALLOC_MEMDUP(
- ee, puserdata, ee->data_record.user_data_len);
- if (!ee->data_record.user_data) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- out:
-
- SAFE_FREE(wpcomputer);
- SAFE_FREE(wpsource);
- SAFE_FREE(wpsid);
- SAFE_FREE(wpstrs);
- SAFE_FREE(puserdata);
-
- DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) );
- DEBUG( 10,
- ( "get_eventlog_record: computer_name %d is ",
- ee->data_record.computer_name_len ) );
- SAFE_FREE(ret.dptr);
- return ee;
-}
-
/********************************************************************
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( EVENTLOG_INFO *info )
{
char *path = NULL;
- uint32 uiMaxSize;
- uint32 uiRetention;
+ uint32_t uiMaxSize = 0;
+ uint32_t uiRetention = 0;
struct registry_key *key;
struct registry_value *value;
WERROR wresult;
to use the same fetch/store api that we use in
srv_reg_nt.c */
- path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
+ 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(),
+ wresult = reg_open_path(ctx, path, REG_KEY_READ, get_system_token(),
&key);
if ( !W_ERROR_IS_OK( wresult ) ) {
win_errstr(wresult)));
goto done;
}
- uiRetention = value->v.dword;
+
+ if (value->data.length >= 4) {
+ uiRetention = IVAL(value->data.data, 0);
+ }
wresult = reg_queryvalue(key, key, "MaxSize", &value);
if (!W_ERROR_IS_OK(wresult)) {
win_errstr(wresult)));
goto done;
}
- uiMaxSize = value->v.dword;
+ if (value->data.length >= 4) {
+ uiMaxSize = IVAL(value->data.data, 0);
+ }
tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
return ret;
}
-/********************************************************************
- ********************************************************************/
-
-static Eventlog_entry *read_package_entry( TALLOC_CTX *mem_ctx,
- Eventlog_entry * entry )
-{
- uint8 *offset;
- Eventlog_entry *ee_new = NULL;
-
- ee_new = TALLOC_ZERO_ARRAY(mem_ctx, 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 =
- TALLOC_ZERO_ARRAY(mem_ctx, uint8_t,
- 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_entry *entry,
- uint32_t *num_records,
- uint32_t *num_bytes_in_resp,
- Eventlog_entry * ee_new )
-{
- Eventlog_entry *insert_point;
-
- insert_point = entry;
-
- if ( NULL == insert_point ) {
- 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;
- }
- (*num_records)++;
- *num_bytes_in_resp += ee_new->record.length;
-
- return True;
-}
-
/********************************************************************
_eventlog_OpenEventLogW
********************************************************************/
NTSTATUS _eventlog_OpenEventLogW(pipes_struct *p,
struct eventlog_OpenEventLogW *r)
{
- const char *servername = "";
- const char *logname = "";
EVENTLOG_INFO *info;
NTSTATUS result;
- if (r->in.servername->string) {
- servername = r->in.servername->string;
- }
-
- if (r->in.logname->string) {
- logname = r->in.logname->string;
- }
-
- DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
- servername, logname ));
+ 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, logname, r->out.handle )) )
+ 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_open_eventlog: eventlog (%s) opened but unable to find handle!\n",
- logname ));
+ 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_open_eventlog: Size [%d]\n", elog_size( info )));
+ DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
- sync_eventlog_params( info );
+ if (!sync_eventlog_params(info)) {
+ elog_close(p, r->out.handle);
+ return NT_STATUS_EVENTLOG_FILE_CORRUPT;
+ }
prune_eventlog( ELOG_TDB_CTX(info->etdb) );
return NT_STATUS_OK;
struct eventlog_ClearEventLogW *r)
{
EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
- const char *backup_file_name = NULL;
if ( !info )
return NT_STATUS_INVALID_HANDLE;
if (r->in.backupfile && r->in.backupfile->string) {
- backup_file_name = r->in.backupfile->string;
-
- DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
+ DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
"file name for log [%s].",
- backup_file_name, info->logname ) );
+ r->in.backupfile->string, info->logname ) );
}
/* check for WRITE access to the file */
- if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) )
+ if ( !(info->access_granted & SEC_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 );
+ info->etdb = elog_open_tdb( info->logname, True, False );
unbecome_root();
if ( !info->etdb )
NTSTATUS _eventlog_CloseEventLog(pipes_struct * p,
struct eventlog_CloseEventLog *r)
{
- return elog_close( p, r->in.handle );
+ NTSTATUS status;
+
+ status = elog_close( p, r->in.handle );
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ ZERO_STRUCTP(r->out.handle);
+
+ return NT_STATUS_OK;
}
/********************************************************************
+ _eventlog_ReadEventLogW
********************************************************************/
-NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
- EVENTLOG_Q_READ_EVENTLOG * q_u,
- EVENTLOG_R_READ_EVENTLOG * r_u )
+NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p,
+ struct eventlog_ReadEventLogW *r)
{
- EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
- Eventlog_entry *entry = NULL, *ee_new = NULL;
- uint32 num_records_read = 0;
- prs_struct *ps;
+ EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
+ uint32_t num_records_read = 0;
int bytes_left, record_number;
- uint32 elog_read_type, elog_read_dir;
+ uint32_t elog_read_type, elog_read_dir;
- if (info == NULL) {
+ if (!info) {
return NT_STATUS_INVALID_HANDLE;
}
- info->flags = q_u->flags;
- ps = &p->out_data.rdata;
+ info->flags = r->in.flags;
+ bytes_left = r->in.number_of_bytes;
- bytes_left = q_u->max_read_size;
-
- if ( !info->etdb )
+ 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);
+ 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 ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ)
- || elog_read_dir == (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_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->flags));
+ 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 )
+ if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
record_number = info->current_record;
- else
- record_number = q_u->offset;
+ } else {
+ record_number = r->in.offset;
+ }
- while ( bytes_left > 0 ) {
+ 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) {
- /* assume that when the record fetch fails, that we are done */
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct EVENTLOGRECORD *e;
- entry = get_eventlog_record (ps->mem_ctx, ELOG_TDB_CTX(info->etdb), record_number);
- if (!entry) {
+ e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
+ record_number);
+ if (!e) {
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->mem_ctx, entry )) )
- return NT_STATUS_NO_MEMORY;
+ ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, e,
+ (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
- 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;
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
+ }
- /* response would be too big to fit in client-size buffer */
+ if (blob.length > r->in.number_of_bytes) {
+ *r->out.real_size = blob.length;
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- bytes_left = 0;
+ if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
break;
}
- add_record_to_resp( r_u->entry,
- &r_u->num_records, &r_u->num_bytes_in_resp,
- ee_new );
-
- bytes_left -= ee_new->record.length;
- TALLOC_FREE(entry);
- num_records_read = r_u->num_records - num_records_read;
+ bytes_left -= blob.length;
- 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 )
+ if (info->flags & EVENTLOG_FORWARDS_READ) {
record_number++;
- else
+ } 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++;
}
- /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
- say when there are no more records */
+ if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
+ return NT_STATUS_END_OF_FILE;
+ }
- return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);
+ return NT_STATUS_OK;
}
/********************************************************************
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_DeregisterEventSource(pipes_struct *p, struct eventlog_DeregisterEventSource *r)
+/********************************************************************
+_eventlog_GetLogInformation
+ ********************************************************************/
+
+NTSTATUS _eventlog_GetLogInformation(pipes_struct *p,
+ struct eventlog_GetLogInformation *r)
{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
+ EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
+ struct EVENTLOG_FULL_INFORMATION f;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+
+ if (!info) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (r->in.level != 0) {
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ *r->out.bytes_needed = 4;
+
+ if (r->in.buf_size < 4) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* FIXME: this should be retrieved from the handle */
+ f.full = false;
+
+ ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &f,
+ (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
+ }
+
+ memcpy(r->out.buffer, blob.data, 4);
+
+ return NT_STATUS_OK;
}
-NTSTATUS _eventlog_ChangeNotify(pipes_struct *p, struct eventlog_ChangeNotify *r)
+/********************************************************************
+_eventlog_FlushEventLog
+ ********************************************************************/
+
+NTSTATUS _eventlog_FlushEventLog(pipes_struct *p,
+ struct eventlog_FlushEventLog *r)
{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
+ EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
+ if (!info) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_ACCESS_DENIED;
}
-NTSTATUS _eventlog_RegisterEventSourceW(pipes_struct *p, struct eventlog_RegisterEventSourceW *r)
+/********************************************************************
+ ********************************************************************/
+
+static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
+ const struct eventlog_ReportEventW *r,
+ const char *logname,
+ struct EVENTLOGRECORD *e)
+{
+ uint32_t i;
+ ZERO_STRUCTP(e);
+
+ e->TimeGenerated = r->in.timestamp;
+ e->TimeWritten = time(NULL);
+ e->EventID = r->in.event_id;
+ e->EventType = r->in.event_type;
+ e->NumStrings = r->in.num_of_strings;
+ e->EventCategory = r->in.event_category;
+ e->ReservedFlags = r->in.flags;
+ e->DataLength = r->in.data_size;
+ e->SourceName = talloc_strdup(mem_ctx, logname);
+ NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
+ if (r->in.servername->string) {
+ e->Computername = r->in.servername->string;
+ } else {
+ e->Computername = talloc_strdup(mem_ctx, "");
+ NT_STATUS_HAVE_NO_MEMORY(e->Computername);
+ }
+ if (r->in.user_sid) {
+ e->UserSid = *r->in.user_sid;
+ }
+ e->Strings = talloc_array(mem_ctx, const char *, e->NumStrings);
+ NT_STATUS_HAVE_NO_MEMORY(e->Strings);
+
+ for (i=0; i < e->NumStrings; i++) {
+ e->Strings[i] = talloc_strdup(e->Strings,
+ r->in.strings[i]->string);
+ NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
+ }
+ e->Data = r->in.data;
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+_eventlog_ReportEventW
+ ********************************************************************/
+
+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_DeregisterEventSource(pipes_struct *p, struct eventlog_DeregisterEventSource *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_OpenBackupEventLogW(pipes_struct *p, struct eventlog_OpenBackupEventLogW *r)
+NTSTATUS _eventlog_ChangeNotify(pipes_struct *p, struct eventlog_ChangeNotify *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p, struct eventlog_ReadEventLogW *r)
+NTSTATUS _eventlog_RegisterEventSourceW(pipes_struct *p, struct eventlog_RegisterEventSourceW *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_ReportEventW(pipes_struct *p, struct eventlog_ReportEventW *r)
+NTSTATUS _eventlog_OpenBackupEventLogW(pipes_struct *p, struct eventlog_OpenBackupEventLogW *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r)
+NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
}
-
-NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-