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"
27 #define DBGC_CLASS DBGC_RPC_SRV
32 uint32 current_record
;
36 uint32 access_granted
;
39 /********************************************************************
40 ********************************************************************/
42 static int eventlog_info_destructor(EVENTLOG_INFO
*elog
)
45 elog_close_tdb(elog
->etdb
, false);
50 /********************************************************************
51 ********************************************************************/
53 static EVENTLOG_INFO
*find_eventlog_info_by_hnd( pipes_struct
* p
,
54 struct policy_handle
* handle
)
58 if ( !find_policy_by_hnd( p
, handle
, (void **)(void *)&info
) ) {
60 ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
67 /********************************************************************
68 ********************************************************************/
70 static bool elog_check_access( EVENTLOG_INFO
*info
, NT_USER_TOKEN
*token
)
72 char *tdbname
= elog_tdbname(talloc_tos(), info
->logname
);
79 /* get the security descriptor for the file */
81 sec_desc
= get_nt_acl_no_snum( info
, tdbname
);
82 TALLOC_FREE( tdbname
);
85 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
92 if ( geteuid() == sec_initial_uid() ) {
93 DEBUG(5,("elog_check_access: using root's token\n"));
94 token
= get_root_nt_token();
97 /* run the check, try for the max allowed */
99 status
= se_access_check( sec_desc
, token
, MAXIMUM_ALLOWED_ACCESS
,
100 &info
->access_granted
);
103 TALLOC_FREE( sec_desc
);
105 if (!NT_STATUS_IS_OK(status
)) {
106 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
111 /* we have to have READ permission for a successful open */
113 return ( info
->access_granted
& SA_RIGHT_FILE_READ_DATA
);
116 /********************************************************************
117 ********************************************************************/
119 static bool elog_validate_logname( const char *name
)
122 const char **elogs
= lp_eventlog_list();
128 for ( i
=0; elogs
[i
]; i
++ ) {
129 if ( strequal( name
, elogs
[i
] ) )
136 /********************************************************************
137 ********************************************************************/
139 static bool get_num_records_hook( EVENTLOG_INFO
* info
)
145 DEBUG( 10, ( "No open tdb for %s\n", info
->logname
) );
149 /* lock the tdb since we have to get 2 records */
151 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
, 1 );
152 next_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
153 oldest_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_OLDEST_ENTRY
);
154 tdb_unlock_bystring( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
157 ( "Oldest Record %d; Next Record %d\n", oldest_record
,
160 info
->num_records
= ( next_record
- oldest_record
);
161 info
->oldest_entry
= oldest_record
;
166 /********************************************************************
167 ********************************************************************/
169 static bool get_oldest_entry_hook( EVENTLOG_INFO
* info
)
171 /* it's the same thing */
172 return get_num_records_hook( info
);
175 /********************************************************************
176 ********************************************************************/
178 static NTSTATUS
elog_open( pipes_struct
* p
, const char *logname
, struct policy_handle
*hnd
)
182 /* first thing is to validate the eventlog name */
184 if ( !elog_validate_logname( logname
) )
185 return NT_STATUS_OBJECT_PATH_INVALID
;
187 if ( !(elog
= TALLOC_ZERO_P( NULL
, EVENTLOG_INFO
)) )
188 return NT_STATUS_NO_MEMORY
;
189 talloc_set_destructor(elog
, eventlog_info_destructor
);
191 elog
->logname
= talloc_strdup( elog
, logname
);
193 /* Open the tdb first (so that we can create any new tdbs if necessary).
194 We have to do this as root and then use an internal access check
195 on the file permissions since you can only have a tdb open once
196 in a single process */
199 elog
->etdb
= elog_open_tdb( elog
->logname
, False
, False
);
203 /* according to MSDN, if the logfile cannot be found, we should
204 default to the "Application" log */
206 if ( !strequal( logname
, ELOG_APPL
) ) {
208 TALLOC_FREE( elog
->logname
);
210 elog
->logname
= talloc_strdup( elog
, ELOG_APPL
);
212 /* do the access check */
213 if ( !elog_check_access( elog
, p
->server_info
->ptok
) ) {
215 return NT_STATUS_ACCESS_DENIED
;
219 elog
->etdb
= elog_open_tdb( elog
->logname
, False
, False
);
225 return NT_STATUS_ACCESS_DENIED
; /* ??? */
229 /* now do the access check. Close the tdb if we fail here */
231 if ( !elog_check_access( elog
, p
->server_info
->ptok
) ) {
233 return NT_STATUS_ACCESS_DENIED
;
236 /* create the policy handle */
238 if ( !create_policy_hnd( p
, hnd
, elog
) ) {
240 return NT_STATUS_NO_MEMORY
;
243 /* set the initial current_record pointer */
245 if ( !get_oldest_entry_hook( elog
) ) {
246 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
247 "get any information on internal records!\n"));
250 elog
->current_record
= elog
->oldest_entry
;
255 /********************************************************************
256 ********************************************************************/
258 static NTSTATUS
elog_close( pipes_struct
*p
, struct policy_handle
*hnd
)
260 if ( !( close_policy_hnd( p
, hnd
) ) ) {
261 return NT_STATUS_INVALID_HANDLE
;
267 /*******************************************************************
268 *******************************************************************/
270 static int elog_size( EVENTLOG_INFO
*info
)
272 if ( !info
|| !info
->etdb
) {
273 DEBUG(0,("elog_size: Invalid info* structure!\n"));
277 return elog_tdb_size( ELOG_TDB_CTX(info
->etdb
), NULL
, NULL
);
280 /********************************************************************
281 note that this can only be called AFTER the table is constructed,
282 since it uses the table to find the tdb handle
283 ********************************************************************/
285 static bool sync_eventlog_params( EVENTLOG_INFO
*info
)
290 struct registry_key
*key
;
291 struct registry_value
*value
;
293 char *elogname
= info
->logname
;
294 TALLOC_CTX
*ctx
= talloc_stackframe();
297 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname
) );
300 DEBUG( 4, ( "No open tdb! (%s)\n", info
->logname
) );
303 /* set resonable defaults. 512Kb on size and 1 week on time */
306 uiRetention
= 604800;
308 /* the general idea is to internally open the registry
309 key and retrieve the values. That way we can continue
310 to use the same fetch/store api that we use in
313 path
= talloc_asprintf(ctx
, "%s/%s", KEY_EVENTLOG
, elogname
);
318 wresult
= reg_open_path(ctx
, path
, REG_KEY_READ
, get_root_nt_token(),
321 if ( !W_ERROR_IS_OK( wresult
) ) {
323 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
324 path
, win_errstr( wresult
) ) );
328 wresult
= reg_queryvalue(key
, key
, "Retention", &value
);
329 if (!W_ERROR_IS_OK(wresult
)) {
330 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
331 win_errstr(wresult
)));
334 uiRetention
= value
->v
.dword
;
336 wresult
= reg_queryvalue(key
, key
, "MaxSize", &value
);
337 if (!W_ERROR_IS_OK(wresult
)) {
338 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
339 win_errstr(wresult
)));
342 uiMaxSize
= value
->v
.dword
;
344 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_MAXSIZE
, uiMaxSize
);
345 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_RETENTION
, uiRetention
);
354 /********************************************************************
355 _eventlog_OpenEventLogW
356 ********************************************************************/
358 NTSTATUS
_eventlog_OpenEventLogW(pipes_struct
*p
,
359 struct eventlog_OpenEventLogW
*r
)
364 DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
365 r
->in
.servername
->string
, r
->in
.logname
->string
));
367 /* according to MSDN, if the logfile cannot be found, we should
368 default to the "Application" log */
370 if ( !NT_STATUS_IS_OK( result
= elog_open( p
, r
->in
.logname
->string
, r
->out
.handle
)) )
373 if ( !(info
= find_eventlog_info_by_hnd( p
, r
->out
.handle
)) ) {
374 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
375 r
->in
.logname
->string
));
376 elog_close( p
, r
->out
.handle
);
377 return NT_STATUS_INVALID_HANDLE
;
380 DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info
)));
382 sync_eventlog_params( info
);
383 prune_eventlog( ELOG_TDB_CTX(info
->etdb
) );
388 /********************************************************************
389 _eventlog_ClearEventLogW
390 This call still needs some work
391 ********************************************************************/
392 /** The windows client seems to be doing something funny with the file name
394 ClearEventLog(handle, "backup_file")
395 on the client side will result in the backup file name looking like this on the
397 \??\${CWD of client}\backup_file
398 If an absolute path gets specified, such as
399 ClearEventLog(handle, "C:\\temp\\backup_file")
400 then it is still mangled by the client into this:
401 \??\C:\temp\backup_file
402 when it is on the wire.
403 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
404 would be added in given that the backup file gets written on the server side. */
406 NTSTATUS
_eventlog_ClearEventLogW(pipes_struct
*p
,
407 struct eventlog_ClearEventLogW
*r
)
409 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
412 return NT_STATUS_INVALID_HANDLE
;
414 if (r
->in
.backupfile
&& r
->in
.backupfile
->string
) {
416 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
417 "file name for log [%s].",
418 r
->in
.backupfile
->string
, info
->logname
) );
421 /* check for WRITE access to the file */
423 if ( !(info
->access_granted
&SA_RIGHT_FILE_WRITE_DATA
) )
424 return NT_STATUS_ACCESS_DENIED
;
426 /* Force a close and reopen */
428 elog_close_tdb( info
->etdb
, True
);
430 info
->etdb
= elog_open_tdb( info
->logname
, True
, False
);
434 return NT_STATUS_ACCESS_DENIED
;
439 /********************************************************************
440 _eventlog_CloseEventLog
441 ********************************************************************/
443 NTSTATUS
_eventlog_CloseEventLog(pipes_struct
* p
,
444 struct eventlog_CloseEventLog
*r
)
448 status
= elog_close( p
, r
->in
.handle
);
449 if (!NT_STATUS_IS_OK(status
)) {
453 ZERO_STRUCTP(r
->out
.handle
);
458 /********************************************************************
459 _eventlog_ReadEventLogW
460 ********************************************************************/
462 NTSTATUS
_eventlog_ReadEventLogW(pipes_struct
*p
,
463 struct eventlog_ReadEventLogW
*r
)
465 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
466 uint32_t num_records_read
= 0;
467 int bytes_left
, record_number
;
468 uint32_t elog_read_type
, elog_read_dir
;
471 return NT_STATUS_INVALID_HANDLE
;
474 info
->flags
= r
->in
.flags
;
475 bytes_left
= r
->in
.number_of_bytes
;
478 return NT_STATUS_ACCESS_DENIED
;
481 /* check for valid flags. Can't use the sequential and seek flags together */
483 elog_read_type
= r
->in
.flags
& (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
);
484 elog_read_dir
= r
->in
.flags
& (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
);
486 if (r
->in
.flags
== 0 ||
487 elog_read_type
== (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
) ||
488 elog_read_dir
== (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
))
490 DEBUG(3,("_eventlog_ReadEventLogW: "
491 "Invalid flags [0x%08x] for ReadEventLog\n",
493 return NT_STATUS_INVALID_PARAMETER
;
496 /* a sequential read should ignore the offset */
498 if (elog_read_type
& EVENTLOG_SEQUENTIAL_READ
) {
499 record_number
= info
->current_record
;
501 record_number
= r
->in
.offset
;
504 if (r
->in
.number_of_bytes
== 0) {
505 struct EVENTLOGRECORD
*e
;
506 e
= evlog_pull_record(p
->mem_ctx
, ELOG_TDB_CTX(info
->etdb
),
509 return NT_STATUS_END_OF_FILE
;
511 *r
->out
.real_size
= e
->Length
;
512 return NT_STATUS_BUFFER_TOO_SMALL
;
515 while (bytes_left
> 0) {
518 enum ndr_err_code ndr_err
;
519 struct EVENTLOGRECORD
*e
;
521 e
= evlog_pull_record(p
->mem_ctx
, ELOG_TDB_CTX(info
->etdb
),
527 ndr_err
= ndr_push_struct_blob(&blob
, p
->mem_ctx
, NULL
, e
,
528 (ndr_push_flags_fn_t
)ndr_push_EVENTLOGRECORD
);
529 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
530 return ndr_map_error2ntstatus(ndr_err
);
533 if (DEBUGLEVEL
>= 10) {
534 NDR_PRINT_DEBUG(EVENTLOGRECORD
, e
);
537 if (blob
.length
> r
->in
.number_of_bytes
) {
538 *r
->out
.real_size
= blob
.length
;
539 return NT_STATUS_BUFFER_TOO_SMALL
;
542 if (*r
->out
.sent_size
+ blob
.length
> r
->in
.number_of_bytes
) {
546 bytes_left
-= blob
.length
;
548 if (info
->flags
& EVENTLOG_FORWARDS_READ
) {
554 /* update the eventlog record pointer */
556 info
->current_record
= record_number
;
558 memcpy(&r
->out
.data
[*(r
->out
.sent_size
)],
559 blob
.data
, blob
.length
);
560 *(r
->out
.sent_size
) += blob
.length
;
565 if (r
->in
.offset
== 0 && record_number
== 0 && *r
->out
.sent_size
== 0) {
566 return NT_STATUS_END_OF_FILE
;
572 /********************************************************************
573 _eventlog_GetOldestRecord
574 ********************************************************************/
576 NTSTATUS
_eventlog_GetOldestRecord(pipes_struct
*p
,
577 struct eventlog_GetOldestRecord
*r
)
579 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
582 return NT_STATUS_INVALID_HANDLE
;
585 if ( !( get_oldest_entry_hook( info
) ) )
586 return NT_STATUS_ACCESS_DENIED
;
588 *r
->out
.oldest_entry
= info
->oldest_entry
;
593 /********************************************************************
594 _eventlog_GetNumRecords
595 ********************************************************************/
597 NTSTATUS
_eventlog_GetNumRecords(pipes_struct
*p
,
598 struct eventlog_GetNumRecords
*r
)
600 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
603 return NT_STATUS_INVALID_HANDLE
;
606 if ( !( get_num_records_hook( info
) ) )
607 return NT_STATUS_ACCESS_DENIED
;
609 *r
->out
.number
= info
->num_records
;
614 NTSTATUS
_eventlog_BackupEventLogW(pipes_struct
*p
, struct eventlog_BackupEventLogW
*r
)
616 p
->rng_fault_state
= True
;
617 return NT_STATUS_NOT_IMPLEMENTED
;
620 /********************************************************************
621 _eventlog_GetLogInformation
622 ********************************************************************/
624 NTSTATUS
_eventlog_GetLogInformation(pipes_struct
*p
,
625 struct eventlog_GetLogInformation
*r
)
627 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd(p
, r
->in
.handle
);
628 struct EVENTLOG_FULL_INFORMATION f
;
629 enum ndr_err_code ndr_err
;
633 return NT_STATUS_INVALID_HANDLE
;
636 if (r
->in
.level
!= 0) {
637 return NT_STATUS_INVALID_LEVEL
;
640 *r
->out
.bytes_needed
= 4;
642 if (r
->in
.buf_size
< 4) {
643 return NT_STATUS_BUFFER_TOO_SMALL
;
646 /* FIXME: this should be retrieved from the handle */
649 ndr_err
= ndr_push_struct_blob(&blob
, p
->mem_ctx
, NULL
, &f
,
650 (ndr_push_flags_fn_t
)ndr_push_EVENTLOG_FULL_INFORMATION
);
651 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
652 return ndr_map_error2ntstatus(ndr_err
);
655 if (DEBUGLEVEL
>= 10) {
656 NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION
, &f
);
659 memcpy(r
->out
.buffer
, blob
.data
, 4);
664 /********************************************************************
665 _eventlog_FlushEventLog
666 ********************************************************************/
668 NTSTATUS
_eventlog_FlushEventLog(pipes_struct
*p
,
669 struct eventlog_FlushEventLog
*r
)
671 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd(p
, r
->in
.handle
);
673 return NT_STATUS_INVALID_HANDLE
;
676 return NT_STATUS_ACCESS_DENIED
;
679 /********************************************************************
680 ********************************************************************/
682 static NTSTATUS
evlog_report_to_record(TALLOC_CTX
*mem_ctx
,
683 const struct eventlog_ReportEventW
*r
,
685 struct EVENTLOGRECORD
*e
)
690 e
->TimeGenerated
= r
->in
.timestamp
;
691 e
->TimeWritten
= time(NULL
);
692 e
->EventID
= r
->in
.event_id
;
693 e
->EventType
= r
->in
.event_type
;
694 e
->NumStrings
= r
->in
.num_of_strings
;
695 e
->EventCategory
= r
->in
.event_category
;
696 e
->ReservedFlags
= r
->in
.flags
;
697 e
->DataLength
= r
->in
.data_size
;
698 e
->SourceName
= talloc_strdup(mem_ctx
, logname
);
699 NT_STATUS_HAVE_NO_MEMORY(e
->SourceName
);
700 if (r
->in
.servername
->string
) {
701 e
->Computername
= r
->in
.servername
->string
;
703 e
->Computername
= talloc_strdup(mem_ctx
, "");
704 NT_STATUS_HAVE_NO_MEMORY(e
->Computername
);
706 if (r
->in
.user_sid
) {
707 e
->UserSid
= *r
->in
.user_sid
;
709 e
->Strings
= talloc_array(mem_ctx
, const char *, e
->NumStrings
);
710 NT_STATUS_HAVE_NO_MEMORY(e
->Strings
);
712 for (i
=0; i
< e
->NumStrings
; i
++) {
713 e
->Strings
[i
] = talloc_strdup(e
->Strings
,
714 r
->in
.strings
[i
]->string
);
715 NT_STATUS_HAVE_NO_MEMORY(e
->Strings
[i
]);
717 e
->Data
= r
->in
.data
;
722 /********************************************************************
723 _eventlog_ReportEventW
724 ********************************************************************/
726 NTSTATUS
_eventlog_ReportEventW(pipes_struct
*p
,
727 struct eventlog_ReportEventW
*r
)
730 struct EVENTLOGRECORD record
;
732 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd(p
, r
->in
.handle
);
734 return NT_STATUS_INVALID_HANDLE
;
737 status
= evlog_report_to_record(p
->mem_ctx
, r
, info
->logname
, &record
);
738 if (!NT_STATUS_IS_OK(status
)) {
742 status
= evlog_push_record(p
->mem_ctx
,
743 ELOG_TDB_CTX(info
->etdb
),
745 r
->out
.record_number
);
746 if (!NT_STATUS_IS_OK(status
)) {
753 /********************************************************************
754 ********************************************************************/
756 NTSTATUS
_eventlog_DeregisterEventSource(pipes_struct
*p
, struct eventlog_DeregisterEventSource
*r
)
758 p
->rng_fault_state
= True
;
759 return NT_STATUS_NOT_IMPLEMENTED
;
762 NTSTATUS
_eventlog_ChangeNotify(pipes_struct
*p
, struct eventlog_ChangeNotify
*r
)
764 p
->rng_fault_state
= True
;
765 return NT_STATUS_NOT_IMPLEMENTED
;
768 NTSTATUS
_eventlog_RegisterEventSourceW(pipes_struct
*p
, struct eventlog_RegisterEventSourceW
*r
)
770 p
->rng_fault_state
= True
;
771 return NT_STATUS_NOT_IMPLEMENTED
;
774 NTSTATUS
_eventlog_OpenBackupEventLogW(pipes_struct
*p
, struct eventlog_OpenBackupEventLogW
*r
)
776 p
->rng_fault_state
= True
;
777 return NT_STATUS_NOT_IMPLEMENTED
;
780 NTSTATUS
_eventlog_ClearEventLogA(pipes_struct
*p
, struct eventlog_ClearEventLogA
*r
)
782 p
->rng_fault_state
= True
;
783 return NT_STATUS_NOT_IMPLEMENTED
;
786 NTSTATUS
_eventlog_BackupEventLogA(pipes_struct
*p
, struct eventlog_BackupEventLogA
*r
)
788 p
->rng_fault_state
= True
;
789 return NT_STATUS_NOT_IMPLEMENTED
;
792 NTSTATUS
_eventlog_OpenEventLogA(pipes_struct
*p
, struct eventlog_OpenEventLogA
*r
)
794 p
->rng_fault_state
= True
;
795 return NT_STATUS_NOT_IMPLEMENTED
;
798 NTSTATUS
_eventlog_RegisterEventSourceA(pipes_struct
*p
, struct eventlog_RegisterEventSourceA
*r
)
800 p
->rng_fault_state
= True
;
801 return NT_STATUS_NOT_IMPLEMENTED
;
804 NTSTATUS
_eventlog_OpenBackupEventLogA(pipes_struct
*p
, struct eventlog_OpenBackupEventLogA
*r
)
806 p
->rng_fault_state
= True
;
807 return NT_STATUS_NOT_IMPLEMENTED
;
810 NTSTATUS
_eventlog_ReadEventLogA(pipes_struct
*p
, struct eventlog_ReadEventLogA
*r
)
812 p
->rng_fault_state
= True
;
813 return NT_STATUS_NOT_IMPLEMENTED
;
816 NTSTATUS
_eventlog_ReportEventA(pipes_struct
*p
, struct eventlog_ReportEventA
*r
)
818 p
->rng_fault_state
= True
;
819 return NT_STATUS_NOT_IMPLEMENTED
;
822 NTSTATUS
_eventlog_RegisterClusterSvc(pipes_struct
*p
, struct eventlog_RegisterClusterSvc
*r
)
824 p
->rng_fault_state
= True
;
825 return NT_STATUS_NOT_IMPLEMENTED
;
828 NTSTATUS
_eventlog_DeregisterClusterSvc(pipes_struct
*p
, struct eventlog_DeregisterClusterSvc
*r
)
830 p
->rng_fault_state
= True
;
831 return NT_STATUS_NOT_IMPLEMENTED
;
834 NTSTATUS
_eventlog_WriteClusterEvents(pipes_struct
*p
, struct eventlog_WriteClusterEvents
*r
)
836 p
->rng_fault_state
= True
;
837 return NT_STATUS_NOT_IMPLEMENTED
;
840 NTSTATUS
_eventlog_ReportEventAndSourceW(pipes_struct
*p
, struct eventlog_ReportEventAndSourceW
*r
)
842 p
->rng_fault_state
= True
;
843 return NT_STATUS_NOT_IMPLEMENTED
;