s3:auth Remove NT_USER_TOKEN
[gd/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( struct 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, struct security_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( struct 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( struct 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_t uiMaxSize = 0;
308         uint32_t uiRetention = 0;
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
354         if (value->data.length >= 4) {
355                 uiRetention = IVAL(value->data.data, 0);
356         }
357
358         wresult = reg_queryvalue(key, key, "MaxSize", &value);
359         if (!W_ERROR_IS_OK(wresult)) {
360                 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
361                           win_errstr(wresult)));
362                 goto done;
363         }
364         if (value->data.length >= 4) {
365                 uiMaxSize = IVAL(value->data.data, 0);
366         }
367
368         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
369         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
370
371         ret = true;
372
373 done:
374         TALLOC_FREE(ctx);
375         return ret;
376 }
377
378 /********************************************************************
379  _eventlog_OpenEventLogW
380  ********************************************************************/
381
382 NTSTATUS _eventlog_OpenEventLogW(struct pipes_struct *p,
383                                  struct eventlog_OpenEventLogW *r)
384 {
385         EVENTLOG_INFO *info;
386         NTSTATUS result;
387
388         DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
389                 r->in.servername->string, r->in.logname->string ));
390
391         /* according to MSDN, if the logfile cannot be found, we should
392           default to the "Application" log */
393
394         if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
395                 return result;
396
397         if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
398                 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
399                         r->in.logname->string ));
400                 elog_close( p, r->out.handle );
401                 return NT_STATUS_INVALID_HANDLE;
402         }
403
404         DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
405
406         if (!sync_eventlog_params(info)) {
407                 elog_close(p, r->out.handle);
408                 return NT_STATUS_EVENTLOG_FILE_CORRUPT;
409         }
410         prune_eventlog( ELOG_TDB_CTX(info->etdb) );
411
412         return NT_STATUS_OK;
413 }
414
415 /********************************************************************
416  _eventlog_ClearEventLogW
417  This call still needs some work
418  ********************************************************************/
419 /** The windows client seems to be doing something funny with the file name
420    A call like
421       ClearEventLog(handle, "backup_file")
422    on the client side will result in the backup file name looking like this on the
423    server side:
424       \??\${CWD of client}\backup_file
425    If an absolute path gets specified, such as
426       ClearEventLog(handle, "C:\\temp\\backup_file")
427    then it is still mangled by the client into this:
428       \??\C:\temp\backup_file
429    when it is on the wire.
430    I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
431    would be added in given that the backup file gets written on the server side. */
432
433 NTSTATUS _eventlog_ClearEventLogW(struct pipes_struct *p,
434                                   struct eventlog_ClearEventLogW *r)
435 {
436         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
437
438         if ( !info )
439                 return NT_STATUS_INVALID_HANDLE;
440
441         if (r->in.backupfile && r->in.backupfile->string) {
442
443                 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
444                         "file name for log [%s].",
445                          r->in.backupfile->string, info->logname ) );
446         }
447
448         /* check for WRITE access to the file */
449
450         if ( !(info->access_granted & SEC_FILE_WRITE_DATA) )
451                 return NT_STATUS_ACCESS_DENIED;
452
453         /* Force a close and reopen */
454
455         elog_close_tdb( info->etdb, True );
456         become_root();
457         info->etdb = elog_open_tdb( info->logname, True, False );
458         unbecome_root();
459
460         if ( !info->etdb )
461                 return NT_STATUS_ACCESS_DENIED;
462
463         return NT_STATUS_OK;
464 }
465
466 /********************************************************************
467  _eventlog_CloseEventLog
468  ********************************************************************/
469
470 NTSTATUS _eventlog_CloseEventLog(struct pipes_struct * p,
471                                  struct eventlog_CloseEventLog *r)
472 {
473         NTSTATUS status;
474
475         status = elog_close( p, r->in.handle );
476         if (!NT_STATUS_IS_OK(status)) {
477                 return status;
478         }
479
480         ZERO_STRUCTP(r->out.handle);
481
482         return NT_STATUS_OK;
483 }
484
485 /********************************************************************
486  _eventlog_ReadEventLogW
487  ********************************************************************/
488
489 NTSTATUS _eventlog_ReadEventLogW(struct pipes_struct *p,
490                                  struct eventlog_ReadEventLogW *r)
491 {
492         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
493         uint32_t num_records_read = 0;
494         int bytes_left, record_number;
495         uint32_t elog_read_type, elog_read_dir;
496
497         if (!info) {
498                 return NT_STATUS_INVALID_HANDLE;
499         }
500
501         info->flags     = r->in.flags;
502         bytes_left      = r->in.number_of_bytes;
503
504         if (!info->etdb) {
505                 return NT_STATUS_ACCESS_DENIED;
506         }
507
508         /* check for valid flags.  Can't use the sequential and seek flags together */
509
510         elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
511         elog_read_dir  = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
512
513         if (r->in.flags == 0 ||
514             elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
515             elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
516         {
517                 DEBUG(3,("_eventlog_ReadEventLogW: "
518                         "Invalid flags [0x%08x] for ReadEventLog\n",
519                         r->in.flags));
520                 return NT_STATUS_INVALID_PARAMETER;
521         }
522
523         /* a sequential read should ignore the offset */
524
525         if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
526                 record_number = info->current_record;
527         } else {
528                 record_number = r->in.offset;
529         }
530
531         if (r->in.number_of_bytes == 0) {
532                 struct EVENTLOGRECORD *e;
533                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
534                                       record_number);
535                 if (!e) {
536                         return NT_STATUS_END_OF_FILE;
537                 }
538                 *r->out.real_size = e->Length;
539                 return NT_STATUS_BUFFER_TOO_SMALL;
540         }
541
542         while (bytes_left > 0) {
543
544                 DATA_BLOB blob;
545                 enum ndr_err_code ndr_err;
546                 struct EVENTLOGRECORD *e;
547
548                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
549                                       record_number);
550                 if (!e) {
551                         break;
552                 }
553
554                 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, e,
555                               (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
556                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
557                         return ndr_map_error2ntstatus(ndr_err);
558                 }
559
560                 if (DEBUGLEVEL >= 10) {
561                         NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
562                 }
563
564                 if (blob.length > r->in.number_of_bytes) {
565                         *r->out.real_size = blob.length;
566                         return NT_STATUS_BUFFER_TOO_SMALL;
567                 }
568
569                 if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
570                         break;
571                 }
572
573                 bytes_left -= blob.length;
574
575                 if (info->flags & EVENTLOG_FORWARDS_READ) {
576                         record_number++;
577                 } else {
578                         record_number--;
579                 }
580
581                 /* update the eventlog record pointer */
582
583                 info->current_record = record_number;
584
585                 memcpy(&r->out.data[*(r->out.sent_size)],
586                        blob.data, blob.length);
587                 *(r->out.sent_size) += blob.length;
588
589                 num_records_read++;
590         }
591
592         if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
593                 return NT_STATUS_END_OF_FILE;
594         }
595
596         return NT_STATUS_OK;
597 }
598
599 /********************************************************************
600  _eventlog_GetOldestRecord
601  ********************************************************************/
602
603 NTSTATUS _eventlog_GetOldestRecord(struct pipes_struct *p,
604                                    struct eventlog_GetOldestRecord *r)
605 {
606         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
607
608         if (info == NULL) {
609                 return NT_STATUS_INVALID_HANDLE;
610         }
611
612         if ( !( get_oldest_entry_hook( info ) ) )
613                 return NT_STATUS_ACCESS_DENIED;
614
615         *r->out.oldest_entry = info->oldest_entry;
616
617         return NT_STATUS_OK;
618 }
619
620 /********************************************************************
621 _eventlog_GetNumRecords
622  ********************************************************************/
623
624 NTSTATUS _eventlog_GetNumRecords(struct pipes_struct *p,
625                                  struct eventlog_GetNumRecords *r)
626 {
627         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
628
629         if (info == NULL) {
630                 return NT_STATUS_INVALID_HANDLE;
631         }
632
633         if ( !( get_num_records_hook( info ) ) )
634                 return NT_STATUS_ACCESS_DENIED;
635
636         *r->out.number = info->num_records;
637
638         return NT_STATUS_OK;
639 }
640
641 NTSTATUS _eventlog_BackupEventLogW(struct pipes_struct *p, struct eventlog_BackupEventLogW *r)
642 {
643         p->rng_fault_state = True;
644         return NT_STATUS_NOT_IMPLEMENTED;
645 }
646
647 /********************************************************************
648 _eventlog_GetLogInformation
649  ********************************************************************/
650
651 NTSTATUS _eventlog_GetLogInformation(struct pipes_struct *p,
652                                      struct eventlog_GetLogInformation *r)
653 {
654         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
655         struct EVENTLOG_FULL_INFORMATION f;
656         enum ndr_err_code ndr_err;
657         DATA_BLOB blob;
658
659         if (!info) {
660                 return NT_STATUS_INVALID_HANDLE;
661         }
662
663         if (r->in.level != 0) {
664                 return NT_STATUS_INVALID_LEVEL;
665         }
666
667         *r->out.bytes_needed = 4;
668
669         if (r->in.buf_size < 4) {
670                 return NT_STATUS_BUFFER_TOO_SMALL;
671         }
672
673         /* FIXME: this should be retrieved from the handle */
674         f.full = false;
675
676         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &f,
677                       (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
678         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
679                 return ndr_map_error2ntstatus(ndr_err);
680         }
681
682         if (DEBUGLEVEL >= 10) {
683                 NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
684         }
685
686         memcpy(r->out.buffer, blob.data, 4);
687
688         return NT_STATUS_OK;
689 }
690
691 /********************************************************************
692 _eventlog_FlushEventLog
693  ********************************************************************/
694
695 NTSTATUS _eventlog_FlushEventLog(struct pipes_struct *p,
696                                  struct eventlog_FlushEventLog *r)
697 {
698         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
699         if (!info) {
700                 return NT_STATUS_INVALID_HANDLE;
701         }
702
703         return NT_STATUS_ACCESS_DENIED;
704 }
705
706 /********************************************************************
707  ********************************************************************/
708
709 static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
710                                        const struct eventlog_ReportEventW *r,
711                                        const char *logname,
712                                        struct EVENTLOGRECORD *e)
713 {
714         uint32_t i;
715         ZERO_STRUCTP(e);
716
717         e->TimeGenerated        = r->in.timestamp;
718         e->TimeWritten          = time(NULL);
719         e->EventID              = r->in.event_id;
720         e->EventType            = r->in.event_type;
721         e->NumStrings           = r->in.num_of_strings;
722         e->EventCategory        = r->in.event_category;
723         e->ReservedFlags        = r->in.flags;
724         e->DataLength           = r->in.data_size;
725         e->SourceName           = talloc_strdup(mem_ctx, logname);
726         NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
727         if (r->in.servername->string) {
728                 e->Computername = r->in.servername->string;
729         } else {
730                 e->Computername = talloc_strdup(mem_ctx, "");
731                 NT_STATUS_HAVE_NO_MEMORY(e->Computername);
732         }
733         if (r->in.user_sid) {
734                 e->UserSid      = *r->in.user_sid;
735         }
736         e->Strings              = talloc_array(mem_ctx, const char *, e->NumStrings);
737         NT_STATUS_HAVE_NO_MEMORY(e->Strings);
738
739         for (i=0; i < e->NumStrings; i++) {
740                 e->Strings[i] = talloc_strdup(e->Strings,
741                                               r->in.strings[i]->string);
742                 NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
743         }
744         e->Data                 = r->in.data;
745
746         return NT_STATUS_OK;
747 }
748
749 /********************************************************************
750 _eventlog_ReportEventW
751  ********************************************************************/
752
753 NTSTATUS _eventlog_ReportEventW(struct pipes_struct *p,
754                                 struct eventlog_ReportEventW *r)
755 {
756         NTSTATUS status;
757         struct EVENTLOGRECORD record;
758
759         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
760         if (!info) {
761                 return NT_STATUS_INVALID_HANDLE;
762         }
763
764         status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record);
765         if (!NT_STATUS_IS_OK(status)) {
766                 return status;
767         }
768
769         status = evlog_push_record(p->mem_ctx,
770                                    ELOG_TDB_CTX(info->etdb),
771                                    &record,
772                                    r->out.record_number);
773         if (!NT_STATUS_IS_OK(status)) {
774                 return status;
775         }
776
777         return NT_STATUS_OK;
778 }
779
780 /********************************************************************
781  ********************************************************************/
782
783 NTSTATUS _eventlog_DeregisterEventSource(struct pipes_struct *p,
784                                          struct eventlog_DeregisterEventSource *r)
785 {
786         p->rng_fault_state = True;
787         return NT_STATUS_NOT_IMPLEMENTED;
788 }
789
790 NTSTATUS _eventlog_ChangeNotify(struct pipes_struct *p,
791                                 struct eventlog_ChangeNotify *r)
792 {
793         p->rng_fault_state = True;
794         return NT_STATUS_NOT_IMPLEMENTED;
795 }
796
797 NTSTATUS _eventlog_RegisterEventSourceW(struct pipes_struct *p,
798                                         struct eventlog_RegisterEventSourceW *r)
799 {
800         p->rng_fault_state = True;
801         return NT_STATUS_NOT_IMPLEMENTED;
802 }
803
804 NTSTATUS _eventlog_OpenBackupEventLogW(struct pipes_struct *p,
805                                        struct eventlog_OpenBackupEventLogW *r)
806 {
807         p->rng_fault_state = True;
808         return NT_STATUS_NOT_IMPLEMENTED;
809 }
810
811 NTSTATUS _eventlog_ClearEventLogA(struct pipes_struct *p,
812                                   struct eventlog_ClearEventLogA *r)
813 {
814         p->rng_fault_state = True;
815         return NT_STATUS_NOT_IMPLEMENTED;
816 }
817
818 NTSTATUS _eventlog_BackupEventLogA(struct pipes_struct *p,
819                                    struct eventlog_BackupEventLogA *r)
820 {
821         p->rng_fault_state = True;
822         return NT_STATUS_NOT_IMPLEMENTED;
823 }
824
825 NTSTATUS _eventlog_OpenEventLogA(struct pipes_struct *p,
826                                  struct eventlog_OpenEventLogA *r)
827 {
828         p->rng_fault_state = True;
829         return NT_STATUS_NOT_IMPLEMENTED;
830 }
831
832 NTSTATUS _eventlog_RegisterEventSourceA(struct pipes_struct *p,
833                                         struct eventlog_RegisterEventSourceA *r)
834 {
835         p->rng_fault_state = True;
836         return NT_STATUS_NOT_IMPLEMENTED;
837 }
838
839 NTSTATUS _eventlog_OpenBackupEventLogA(struct pipes_struct *p,
840                                        struct eventlog_OpenBackupEventLogA *r)
841 {
842         p->rng_fault_state = True;
843         return NT_STATUS_NOT_IMPLEMENTED;
844 }
845
846 NTSTATUS _eventlog_ReadEventLogA(struct pipes_struct *p,
847                                  struct eventlog_ReadEventLogA *r)
848 {
849         p->rng_fault_state = True;
850         return NT_STATUS_NOT_IMPLEMENTED;
851 }
852
853 NTSTATUS _eventlog_ReportEventA(struct pipes_struct *p,
854                                 struct eventlog_ReportEventA *r)
855 {
856         p->rng_fault_state = True;
857         return NT_STATUS_NOT_IMPLEMENTED;
858 }
859
860 NTSTATUS _eventlog_RegisterClusterSvc(struct pipes_struct *p,
861                                       struct eventlog_RegisterClusterSvc *r)
862 {
863         p->rng_fault_state = True;
864         return NT_STATUS_NOT_IMPLEMENTED;
865 }
866
867 NTSTATUS _eventlog_DeregisterClusterSvc(struct pipes_struct *p,
868                                         struct eventlog_DeregisterClusterSvc *r)
869 {
870         p->rng_fault_state = True;
871         return NT_STATUS_NOT_IMPLEMENTED;
872 }
873
874 NTSTATUS _eventlog_WriteClusterEvents(struct pipes_struct *p,
875                                       struct eventlog_WriteClusterEvents *r)
876 {
877         p->rng_fault_state = True;
878         return NT_STATUS_NOT_IMPLEMENTED;
879 }
880
881 NTSTATUS _eventlog_ReportEventAndSourceW(struct pipes_struct *p,
882                                          struct eventlog_ReportEventAndSourceW *r)
883 {
884         p->rng_fault_state = True;
885         return NT_STATUS_NOT_IMPLEMENTED;
886 }