2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Marcin Krzysztof Porwit 2005,
5 * Copyright (C) Brian Moran 2005,
6 * Copyright (C) Gerald (Jerry) Carter 2005.
7 * Copyright (C) Guenther Deschner 2009.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "../librpc/gen_ndr/srv_eventlog.h"
25 #include "lib/eventlog/eventlog.h"
27 #include "../libcli/security/security.h"
28 #include "../librpc/gen_ndr/ndr_winreg_c.h"
29 #include "rpc_client/cli_winreg_int.h"
30 #include "rpc_client/cli_winreg.h"
34 #define DBGC_CLASS DBGC_RPC_SRV
36 #define TOP_LEVEL_EVENTLOG_KEY "SYSTEM\\CurrentControlSet\\Services\\Eventlog"
41 uint32 current_record;
45 uint32 access_granted;
48 /********************************************************************
49 ********************************************************************/
51 static int eventlog_info_destructor(EVENTLOG_INFO *elog)
54 elog_close_tdb(elog->etdb, false);
59 /********************************************************************
60 ********************************************************************/
62 static EVENTLOG_INFO *find_eventlog_info_by_hnd( struct pipes_struct * p,
63 struct policy_handle * handle )
67 if ( !find_policy_by_hnd( p, handle, (void **)(void *)&info ) ) {
69 ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
76 /********************************************************************
77 ********************************************************************/
79 static bool elog_check_access( EVENTLOG_INFO *info, const struct security_token *token )
81 char *tdbname = elog_tdbname(talloc_tos(), info->logname );
82 struct security_descriptor *sec_desc;
83 struct security_ace *ace;
89 /* get the security descriptor for the file */
91 sec_desc = get_nt_acl_no_snum( info, tdbname );
92 TALLOC_FREE( tdbname );
95 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
100 ace = talloc_zero(sec_desc, struct security_ace);
102 TALLOC_FREE(sec_desc);
106 ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
108 ace->access_mask = REG_KEY_ALL;
109 ace->trustee = global_sid_System;
111 status = security_descriptor_dacl_add(sec_desc, ace);
112 if (!NT_STATUS_IS_OK(status)) {
113 TALLOC_FREE(sec_desc);
119 if ( geteuid() == sec_initial_uid() ) {
120 DEBUG(5,("elog_check_access: running as root, using system token\n"));
121 token = get_system_token();
124 /* run the check, try for the max allowed */
126 status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
127 &info->access_granted);
129 TALLOC_FREE(sec_desc);
131 if (!NT_STATUS_IS_OK(status)) {
132 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
137 /* we have to have READ permission for a successful open */
139 return ( info->access_granted & SEC_FILE_READ_DATA );
142 /********************************************************************
143 ********************************************************************/
145 static bool elog_validate_logname( const char *name )
148 const char **elogs = lp_eventlog_list();
154 for ( i=0; elogs[i]; i++ ) {
155 if ( strequal( name, elogs[i] ) )
162 /********************************************************************
163 ********************************************************************/
165 static bool get_num_records_hook( EVENTLOG_INFO * info )
171 DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
175 /* lock the tdb since we have to get 2 records */
177 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
178 next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
179 oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
180 tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
183 ( "Oldest Record %d; Next Record %d\n", oldest_record,
186 info->num_records = ( next_record - oldest_record );
187 info->oldest_entry = oldest_record;
192 /********************************************************************
193 ********************************************************************/
195 static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
197 /* it's the same thing */
198 return get_num_records_hook( info );
201 /********************************************************************
202 ********************************************************************/
204 static NTSTATUS elog_open( struct pipes_struct * p, const char *logname, struct policy_handle *hnd )
208 /* first thing is to validate the eventlog name */
210 if ( !elog_validate_logname( logname ) )
211 return NT_STATUS_OBJECT_PATH_INVALID;
213 if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
214 return NT_STATUS_NO_MEMORY;
215 talloc_set_destructor(elog, eventlog_info_destructor);
217 elog->logname = talloc_strdup( elog, logname );
219 /* Open the tdb first (so that we can create any new tdbs if necessary).
220 We have to do this as root and then use an internal access check
221 on the file permissions since you can only have a tdb open once
222 in a single process */
225 elog->etdb = elog_open_tdb( elog->logname, False, False );
229 /* according to MSDN, if the logfile cannot be found, we should
230 default to the "Application" log */
232 if ( !strequal( logname, ELOG_APPL ) ) {
234 TALLOC_FREE( elog->logname );
236 elog->logname = talloc_strdup( elog, ELOG_APPL );
238 /* do the access check */
239 if ( !elog_check_access( elog, p->session_info->security_token ) ) {
241 return NT_STATUS_ACCESS_DENIED;
245 elog->etdb = elog_open_tdb( elog->logname, False, False );
251 return NT_STATUS_ACCESS_DENIED; /* ??? */
255 /* now do the access check. Close the tdb if we fail here */
257 if ( !elog_check_access( elog, p->session_info->security_token ) ) {
259 return NT_STATUS_ACCESS_DENIED;
262 /* create the policy handle */
264 if ( !create_policy_hnd( p, hnd, elog ) ) {
266 return NT_STATUS_NO_MEMORY;
269 /* set the initial current_record pointer */
271 if ( !get_oldest_entry_hook( elog ) ) {
272 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
273 "get any information on internal records!\n"));
276 elog->current_record = elog->oldest_entry;
281 /********************************************************************
282 ********************************************************************/
284 static NTSTATUS elog_close( struct pipes_struct *p, struct policy_handle *hnd )
286 if ( !( close_policy_hnd( p, hnd ) ) ) {
287 return NT_STATUS_INVALID_HANDLE;
293 /*******************************************************************
294 *******************************************************************/
296 static int elog_size( EVENTLOG_INFO *info )
298 if ( !info || !info->etdb ) {
299 DEBUG(0,("elog_size: Invalid info* structure!\n"));
303 return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
306 /********************************************************************
307 note that this can only be called AFTER the table is constructed,
308 since it uses the table to find the tdb handle
309 ********************************************************************/
311 static bool sync_eventlog_params(TALLOC_CTX *mem_ctx,
312 struct messaging_context *msg_ctx,
315 struct dcerpc_binding_handle *h = NULL;
316 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
317 struct policy_handle hive_hnd, key_hnd;
318 uint32_t uiMaxSize = 0;
319 uint32_t uiRetention = 0;
322 WERROR wresult = WERR_OK;
323 char *elogname = info->logname;
327 ctx = talloc_stackframe();
332 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
335 DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
338 /* set resonable defaults. 512Kb on size and 1 week on time */
341 uiRetention = 604800;
343 /* the general idea is to internally open the registry
344 key and retrieve the values. That way we can continue
345 to use the same fetch/store api that we use in
347 path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname);
352 status = dcerpc_winreg_int_hklm_openkey(ctx,
353 get_session_info_system(),
362 if (!NT_STATUS_IS_OK(status)) {
363 DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n",
364 path, nt_errstr(status)));
367 if ( !W_ERROR_IS_OK( wresult ) ) {
369 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
370 path, win_errstr( wresult ) ) );
374 status = dcerpc_winreg_query_dword(ctx,
380 if (!NT_STATUS_IS_OK(status)) {
381 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
385 if (!W_ERROR_IS_OK(wresult)) {
386 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
387 win_errstr(wresult)));
391 status = dcerpc_winreg_query_dword(ctx,
397 if (!NT_STATUS_IS_OK(status)) {
398 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
402 if (!W_ERROR_IS_OK(wresult)) {
403 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
404 win_errstr(wresult)));
408 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
409 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
417 if (is_valid_policy_hnd(&key_hnd)) {
418 dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore);
420 if (is_valid_policy_hnd(&hive_hnd)) {
421 dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore);
429 /********************************************************************
430 _eventlog_OpenEventLogW
431 ********************************************************************/
433 NTSTATUS _eventlog_OpenEventLogW(struct pipes_struct *p,
434 struct eventlog_OpenEventLogW *r)
439 DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
440 r->in.servername->string, r->in.logname->string ));
442 /* according to MSDN, if the logfile cannot be found, we should
443 default to the "Application" log */
445 if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
448 if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
449 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
450 r->in.logname->string ));
451 elog_close( p, r->out.handle );
452 return NT_STATUS_INVALID_HANDLE;
455 DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
457 if (!sync_eventlog_params(p->mem_ctx,
460 elog_close(p, r->out.handle);
461 return NT_STATUS_EVENTLOG_FILE_CORRUPT;
463 prune_eventlog( ELOG_TDB_CTX(info->etdb) );
468 /********************************************************************
469 _eventlog_ClearEventLogW
470 This call still needs some work
471 ********************************************************************/
472 /** The windows client seems to be doing something funny with the file name
474 ClearEventLog(handle, "backup_file")
475 on the client side will result in the backup file name looking like this on the
477 \??\${CWD of client}\backup_file
478 If an absolute path gets specified, such as
479 ClearEventLog(handle, "C:\\temp\\backup_file")
480 then it is still mangled by the client into this:
481 \??\C:\temp\backup_file
482 when it is on the wire.
483 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
484 would be added in given that the backup file gets written on the server side. */
486 NTSTATUS _eventlog_ClearEventLogW(struct pipes_struct *p,
487 struct eventlog_ClearEventLogW *r)
489 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
492 return NT_STATUS_INVALID_HANDLE;
494 if (r->in.backupfile && r->in.backupfile->string) {
496 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
497 "file name for log [%s].",
498 r->in.backupfile->string, info->logname ) );
501 /* check for WRITE access to the file */
503 if ( !(info->access_granted & SEC_FILE_WRITE_DATA) )
504 return NT_STATUS_ACCESS_DENIED;
506 /* Force a close and reopen */
508 elog_close_tdb( info->etdb, True );
510 info->etdb = elog_open_tdb( info->logname, True, False );
514 return NT_STATUS_ACCESS_DENIED;
519 /********************************************************************
520 _eventlog_CloseEventLog
521 ********************************************************************/
523 NTSTATUS _eventlog_CloseEventLog(struct pipes_struct * p,
524 struct eventlog_CloseEventLog *r)
528 status = elog_close( p, r->in.handle );
529 if (!NT_STATUS_IS_OK(status)) {
533 ZERO_STRUCTP(r->out.handle);
538 /********************************************************************
539 _eventlog_ReadEventLogW
540 ********************************************************************/
542 NTSTATUS _eventlog_ReadEventLogW(struct pipes_struct *p,
543 struct eventlog_ReadEventLogW *r)
545 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
546 uint32_t num_records_read = 0;
547 int bytes_left, record_number;
548 uint32_t elog_read_type, elog_read_dir;
551 return NT_STATUS_INVALID_HANDLE;
554 info->flags = r->in.flags;
555 bytes_left = r->in.number_of_bytes;
558 return NT_STATUS_ACCESS_DENIED;
561 /* check for valid flags. Can't use the sequential and seek flags together */
563 elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
564 elog_read_dir = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
566 if (r->in.flags == 0 ||
567 elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
568 elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
570 DEBUG(3,("_eventlog_ReadEventLogW: "
571 "Invalid flags [0x%08x] for ReadEventLog\n",
573 return NT_STATUS_INVALID_PARAMETER;
576 /* a sequential read should ignore the offset */
578 if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
579 record_number = info->current_record;
581 record_number = r->in.offset;
584 if (r->in.number_of_bytes == 0) {
585 struct EVENTLOGRECORD *e;
586 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
589 return NT_STATUS_END_OF_FILE;
591 *r->out.real_size = e->Length;
592 return NT_STATUS_BUFFER_TOO_SMALL;
595 while (bytes_left > 0) {
598 enum ndr_err_code ndr_err;
599 struct EVENTLOGRECORD *e;
601 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
607 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, e,
608 (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
609 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
610 return ndr_map_error2ntstatus(ndr_err);
613 if (DEBUGLEVEL >= 10) {
614 NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
617 if (blob.length > r->in.number_of_bytes) {
618 *r->out.real_size = blob.length;
619 return NT_STATUS_BUFFER_TOO_SMALL;
622 if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
626 bytes_left -= blob.length;
628 if (info->flags & EVENTLOG_FORWARDS_READ) {
634 /* update the eventlog record pointer */
636 info->current_record = record_number;
638 memcpy(&r->out.data[*(r->out.sent_size)],
639 blob.data, blob.length);
640 *(r->out.sent_size) += blob.length;
645 if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
646 return NT_STATUS_END_OF_FILE;
652 /********************************************************************
653 _eventlog_GetOldestRecord
654 ********************************************************************/
656 NTSTATUS _eventlog_GetOldestRecord(struct pipes_struct *p,
657 struct eventlog_GetOldestRecord *r)
659 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
662 return NT_STATUS_INVALID_HANDLE;
665 if ( !( get_oldest_entry_hook( info ) ) )
666 return NT_STATUS_ACCESS_DENIED;
668 *r->out.oldest_entry = info->oldest_entry;
673 /********************************************************************
674 _eventlog_GetNumRecords
675 ********************************************************************/
677 NTSTATUS _eventlog_GetNumRecords(struct pipes_struct *p,
678 struct eventlog_GetNumRecords *r)
680 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
683 return NT_STATUS_INVALID_HANDLE;
686 if ( !( get_num_records_hook( info ) ) )
687 return NT_STATUS_ACCESS_DENIED;
689 *r->out.number = info->num_records;
694 NTSTATUS _eventlog_BackupEventLogW(struct pipes_struct *p, struct eventlog_BackupEventLogW *r)
696 p->rng_fault_state = True;
697 return NT_STATUS_NOT_IMPLEMENTED;
700 /********************************************************************
701 _eventlog_GetLogInformation
702 ********************************************************************/
704 NTSTATUS _eventlog_GetLogInformation(struct pipes_struct *p,
705 struct eventlog_GetLogInformation *r)
707 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
708 struct EVENTLOG_FULL_INFORMATION f;
709 enum ndr_err_code ndr_err;
713 return NT_STATUS_INVALID_HANDLE;
716 if (r->in.level != 0) {
717 return NT_STATUS_INVALID_LEVEL;
720 *r->out.bytes_needed = 4;
722 if (r->in.buf_size < 4) {
723 return NT_STATUS_BUFFER_TOO_SMALL;
726 /* FIXME: this should be retrieved from the handle */
729 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &f,
730 (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
731 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
732 return ndr_map_error2ntstatus(ndr_err);
735 if (DEBUGLEVEL >= 10) {
736 NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
739 memcpy(r->out.buffer, blob.data, 4);
744 /********************************************************************
745 _eventlog_FlushEventLog
746 ********************************************************************/
748 NTSTATUS _eventlog_FlushEventLog(struct pipes_struct *p,
749 struct eventlog_FlushEventLog *r)
751 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
753 return NT_STATUS_INVALID_HANDLE;
756 return NT_STATUS_ACCESS_DENIED;
759 /********************************************************************
760 ********************************************************************/
762 static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
763 const struct eventlog_ReportEventW *r,
765 struct EVENTLOGRECORD *e)
770 e->TimeGenerated = r->in.timestamp;
771 e->TimeWritten = time(NULL);
772 e->EventID = r->in.event_id;
773 e->EventType = r->in.event_type;
774 e->NumStrings = r->in.num_of_strings;
775 e->EventCategory = r->in.event_category;
776 e->ReservedFlags = r->in.flags;
777 e->DataLength = r->in.data_size;
778 e->SourceName = talloc_strdup(mem_ctx, logname);
779 NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
780 if (r->in.servername->string) {
781 e->Computername = r->in.servername->string;
783 e->Computername = talloc_strdup(mem_ctx, "");
784 NT_STATUS_HAVE_NO_MEMORY(e->Computername);
786 if (r->in.user_sid) {
787 e->UserSid = *r->in.user_sid;
789 e->Strings = talloc_array(mem_ctx, const char *, e->NumStrings);
790 NT_STATUS_HAVE_NO_MEMORY(e->Strings);
792 for (i=0; i < e->NumStrings; i++) {
793 e->Strings[i] = talloc_strdup(e->Strings,
794 r->in.strings[i]->string);
795 NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
797 e->Data = r->in.data;
802 /********************************************************************
803 _eventlog_ReportEventW
804 ********************************************************************/
806 NTSTATUS _eventlog_ReportEventW(struct pipes_struct *p,
807 struct eventlog_ReportEventW *r)
810 struct EVENTLOGRECORD record;
812 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
814 return NT_STATUS_INVALID_HANDLE;
817 status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record);
818 if (!NT_STATUS_IS_OK(status)) {
822 status = evlog_push_record(p->mem_ctx,
823 ELOG_TDB_CTX(info->etdb),
825 r->out.record_number);
826 if (!NT_STATUS_IS_OK(status)) {
833 /********************************************************************
834 ********************************************************************/
836 NTSTATUS _eventlog_DeregisterEventSource(struct pipes_struct *p,
837 struct eventlog_DeregisterEventSource *r)
839 p->rng_fault_state = True;
840 return NT_STATUS_NOT_IMPLEMENTED;
843 NTSTATUS _eventlog_ChangeNotify(struct pipes_struct *p,
844 struct eventlog_ChangeNotify *r)
846 p->rng_fault_state = True;
847 return NT_STATUS_NOT_IMPLEMENTED;
850 NTSTATUS _eventlog_RegisterEventSourceW(struct pipes_struct *p,
851 struct eventlog_RegisterEventSourceW *r)
853 p->rng_fault_state = True;
854 return NT_STATUS_NOT_IMPLEMENTED;
857 NTSTATUS _eventlog_OpenBackupEventLogW(struct pipes_struct *p,
858 struct eventlog_OpenBackupEventLogW *r)
860 p->rng_fault_state = True;
861 return NT_STATUS_NOT_IMPLEMENTED;
864 NTSTATUS _eventlog_ClearEventLogA(struct pipes_struct *p,
865 struct eventlog_ClearEventLogA *r)
867 p->rng_fault_state = True;
868 return NT_STATUS_NOT_IMPLEMENTED;
871 NTSTATUS _eventlog_BackupEventLogA(struct pipes_struct *p,
872 struct eventlog_BackupEventLogA *r)
874 p->rng_fault_state = True;
875 return NT_STATUS_NOT_IMPLEMENTED;
878 NTSTATUS _eventlog_OpenEventLogA(struct pipes_struct *p,
879 struct eventlog_OpenEventLogA *r)
881 p->rng_fault_state = True;
882 return NT_STATUS_NOT_IMPLEMENTED;
885 NTSTATUS _eventlog_RegisterEventSourceA(struct pipes_struct *p,
886 struct eventlog_RegisterEventSourceA *r)
888 p->rng_fault_state = True;
889 return NT_STATUS_NOT_IMPLEMENTED;
892 NTSTATUS _eventlog_OpenBackupEventLogA(struct pipes_struct *p,
893 struct eventlog_OpenBackupEventLogA *r)
895 p->rng_fault_state = True;
896 return NT_STATUS_NOT_IMPLEMENTED;
899 NTSTATUS _eventlog_ReadEventLogA(struct pipes_struct *p,
900 struct eventlog_ReadEventLogA *r)
902 p->rng_fault_state = True;
903 return NT_STATUS_NOT_IMPLEMENTED;
906 NTSTATUS _eventlog_ReportEventA(struct pipes_struct *p,
907 struct eventlog_ReportEventA *r)
909 p->rng_fault_state = True;
910 return NT_STATUS_NOT_IMPLEMENTED;
913 NTSTATUS _eventlog_RegisterClusterSvc(struct pipes_struct *p,
914 struct eventlog_RegisterClusterSvc *r)
916 p->rng_fault_state = True;
917 return NT_STATUS_NOT_IMPLEMENTED;
920 NTSTATUS _eventlog_DeregisterClusterSvc(struct pipes_struct *p,
921 struct eventlog_DeregisterClusterSvc *r)
923 p->rng_fault_state = True;
924 return NT_STATUS_NOT_IMPLEMENTED;
927 NTSTATUS _eventlog_WriteClusterEvents(struct pipes_struct *p,
928 struct eventlog_WriteClusterEvents *r)
930 p->rng_fault_state = True;
931 return NT_STATUS_NOT_IMPLEMENTED;
934 NTSTATUS _eventlog_ReportEventAndSourceW(struct pipes_struct *p,
935 struct eventlog_ReportEventAndSourceW *r)
937 p->rng_fault_state = True;
938 return NT_STATUS_NOT_IMPLEMENTED;