s3: remove POLICY_HND.
[jra/samba/.git] / source3 / rpc_server / srv_eventlog_nt.c
1 /*
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.
8  *
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.
13  *
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.
18  *
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/>.
21  */
22
23 #include "includes.h"
24
25 #undef  DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28 typedef struct {
29         char *logname;
30         ELOG_TDB *etdb;
31         uint32 current_record;
32         uint32 num_records;
33         uint32 oldest_entry;
34         uint32 flags;
35         uint32 access_granted;
36 } EVENTLOG_INFO;
37
38 /********************************************************************
39  ********************************************************************/
40
41 static int eventlog_info_destructor(EVENTLOG_INFO *elog)
42 {
43         if (elog->etdb) {
44                 elog_close_tdb(elog->etdb, false);
45         }
46         return 0;
47 }
48
49 /********************************************************************
50  ********************************************************************/
51
52 static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
53                                                 struct policy_handle * handle )
54 {
55         EVENTLOG_INFO *info;
56
57         if ( !find_policy_by_hnd( p, handle, (void **)(void *)&info ) ) {
58                 DEBUG( 2,
59                        ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
60                 return NULL;
61         }
62
63         return info;
64 }
65
66 /********************************************************************
67 ********************************************************************/
68
69 static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
70 {
71         char *tdbname = elog_tdbname(talloc_tos(), info->logname );
72         SEC_DESC *sec_desc;
73         NTSTATUS status;
74
75         if ( !tdbname )
76                 return False;
77
78         /* get the security descriptor for the file */
79
80         sec_desc = get_nt_acl_no_snum( info, tdbname );
81         TALLOC_FREE( tdbname );
82
83         if ( !sec_desc ) {
84                 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
85                         tdbname));
86                 return False;
87         }
88
89         /* root free pass */
90
91         if ( geteuid() == sec_initial_uid() ) {
92                 DEBUG(5,("elog_check_access: using root's token\n"));
93                 token = get_root_nt_token();
94         }
95
96         /* run the check, try for the max allowed */
97
98         status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
99                 &info->access_granted);
100
101         if ( sec_desc )
102                 TALLOC_FREE( sec_desc );
103
104         if (!NT_STATUS_IS_OK(status)) {
105                 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
106                         nt_errstr(status)));
107                 return False;
108         }
109
110         /* we have to have READ permission for a successful open */
111
112         return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
113 }
114
115 /********************************************************************
116  ********************************************************************/
117
118 static bool elog_validate_logname( const char *name )
119 {
120         int i;
121         const char **elogs = lp_eventlog_list();
122
123         if (!elogs) {
124                 return False;
125         }
126
127         for ( i=0; elogs[i]; i++ ) {
128                 if ( strequal( name, elogs[i] ) )
129                         return True;
130         }
131
132         return False;
133 }
134
135 /********************************************************************
136 ********************************************************************/
137
138 static bool get_num_records_hook( EVENTLOG_INFO * info )
139 {
140         int next_record;
141         int oldest_record;
142
143         if ( !info->etdb ) {
144                 DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
145                 return False;
146         }
147
148         /* lock the tdb since we have to get 2 records */
149
150         tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
151         next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
152         oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
153         tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
154
155         DEBUG( 8,
156                ( "Oldest Record %d; Next Record %d\n", oldest_record,
157                  next_record ) );
158
159         info->num_records = ( next_record - oldest_record );
160         info->oldest_entry = oldest_record;
161
162         return True;
163 }
164
165 /********************************************************************
166  ********************************************************************/
167
168 static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
169 {
170         /* it's the same thing */
171         return get_num_records_hook( info );
172 }
173
174 /********************************************************************
175  ********************************************************************/
176
177 static NTSTATUS elog_open( pipes_struct * p, const char *logname, struct policy_handle *hnd )
178 {
179         EVENTLOG_INFO *elog;
180
181         /* first thing is to validate the eventlog name */
182
183         if ( !elog_validate_logname( logname ) )
184                 return NT_STATUS_OBJECT_PATH_INVALID;
185
186         if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
187                 return NT_STATUS_NO_MEMORY;
188         talloc_set_destructor(elog, eventlog_info_destructor);
189
190         elog->logname = talloc_strdup( elog, logname );
191
192         /* Open the tdb first (so that we can create any new tdbs if necessary).
193            We have to do this as root and then use an internal access check
194            on the file permissions since you can only have a tdb open once
195            in a single process */
196
197         become_root();
198         elog->etdb = elog_open_tdb( elog->logname, False, False );
199         unbecome_root();
200
201         if ( !elog->etdb ) {
202                 /* according to MSDN, if the logfile cannot be found, we should
203                   default to the "Application" log */
204
205                 if ( !strequal( logname, ELOG_APPL ) ) {
206
207                         TALLOC_FREE( elog->logname );
208
209                         elog->logname = talloc_strdup( elog, ELOG_APPL );
210
211                         /* do the access check */
212                         if ( !elog_check_access( elog, p->server_info->ptok ) ) {
213                                 TALLOC_FREE( elog );
214                                 return NT_STATUS_ACCESS_DENIED;
215                         }
216
217                         become_root();
218                         elog->etdb = elog_open_tdb( elog->logname, False, False );
219                         unbecome_root();
220                 }
221
222                 if ( !elog->etdb ) {
223                         TALLOC_FREE( elog );
224                         return NT_STATUS_ACCESS_DENIED; /* ??? */
225                 }
226         }
227
228         /* now do the access check.  Close the tdb if we fail here */
229
230         if ( !elog_check_access( elog, p->server_info->ptok ) ) {
231                 TALLOC_FREE( elog );
232                 return NT_STATUS_ACCESS_DENIED;
233         }
234
235         /* create the policy handle */
236
237         if ( !create_policy_hnd( p, hnd, elog ) ) {
238                 TALLOC_FREE(elog);
239                 return NT_STATUS_NO_MEMORY;
240         }
241
242         /* set the initial current_record pointer */
243
244         if ( !get_oldest_entry_hook( elog ) ) {
245                 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
246                         "get any information on internal records!\n"));
247         }
248
249         elog->current_record = elog->oldest_entry;
250
251         return NT_STATUS_OK;
252 }
253
254 /********************************************************************
255  ********************************************************************/
256
257 static NTSTATUS elog_close( pipes_struct *p, struct policy_handle *hnd )
258 {
259         if ( !( close_policy_hnd( p, hnd ) ) ) {
260                 return NT_STATUS_INVALID_HANDLE;
261         }
262
263         return NT_STATUS_OK;
264 }
265
266 /*******************************************************************
267  *******************************************************************/
268
269 static int elog_size( EVENTLOG_INFO *info )
270 {
271         if ( !info || !info->etdb ) {
272                 DEBUG(0,("elog_size: Invalid info* structure!\n"));
273                 return 0;
274         }
275
276         return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
277 }
278
279 /********************************************************************
280  note that this can only be called AFTER the table is constructed,
281  since it uses the table to find the tdb handle
282  ********************************************************************/
283
284 static bool sync_eventlog_params( EVENTLOG_INFO *info )
285 {
286         char *path = NULL;
287         uint32 uiMaxSize;
288         uint32 uiRetention;
289         struct registry_key *key;
290         struct registry_value *value;
291         WERROR wresult;
292         char *elogname = info->logname;
293         TALLOC_CTX *ctx = talloc_stackframe();
294         bool ret = false;
295
296         DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
297
298         if ( !info->etdb ) {
299                 DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
300                 goto done;
301         }
302         /* set resonable defaults.  512Kb on size and 1 week on time */
303
304         uiMaxSize = 0x80000;
305         uiRetention = 604800;
306
307         /* the general idea is to internally open the registry
308            key and retrieve the values.  That way we can continue
309            to use the same fetch/store api that we use in
310            srv_reg_nt.c */
311
312         path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
313         if (!path) {
314                 goto done;
315         }
316
317         wresult = reg_open_path(ctx, path, REG_KEY_READ, get_root_nt_token(),
318                                 &key);
319
320         if ( !W_ERROR_IS_OK( wresult ) ) {
321                 DEBUG( 4,
322                        ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
323                          path, win_errstr( wresult ) ) );
324                 goto done;
325         }
326
327         wresult = reg_queryvalue(key, key, "Retention", &value);
328         if (!W_ERROR_IS_OK(wresult)) {
329                 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
330                           win_errstr(wresult)));
331                 goto done;
332         }
333         uiRetention = value->v.dword;
334
335         wresult = reg_queryvalue(key, key, "MaxSize", &value);
336         if (!W_ERROR_IS_OK(wresult)) {
337                 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
338                           win_errstr(wresult)));
339                 goto done;
340         }
341         uiMaxSize = value->v.dword;
342
343         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
344         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
345
346         ret = true;
347
348 done:
349         TALLOC_FREE(ctx);
350         return ret;
351 }
352
353 /********************************************************************
354  _eventlog_OpenEventLogW
355  ********************************************************************/
356
357 NTSTATUS _eventlog_OpenEventLogW(pipes_struct *p,
358                                  struct eventlog_OpenEventLogW *r)
359 {
360         EVENTLOG_INFO *info;
361         NTSTATUS result;
362
363         DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
364                 r->in.servername->string, r->in.logname->string ));
365
366         /* according to MSDN, if the logfile cannot be found, we should
367           default to the "Application" log */
368
369         if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
370                 return result;
371
372         if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
373                 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
374                         r->in.logname->string ));
375                 elog_close( p, r->out.handle );
376                 return NT_STATUS_INVALID_HANDLE;
377         }
378
379         DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
380
381         sync_eventlog_params( info );
382         prune_eventlog( ELOG_TDB_CTX(info->etdb) );
383
384         return NT_STATUS_OK;
385 }
386
387 /********************************************************************
388  _eventlog_ClearEventLogW
389  This call still needs some work
390  ********************************************************************/
391 /** The windows client seems to be doing something funny with the file name
392    A call like
393       ClearEventLog(handle, "backup_file")
394    on the client side will result in the backup file name looking like this on the
395    server side:
396       \??\${CWD of client}\backup_file
397    If an absolute path gets specified, such as
398       ClearEventLog(handle, "C:\\temp\\backup_file")
399    then it is still mangled by the client into this:
400       \??\C:\temp\backup_file
401    when it is on the wire.
402    I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
403    would be added in given that the backup file gets written on the server side. */
404
405 NTSTATUS _eventlog_ClearEventLogW(pipes_struct *p,
406                                   struct eventlog_ClearEventLogW *r)
407 {
408         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
409
410         if ( !info )
411                 return NT_STATUS_INVALID_HANDLE;
412
413         if (r->in.backupfile && r->in.backupfile->string) {
414
415                 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
416                         "file name for log [%s].",
417                          r->in.backupfile->string, info->logname ) );
418         }
419
420         /* check for WRITE access to the file */
421
422         if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) )
423                 return NT_STATUS_ACCESS_DENIED;
424
425         /* Force a close and reopen */
426
427         elog_close_tdb( info->etdb, True );
428         become_root();
429         info->etdb = elog_open_tdb( info->logname, True, False );
430         unbecome_root();
431
432         if ( !info->etdb )
433                 return NT_STATUS_ACCESS_DENIED;
434
435         return NT_STATUS_OK;
436 }
437
438 /********************************************************************
439  _eventlog_CloseEventLog
440  ********************************************************************/
441
442 NTSTATUS _eventlog_CloseEventLog(pipes_struct * p,
443                                  struct eventlog_CloseEventLog *r)
444 {
445         NTSTATUS status;
446
447         status = elog_close( p, r->in.handle );
448         if (!NT_STATUS_IS_OK(status)) {
449                 return status;
450         }
451
452         ZERO_STRUCTP(r->out.handle);
453
454         return NT_STATUS_OK;
455 }
456
457 /********************************************************************
458  _eventlog_ReadEventLogW
459  ********************************************************************/
460
461 NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p,
462                                  struct eventlog_ReadEventLogW *r)
463 {
464         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
465         uint32_t num_records_read = 0;
466         int bytes_left, record_number;
467         uint32_t elog_read_type, elog_read_dir;
468
469         if (!info) {
470                 return NT_STATUS_INVALID_HANDLE;
471         }
472
473         info->flags     = r->in.flags;
474         bytes_left      = r->in.number_of_bytes;
475
476         if (!info->etdb) {
477                 return NT_STATUS_ACCESS_DENIED;
478         }
479
480         /* check for valid flags.  Can't use the sequential and seek flags together */
481
482         elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
483         elog_read_dir  = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
484
485         if (r->in.flags == 0 ||
486             elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
487             elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
488         {
489                 DEBUG(3,("_eventlog_ReadEventLogW: "
490                         "Invalid flags [0x%08x] for ReadEventLog\n",
491                         r->in.flags));
492                 return NT_STATUS_INVALID_PARAMETER;
493         }
494
495         /* a sequential read should ignore the offset */
496
497         if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
498                 record_number = info->current_record;
499         } else {
500                 record_number = r->in.offset;
501         }
502
503         if (r->in.number_of_bytes == 0) {
504                 struct EVENTLOGRECORD *e;
505                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
506                                       record_number);
507                 if (!e) {
508                         return NT_STATUS_END_OF_FILE;
509                 }
510                 *r->out.real_size = e->Length;
511                 return NT_STATUS_BUFFER_TOO_SMALL;
512         }
513
514         while (bytes_left > 0) {
515
516                 DATA_BLOB blob;
517                 enum ndr_err_code ndr_err;
518                 struct EVENTLOGRECORD *e;
519
520                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
521                                       record_number);
522                 if (!e) {
523                         break;
524                 }
525
526                 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL, e,
527                               (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
528                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
529                         return ndr_map_error2ntstatus(ndr_err);
530                 }
531
532                 if (DEBUGLEVEL >= 10) {
533                         NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
534                 }
535
536                 if (blob.length > r->in.number_of_bytes) {
537                         *r->out.real_size = blob.length;
538                         return NT_STATUS_BUFFER_TOO_SMALL;
539                 }
540
541                 if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
542                         break;
543                 }
544
545                 bytes_left -= blob.length;
546
547                 if (info->flags & EVENTLOG_FORWARDS_READ) {
548                         record_number++;
549                 } else {
550                         record_number--;
551                 }
552
553                 /* update the eventlog record pointer */
554
555                 info->current_record = record_number;
556
557                 memcpy(&r->out.data[*(r->out.sent_size)],
558                        blob.data, blob.length);
559                 *(r->out.sent_size) += blob.length;
560
561                 num_records_read++;
562         }
563
564         if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
565                 return NT_STATUS_END_OF_FILE;
566         }
567
568         return NT_STATUS_OK;
569 }
570
571 /********************************************************************
572  _eventlog_GetOldestRecord
573  ********************************************************************/
574
575 NTSTATUS _eventlog_GetOldestRecord(pipes_struct *p,
576                                    struct eventlog_GetOldestRecord *r)
577 {
578         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
579
580         if (info == NULL) {
581                 return NT_STATUS_INVALID_HANDLE;
582         }
583
584         if ( !( get_oldest_entry_hook( info ) ) )
585                 return NT_STATUS_ACCESS_DENIED;
586
587         *r->out.oldest_entry = info->oldest_entry;
588
589         return NT_STATUS_OK;
590 }
591
592 /********************************************************************
593 _eventlog_GetNumRecords
594  ********************************************************************/
595
596 NTSTATUS _eventlog_GetNumRecords(pipes_struct *p,
597                                  struct eventlog_GetNumRecords *r)
598 {
599         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
600
601         if (info == NULL) {
602                 return NT_STATUS_INVALID_HANDLE;
603         }
604
605         if ( !( get_num_records_hook( info ) ) )
606                 return NT_STATUS_ACCESS_DENIED;
607
608         *r->out.number = info->num_records;
609
610         return NT_STATUS_OK;
611 }
612
613 NTSTATUS _eventlog_BackupEventLogW(pipes_struct *p, struct eventlog_BackupEventLogW *r)
614 {
615         p->rng_fault_state = True;
616         return NT_STATUS_NOT_IMPLEMENTED;
617 }
618
619 NTSTATUS _eventlog_DeregisterEventSource(pipes_struct *p, struct eventlog_DeregisterEventSource *r)
620 {
621         p->rng_fault_state = True;
622         return NT_STATUS_NOT_IMPLEMENTED;
623 }
624
625 NTSTATUS _eventlog_ChangeNotify(pipes_struct *p, struct eventlog_ChangeNotify *r)
626 {
627         p->rng_fault_state = True;
628         return NT_STATUS_NOT_IMPLEMENTED;
629 }
630
631 NTSTATUS _eventlog_RegisterEventSourceW(pipes_struct *p, struct eventlog_RegisterEventSourceW *r)
632 {
633         p->rng_fault_state = True;
634         return NT_STATUS_NOT_IMPLEMENTED;
635 }
636
637 NTSTATUS _eventlog_OpenBackupEventLogW(pipes_struct *p, struct eventlog_OpenBackupEventLogW *r)
638 {
639         p->rng_fault_state = True;
640         return NT_STATUS_NOT_IMPLEMENTED;
641 }
642
643 NTSTATUS _eventlog_ReportEventW(pipes_struct *p, struct eventlog_ReportEventW *r)
644 {
645         p->rng_fault_state = True;
646         return NT_STATUS_NOT_IMPLEMENTED;
647 }
648
649 NTSTATUS _eventlog_ClearEventLogA(pipes_struct *p, struct eventlog_ClearEventLogA *r)
650 {
651         p->rng_fault_state = True;
652         return NT_STATUS_NOT_IMPLEMENTED;
653 }
654
655 NTSTATUS _eventlog_BackupEventLogA(pipes_struct *p, struct eventlog_BackupEventLogA *r)
656 {
657         p->rng_fault_state = True;
658         return NT_STATUS_NOT_IMPLEMENTED;
659 }
660
661 NTSTATUS _eventlog_OpenEventLogA(pipes_struct *p, struct eventlog_OpenEventLogA *r)
662 {
663         p->rng_fault_state = True;
664         return NT_STATUS_NOT_IMPLEMENTED;
665 }
666
667 NTSTATUS _eventlog_RegisterEventSourceA(pipes_struct *p, struct eventlog_RegisterEventSourceA *r)
668 {
669         p->rng_fault_state = True;
670         return NT_STATUS_NOT_IMPLEMENTED;
671 }
672
673 NTSTATUS _eventlog_OpenBackupEventLogA(pipes_struct *p, struct eventlog_OpenBackupEventLogA *r)
674 {
675         p->rng_fault_state = True;
676         return NT_STATUS_NOT_IMPLEMENTED;
677 }
678
679 NTSTATUS _eventlog_ReadEventLogA(pipes_struct *p, struct eventlog_ReadEventLogA *r)
680 {
681         p->rng_fault_state = True;
682         return NT_STATUS_NOT_IMPLEMENTED;
683 }
684
685 NTSTATUS _eventlog_ReportEventA(pipes_struct *p, struct eventlog_ReportEventA *r)
686 {
687         p->rng_fault_state = True;
688         return NT_STATUS_NOT_IMPLEMENTED;
689 }
690
691 NTSTATUS _eventlog_RegisterClusterSvc(pipes_struct *p, struct eventlog_RegisterClusterSvc *r)
692 {
693         p->rng_fault_state = True;
694         return NT_STATUS_NOT_IMPLEMENTED;
695 }
696
697 NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_DeregisterClusterSvc *r)
698 {
699         p->rng_fault_state = True;
700         return NT_STATUS_NOT_IMPLEMENTED;
701 }
702
703 NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r)
704 {
705         p->rng_fault_state = True;
706         return NT_STATUS_NOT_IMPLEMENTED;
707 }
708
709 NTSTATUS _eventlog_GetLogInformation(pipes_struct *p, struct eventlog_GetLogInformation *r)
710 {
711         p->rng_fault_state = True;
712         return NT_STATUS_NOT_IMPLEMENTED;
713 }
714
715 NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r)
716 {
717         p->rng_fault_state = True;
718         return NT_STATUS_NOT_IMPLEMENTED;
719 }
720
721 NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r)
722 {
723         p->rng_fault_state = True;
724         return NT_STATUS_NOT_IMPLEMENTED;
725 }