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