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