s3:rpcclient: Use C99 initializer for cmd_set in cmd_eventlog
[vlendec/samba-autobuild/.git] / source3 / rpcclient / cmd_eventlog.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) G√ľnther Deschner 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "rpcclient.h"
23 #include "../librpc/gen_ndr/ndr_eventlog.h"
24 #include "../librpc/gen_ndr/ndr_eventlog_c.h"
25 #include "rpc_client/init_lsa.h"
26
27 static NTSTATUS get_eventlog_handle(struct rpc_pipe_client *cli,
28                                     TALLOC_CTX *mem_ctx,
29                                     const char *log,
30                                     struct policy_handle *handle)
31 {
32         NTSTATUS status, result;
33         struct eventlog_OpenUnknown0 unknown0;
34         struct lsa_String logname, servername;
35         struct dcerpc_binding_handle *b = cli->binding_handle;
36
37         unknown0.unknown0 = 0x005c;
38         unknown0.unknown1 = 0x0001;
39
40         init_lsa_String(&logname, log);
41         init_lsa_String(&servername, NULL);
42
43         status = dcerpc_eventlog_OpenEventLogW(b, mem_ctx,
44                                                &unknown0,
45                                                &logname,
46                                                &servername,
47                                                0x00000001, /* major */
48                                                0x00000001, /* minor */
49                                                handle,
50                                                &result);
51         if (!NT_STATUS_IS_OK(status)) {
52                 return status;
53         }
54
55         return result;
56 }
57
58 static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
59                                      TALLOC_CTX *mem_ctx,
60                                      int argc,
61                                      const char **argv)
62 {
63         NTSTATUS status = NT_STATUS_OK;
64         NTSTATUS result = NT_STATUS_OK;
65         struct policy_handle handle;
66         struct dcerpc_binding_handle *b = cli->binding_handle;
67
68         uint32_t flags = EVENTLOG_BACKWARDS_READ |
69                          EVENTLOG_SEQUENTIAL_READ;
70         uint32_t offset = 0;
71         uint32_t number_of_bytes = 0;
72         uint8_t *data;
73         uint32_t sent_size = 0;
74         uint32_t real_size = 0;
75
76         if (argc < 2 || argc > 4) {
77                 printf("Usage: %s logname [offset] [number_of_bytes]\n", argv[0]);
78                 return NT_STATUS_OK;
79         }
80
81         if (argc >= 3) {
82                 offset = atoi(argv[2]);
83         }
84
85         if (argc >= 4) {
86                 number_of_bytes = atoi(argv[3]);
87         }
88
89         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
90         if (!NT_STATUS_IS_OK(status)) {
91                 return status;
92         }
93
94         data = talloc_array(mem_ctx, uint8_t, number_of_bytes);
95         if (data == NULL) {
96                 goto done;
97         }
98
99         do {
100
101                 enum ndr_err_code ndr_err;
102                 DATA_BLOB blob;
103                 struct EVENTLOGRECORD r;
104                 uint32_t size = 0;
105                 uint32_t pos = 0;
106
107                 status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
108                                                        &handle,
109                                                        flags,
110                                                        offset,
111                                                        number_of_bytes,
112                                                        data,
113                                                        &sent_size,
114                                                        &real_size,
115                                                        &result);
116                 if (!NT_STATUS_IS_OK(status)) {
117                         return status;
118                 }
119                 if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) &&
120                     real_size > 0 ) {
121                         number_of_bytes = real_size;
122                         data = talloc_realloc(mem_ctx, data, uint8_t, real_size);
123                         if (data == NULL) {
124                                 goto done;
125                         }
126                         status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
127                                                                &handle,
128                                                                flags,
129                                                                offset,
130                                                                number_of_bytes,
131                                                                data,
132                                                                &sent_size,
133                                                                &real_size,
134                                                                &result);
135                         if (!NT_STATUS_IS_OK(status)) {
136                                 return status;
137                         }
138                 }
139
140                 if (!NT_STATUS_EQUAL(result, NT_STATUS_END_OF_FILE) &&
141                     !NT_STATUS_IS_OK(result)) {
142                         goto done;
143                 }
144
145                 number_of_bytes = 0;
146
147                 size = IVAL(data, pos);
148
149                 while (size > 0) {
150
151                         blob = data_blob_const(data + pos, size);
152                         /* dump_data(0, blob.data, blob.length); */
153                         ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &r,
154                                            (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
155                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
156                                 status = ndr_map_error2ntstatus(ndr_err);
157                                 goto done;
158                         }
159
160                         NDR_PRINT_DEBUG(EVENTLOGRECORD, &r);
161
162                         pos += size;
163
164                         if (pos + 4 > sent_size) {
165                                 break;
166                         }
167
168                         size = IVAL(data, pos);
169                 }
170
171                 offset++;
172
173         } while (NT_STATUS_IS_OK(result));
174
175  done:
176         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
177
178         return status;
179 }
180
181 static NTSTATUS cmd_eventlog_numrecords(struct rpc_pipe_client *cli,
182                                         TALLOC_CTX *mem_ctx,
183                                         int argc,
184                                         const char **argv)
185 {
186         NTSTATUS status, result;
187         struct policy_handle handle;
188         uint32_t number = 0;
189         struct dcerpc_binding_handle *b = cli->binding_handle;
190
191         if (argc != 2) {
192                 printf("Usage: %s logname\n", argv[0]);
193                 return NT_STATUS_OK;
194         }
195
196         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
197         if (!NT_STATUS_IS_OK(status)) {
198                 return status;
199         }
200
201         status = dcerpc_eventlog_GetNumRecords(b, mem_ctx,
202                                                &handle,
203                                                &number,
204                                                &result);
205         if (!NT_STATUS_IS_OK(status)) {
206                 goto done;
207         }
208         if (!NT_STATUS_IS_OK(result)) {
209                 status = result;
210                 goto done;
211         }
212
213         printf("number of records: %d\n", number);
214
215  done:
216         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
217
218         return status;
219 }
220
221 static NTSTATUS cmd_eventlog_oldestrecord(struct rpc_pipe_client *cli,
222                                           TALLOC_CTX *mem_ctx,
223                                           int argc,
224                                           const char **argv)
225 {
226         NTSTATUS status, result;
227         struct policy_handle handle;
228         uint32_t oldest_entry = 0;
229         struct dcerpc_binding_handle *b = cli->binding_handle;
230
231         if (argc != 2) {
232                 printf("Usage: %s logname\n", argv[0]);
233                 return NT_STATUS_OK;
234         }
235
236         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
237         if (!NT_STATUS_IS_OK(status)) {
238                 return status;
239         }
240
241         status = dcerpc_eventlog_GetOldestRecord(b, mem_ctx,
242                                                  &handle,
243                                                  &oldest_entry,
244                                                  &result);
245         if (!NT_STATUS_IS_OK(status)) {
246                 goto done;
247         }
248         if (!NT_STATUS_IS_OK(result)) {
249                 status = result;
250                 goto done;
251         }
252
253         printf("oldest entry: %d\n", oldest_entry);
254
255  done:
256         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
257
258         return status;
259 }
260
261 static NTSTATUS cmd_eventlog_reportevent(struct rpc_pipe_client *cli,
262                                          TALLOC_CTX *mem_ctx,
263                                          int argc,
264                                          const char **argv)
265 {
266         NTSTATUS status, result;
267         struct policy_handle handle;
268         struct dcerpc_binding_handle *b = cli->binding_handle;
269
270         uint16_t num_of_strings = 1;
271         uint32_t data_size = 0;
272         struct lsa_String servername;
273         struct lsa_String *strings;
274         uint8_t *data = NULL;
275         uint32_t record_number = 0;
276         time_t time_written = 0;
277
278         if (argc != 2) {
279                 printf("Usage: %s logname\n", argv[0]);
280                 return NT_STATUS_OK;
281         }
282
283         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
284         if (!NT_STATUS_IS_OK(status)) {
285                 return status;
286         }
287
288         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
289         if (!strings) {
290                 return NT_STATUS_NO_MEMORY;
291         }
292
293         init_lsa_String(&strings[0], "test event written by rpcclient\n");
294         init_lsa_String(&servername, NULL);
295
296         status = dcerpc_eventlog_ReportEventW(b, mem_ctx,
297                                               &handle,
298                                               time(NULL),
299                                               EVENTLOG_INFORMATION_TYPE,
300                                               0, /* event_category */
301                                               0, /* event_id */
302                                               num_of_strings,
303                                               data_size,
304                                               &servername,
305                                               NULL, /* user_sid */
306                                               &strings,
307                                               data,
308                                               0, /* flags */
309                                               &record_number,
310                                               &time_written,
311                                               &result);
312
313         if (!NT_STATUS_IS_OK(status)) {
314                 goto done;
315         }
316         if (!NT_STATUS_IS_OK(result)) {
317                 status = result;
318                 goto done;
319         }
320
321         printf("entry: %d written at %s\n", record_number,
322                 http_timestring(talloc_tos(), time_written));
323
324  done:
325         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
326
327         return status;
328 }
329
330 static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli,
331                                                TALLOC_CTX *mem_ctx,
332                                                int argc,
333                                                const char **argv)
334 {
335         NTSTATUS status, result;
336         struct policy_handle handle;
337         struct dcerpc_binding_handle *b = cli->binding_handle;
338
339         uint16_t num_of_strings = 1;
340         uint32_t data_size = 0;
341         struct lsa_String servername, sourcename;
342         struct lsa_String *strings;
343         uint8_t *data = NULL;
344         uint32_t record_number = 0;
345         time_t time_written = 0;
346
347         if (argc != 2) {
348                 printf("Usage: %s logname\n", argv[0]);
349                 return NT_STATUS_OK;
350         }
351
352         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
353         if (!NT_STATUS_IS_OK(status)) {
354                 return status;
355         }
356
357         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
358         if (!strings) {
359                 return NT_STATUS_NO_MEMORY;
360         }
361
362         init_lsa_String(&strings[0], "test event written by rpcclient\n");
363         init_lsa_String(&servername, NULL);
364         init_lsa_String(&sourcename, "rpcclient");
365
366         status = dcerpc_eventlog_ReportEventAndSourceW(b, mem_ctx,
367                                                        &handle,
368                                                        time(NULL),
369                                                        EVENTLOG_INFORMATION_TYPE,
370                                                        0, /* event_category */
371                                                        0, /* event_id */
372                                                        &sourcename,
373                                                        num_of_strings,
374                                                        data_size,
375                                                        &servername,
376                                                        NULL, /* user_sid */
377                                                        &strings,
378                                                        data,
379                                                        0, /* flags */
380                                                        &record_number,
381                                                        &time_written,
382                                                        &result);
383         if (!NT_STATUS_IS_OK(status)) {
384                 goto done;
385         }
386         if (!NT_STATUS_IS_OK(result)) {
387                 status = result;
388                 goto done;
389         }
390
391         printf("entry: %d written at %s\n", record_number,
392                 http_timestring(talloc_tos(), time_written));
393
394  done:
395         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
396
397         return status;
398 }
399
400 static NTSTATUS cmd_eventlog_registerevsource(struct rpc_pipe_client *cli,
401                                               TALLOC_CTX *mem_ctx,
402                                               int argc,
403                                               const char **argv)
404 {
405         NTSTATUS status, result;
406         struct policy_handle log_handle;
407         struct lsa_String module_name, reg_module_name;
408         struct eventlog_OpenUnknown0 unknown0;
409         struct dcerpc_binding_handle *b = cli->binding_handle;
410
411         unknown0.unknown0 = 0x005c;
412         unknown0.unknown1 = 0x0001;
413
414         if (argc != 2) {
415                 printf("Usage: %s logname\n", argv[0]);
416                 return NT_STATUS_OK;
417         }
418
419         init_lsa_String(&module_name, "rpcclient");
420         init_lsa_String(&reg_module_name, NULL);
421
422         status = dcerpc_eventlog_RegisterEventSourceW(b, mem_ctx,
423                                                       &unknown0,
424                                                       &module_name,
425                                                       &reg_module_name,
426                                                       1, /* major_version */
427                                                       1, /* minor_version */
428                                                       &log_handle,
429                                                       &result);
430         if (!NT_STATUS_IS_OK(status)) {
431                 goto done;
432         }
433         if (!NT_STATUS_IS_OK(result)) {
434                 status = result;
435                 goto done;
436         }
437
438  done:
439         dcerpc_eventlog_DeregisterEventSource(b, mem_ctx, &log_handle, &result);
440
441         return status;
442 }
443
444 static NTSTATUS cmd_eventlog_backuplog(struct rpc_pipe_client *cli,
445                                        TALLOC_CTX *mem_ctx,
446                                        int argc,
447                                        const char **argv)
448 {
449         NTSTATUS status, result;
450         struct policy_handle handle;
451         struct lsa_String backup_filename;
452         const char *tmp;
453         struct dcerpc_binding_handle *b = cli->binding_handle;
454
455         if (argc != 3) {
456                 printf("Usage: %s logname backupname\n", argv[0]);
457                 return NT_STATUS_OK;
458         }
459
460         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
461         if (!NT_STATUS_IS_OK(status)) {
462                 return status;
463         }
464
465         tmp = talloc_asprintf(mem_ctx, "\\??\\%s", argv[2]);
466         if (!tmp) {
467                 status = NT_STATUS_NO_MEMORY;
468                 goto done;
469         }
470
471         init_lsa_String(&backup_filename, tmp);
472
473         status = dcerpc_eventlog_BackupEventLogW(b, mem_ctx,
474                                                  &handle,
475                                                  &backup_filename,
476                                                  &result);
477         if (!NT_STATUS_IS_OK(status)) {
478                 goto done;
479         }
480         if (!NT_STATUS_IS_OK(result)) {
481                 status = result;
482                 goto done;
483         }
484
485  done:
486         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
487
488         return status;
489 }
490
491 static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli,
492                                      TALLOC_CTX *mem_ctx,
493                                      int argc,
494                                      const char **argv)
495 {
496         NTSTATUS status, result;
497         struct policy_handle handle;
498         uint8_t *buffer = NULL;
499         uint32_t buf_size = 0;
500         uint32_t bytes_needed = 0;
501         struct dcerpc_binding_handle *b = cli->binding_handle;
502
503         if (argc != 2) {
504                 printf("Usage: %s logname\n", argv[0]);
505                 return NT_STATUS_OK;
506         }
507
508         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
509         if (!NT_STATUS_IS_OK(status)) {
510                 return status;
511         }
512
513         buffer = talloc_array(mem_ctx, uint8_t, bytes_needed);
514         if (buffer == NULL) {
515                 status = NT_STATUS_NO_MEMORY;
516                 goto done;
517         }
518
519         status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
520                                                    &handle,
521                                                    0, /* level */
522                                                    buffer,
523                                                    buf_size,
524                                                    &bytes_needed,
525                                                    &result);
526         if (!NT_STATUS_IS_OK(status)) {
527                 goto done;
528         }
529         if (!NT_STATUS_IS_OK(result) &&
530             !NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) {
531                 goto done;
532         }
533
534         buf_size = bytes_needed;
535         buffer = talloc_realloc(mem_ctx, buffer, uint8_t, bytes_needed);
536         if (buffer == NULL) {
537                 status = NT_STATUS_NO_MEMORY;
538                 goto done;
539         }
540
541         status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
542                                                    &handle,
543                                                    0, /* level */
544                                                    buffer,
545                                                    buf_size,
546                                                    &bytes_needed,
547                                                    &result);
548         if (!NT_STATUS_IS_OK(status)) {
549                 goto done;
550         }
551         if (!NT_STATUS_IS_OK(result)) {
552                 status = result;
553                 goto done;
554         }
555
556  done:
557         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
558
559         return status;
560 }
561
562
563 struct cmd_set eventlog_commands[] = {
564         {
565                 .name = "EVENTLOG",
566         },
567         {
568                 .name               = "eventlog_readlog",
569                 .returntype         = RPC_RTYPE_NTSTATUS,
570                 .ntfn               = cmd_eventlog_readlog,
571                 .wfn                = NULL,
572                 .table              = &ndr_table_eventlog,
573                 .rpc_pipe           = NULL,
574                 .description        = "Read Eventlog",
575                 .usage              = "",
576         },
577         {
578                 .name               = "eventlog_numrecord",
579                 .returntype         = RPC_RTYPE_NTSTATUS,
580                 .ntfn               = cmd_eventlog_numrecords,
581                 .wfn                = NULL,
582                 .table              = &ndr_table_eventlog,
583                 .rpc_pipe           = NULL,
584                 .description        = "Get number of records",
585                 .usage              = "",
586         },
587         {
588                 .name               = "eventlog_oldestrecord",
589                 .returntype         = RPC_RTYPE_NTSTATUS,
590                 .ntfn               = cmd_eventlog_oldestrecord,
591                 .wfn                = NULL,
592                 .table              = &ndr_table_eventlog,
593                 .rpc_pipe           = NULL,
594                 .description        = "Get oldest record",
595                 .usage              = "",
596         },
597         {
598                 .name               = "eventlog_reportevent",
599                 .returntype         = RPC_RTYPE_NTSTATUS,
600                 .ntfn               = cmd_eventlog_reportevent,
601                 .wfn                = NULL,
602                 .table              = &ndr_table_eventlog,
603                 .rpc_pipe           = NULL,
604                 .description        = "Report event",
605                 .usage              = "",
606         },
607         {
608                 .name               = "eventlog_reporteventsource",
609                 .returntype         = RPC_RTYPE_NTSTATUS,
610                 .ntfn               = cmd_eventlog_reporteventsource,
611                 .wfn                = NULL,
612                 .table              = &ndr_table_eventlog,
613                 .rpc_pipe           = NULL,
614                 .description        = "Report event and source",
615                 .usage              = "",
616         },
617         {
618                 .name               = "eventlog_registerevsource",
619                 .returntype         = RPC_RTYPE_NTSTATUS,
620                 .ntfn               = cmd_eventlog_registerevsource,
621                 .wfn                = NULL,
622                 .table              = &ndr_table_eventlog,
623                 .rpc_pipe           = NULL,
624                 .description        = "Register event source",
625                 .usage              = "",
626         },
627         {
628                 .name               = "eventlog_backuplog",
629                 .returntype         = RPC_RTYPE_NTSTATUS,
630                 .ntfn               = cmd_eventlog_backuplog,
631                 .wfn                = NULL,
632                 .table              = &ndr_table_eventlog,
633                 .rpc_pipe           = NULL,
634                 .description        = "Backup Eventlog File",
635                 .usage              = "",
636         },
637         {
638                 .name               = "eventlog_loginfo",
639                 .returntype         = RPC_RTYPE_NTSTATUS,
640                 .ntfn               = cmd_eventlog_loginfo,
641                 .wfn                = NULL,
642                 .table              = &ndr_table_eventlog,
643                 .rpc_pipe           = NULL,
644                 .description        = "Get Eventlog Information",
645                 .usage              = "",
646         },
647         {
648                 .name = NULL,
649         },
650 };