s3: piddir creation fix part 2.
[ira/wip.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 = NULL;
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                 data = talloc_array(mem_ctx, uint8_t, number_of_bytes);
88                 if (!data) {
89                         goto done;
90                 }
91         }
92
93         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
94         if (!NT_STATUS_IS_OK(status)) {
95                 return status;
96         }
97
98         do {
99
100                 enum ndr_err_code ndr_err;
101                 DATA_BLOB blob;
102                 struct EVENTLOGRECORD r;
103                 uint32_t size = 0;
104                 uint32_t pos = 0;
105
106                 status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
107                                                        &handle,
108                                                        flags,
109                                                        offset,
110                                                        number_of_bytes,
111                                                        data,
112                                                        &sent_size,
113                                                        &real_size,
114                                                        &result);
115                 if (!NT_STATUS_IS_OK(status)) {
116                         return status;
117                 }
118                 if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) &&
119                     real_size > 0 ) {
120                         number_of_bytes = real_size;
121                         data = talloc_array(mem_ctx, uint8_t, real_size);
122                         if (!data) {
123                                 goto done;
124                         }
125                         status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
126                                                                &handle,
127                                                                flags,
128                                                                offset,
129                                                                number_of_bytes,
130                                                                data,
131                                                                &sent_size,
132                                                                &real_size,
133                                                                &result);
134                         if (!NT_STATUS_IS_OK(status)) {
135                                 return status;
136                         }
137                 }
138
139                 if (!NT_STATUS_EQUAL(result, NT_STATUS_END_OF_FILE) &&
140                     !NT_STATUS_IS_OK(result)) {
141                         goto done;
142                 }
143
144                 number_of_bytes = 0;
145
146                 size = IVAL(data, pos);
147
148                 while (size > 0) {
149
150                         blob = data_blob_const(data + pos, size);
151                         /* dump_data(0, blob.data, blob.length); */
152                         ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &r,
153                                            (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
154                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
155                                 status = ndr_map_error2ntstatus(ndr_err);
156                                 goto done;
157                         }
158
159                         NDR_PRINT_DEBUG(EVENTLOGRECORD, &r);
160
161                         pos += size;
162
163                         if (pos + 4 > sent_size) {
164                                 break;
165                         }
166
167                         size = IVAL(data, pos);
168                 }
169
170                 offset++;
171
172         } while (NT_STATUS_IS_OK(result));
173
174  done:
175         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
176
177         return status;
178 }
179
180 static NTSTATUS cmd_eventlog_numrecords(struct rpc_pipe_client *cli,
181                                         TALLOC_CTX *mem_ctx,
182                                         int argc,
183                                         const char **argv)
184 {
185         NTSTATUS status, result;
186         struct policy_handle handle;
187         uint32_t number = 0;
188         struct dcerpc_binding_handle *b = cli->binding_handle;
189
190         if (argc != 2) {
191                 printf("Usage: %s logname\n", argv[0]);
192                 return NT_STATUS_OK;
193         }
194
195         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
196         if (!NT_STATUS_IS_OK(status)) {
197                 return status;
198         }
199
200         status = dcerpc_eventlog_GetNumRecords(b, mem_ctx,
201                                                &handle,
202                                                &number,
203                                                &result);
204         if (!NT_STATUS_IS_OK(status)) {
205                 goto done;
206         }
207         if (!NT_STATUS_IS_OK(result)) {
208                 status = result;
209                 goto done;
210         }
211
212         printf("number of records: %d\n", number);
213
214  done:
215         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
216
217         return status;
218 }
219
220 static NTSTATUS cmd_eventlog_oldestrecord(struct rpc_pipe_client *cli,
221                                           TALLOC_CTX *mem_ctx,
222                                           int argc,
223                                           const char **argv)
224 {
225         NTSTATUS status, result;
226         struct policy_handle handle;
227         uint32_t oldest_entry = 0;
228         struct dcerpc_binding_handle *b = cli->binding_handle;
229
230         if (argc != 2) {
231                 printf("Usage: %s logname\n", argv[0]);
232                 return NT_STATUS_OK;
233         }
234
235         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
236         if (!NT_STATUS_IS_OK(status)) {
237                 return status;
238         }
239
240         status = dcerpc_eventlog_GetOldestRecord(b, mem_ctx,
241                                                  &handle,
242                                                  &oldest_entry,
243                                                  &result);
244         if (!NT_STATUS_IS_OK(status)) {
245                 goto done;
246         }
247         if (!NT_STATUS_IS_OK(result)) {
248                 status = result;
249                 goto done;
250         }
251
252         printf("oldest entry: %d\n", oldest_entry);
253
254  done:
255         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
256
257         return status;
258 }
259
260 static NTSTATUS cmd_eventlog_reportevent(struct rpc_pipe_client *cli,
261                                          TALLOC_CTX *mem_ctx,
262                                          int argc,
263                                          const char **argv)
264 {
265         NTSTATUS status, result;
266         struct policy_handle handle;
267         struct dcerpc_binding_handle *b = cli->binding_handle;
268
269         uint16_t num_of_strings = 1;
270         uint32_t data_size = 0;
271         struct lsa_String servername;
272         struct lsa_String *strings;
273         uint8_t *data = NULL;
274         uint32_t record_number = 0;
275         time_t time_written = 0;
276
277         if (argc != 2) {
278                 printf("Usage: %s logname\n", argv[0]);
279                 return NT_STATUS_OK;
280         }
281
282         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
283         if (!NT_STATUS_IS_OK(status)) {
284                 return status;
285         }
286
287         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
288         if (!strings) {
289                 return NT_STATUS_NO_MEMORY;
290         }
291
292         init_lsa_String(&strings[0], "test event written by rpcclient\n");
293         init_lsa_String(&servername, NULL);
294
295         status = dcerpc_eventlog_ReportEventW(b, mem_ctx,
296                                               &handle,
297                                               time(NULL),
298                                               EVENTLOG_INFORMATION_TYPE,
299                                               0, /* event_category */
300                                               0, /* event_id */
301                                               num_of_strings,
302                                               data_size,
303                                               &servername,
304                                               NULL, /* user_sid */
305                                               &strings,
306                                               data,
307                                               0, /* flags */
308                                               &record_number,
309                                               &time_written,
310                                               &result);
311
312         if (!NT_STATUS_IS_OK(status)) {
313                 goto done;
314         }
315         if (!NT_STATUS_IS_OK(result)) {
316                 status = result;
317                 goto done;
318         }
319
320         printf("entry: %d written at %s\n", record_number,
321                 http_timestring(talloc_tos(), time_written));
322
323  done:
324         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
325
326         return status;
327 }
328
329 static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli,
330                                                TALLOC_CTX *mem_ctx,
331                                                int argc,
332                                                const char **argv)
333 {
334         NTSTATUS status, result;
335         struct policy_handle handle;
336         struct dcerpc_binding_handle *b = cli->binding_handle;
337
338         uint16_t num_of_strings = 1;
339         uint32_t data_size = 0;
340         struct lsa_String servername, sourcename;
341         struct lsa_String *strings;
342         uint8_t *data = NULL;
343         uint32_t record_number = 0;
344         time_t time_written = 0;
345
346         if (argc != 2) {
347                 printf("Usage: %s logname\n", argv[0]);
348                 return NT_STATUS_OK;
349         }
350
351         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
352         if (!NT_STATUS_IS_OK(status)) {
353                 return status;
354         }
355
356         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
357         if (!strings) {
358                 return NT_STATUS_NO_MEMORY;
359         }
360
361         init_lsa_String(&strings[0], "test event written by rpcclient\n");
362         init_lsa_String(&servername, NULL);
363         init_lsa_String(&sourcename, "rpcclient");
364
365         status = dcerpc_eventlog_ReportEventAndSourceW(b, mem_ctx,
366                                                        &handle,
367                                                        time(NULL),
368                                                        EVENTLOG_INFORMATION_TYPE,
369                                                        0, /* event_category */
370                                                        0, /* event_id */
371                                                        &sourcename,
372                                                        num_of_strings,
373                                                        data_size,
374                                                        &servername,
375                                                        NULL, /* user_sid */
376                                                        &strings,
377                                                        data,
378                                                        0, /* flags */
379                                                        &record_number,
380                                                        &time_written,
381                                                        &result);
382         if (!NT_STATUS_IS_OK(status)) {
383                 goto done;
384         }
385         if (!NT_STATUS_IS_OK(result)) {
386                 status = result;
387                 goto done;
388         }
389
390         printf("entry: %d written at %s\n", record_number,
391                 http_timestring(talloc_tos(), time_written));
392
393  done:
394         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
395
396         return status;
397 }
398
399 static NTSTATUS cmd_eventlog_registerevsource(struct rpc_pipe_client *cli,
400                                               TALLOC_CTX *mem_ctx,
401                                               int argc,
402                                               const char **argv)
403 {
404         NTSTATUS status, result;
405         struct policy_handle log_handle;
406         struct lsa_String module_name, reg_module_name;
407         struct eventlog_OpenUnknown0 unknown0;
408         struct dcerpc_binding_handle *b = cli->binding_handle;
409
410         unknown0.unknown0 = 0x005c;
411         unknown0.unknown1 = 0x0001;
412
413         if (argc != 2) {
414                 printf("Usage: %s logname\n", argv[0]);
415                 return NT_STATUS_OK;
416         }
417
418         init_lsa_String(&module_name, "rpcclient");
419         init_lsa_String(&reg_module_name, NULL);
420
421         status = dcerpc_eventlog_RegisterEventSourceW(b, mem_ctx,
422                                                       &unknown0,
423                                                       &module_name,
424                                                       &reg_module_name,
425                                                       1, /* major_version */
426                                                       1, /* minor_version */
427                                                       &log_handle,
428                                                       &result);
429         if (!NT_STATUS_IS_OK(status)) {
430                 goto done;
431         }
432         if (!NT_STATUS_IS_OK(result)) {
433                 status = result;
434                 goto done;
435         }
436
437  done:
438         dcerpc_eventlog_DeregisterEventSource(b, mem_ctx, &log_handle, &result);
439
440         return status;
441 }
442
443 static NTSTATUS cmd_eventlog_backuplog(struct rpc_pipe_client *cli,
444                                        TALLOC_CTX *mem_ctx,
445                                        int argc,
446                                        const char **argv)
447 {
448         NTSTATUS status, result;
449         struct policy_handle handle;
450         struct lsa_String backup_filename;
451         const char *tmp;
452         struct dcerpc_binding_handle *b = cli->binding_handle;
453
454         if (argc != 3) {
455                 printf("Usage: %s logname backupname\n", argv[0]);
456                 return NT_STATUS_OK;
457         }
458
459         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
460         if (!NT_STATUS_IS_OK(status)) {
461                 return status;
462         }
463
464         tmp = talloc_asprintf(mem_ctx, "\\??\\%s", argv[2]);
465         if (!tmp) {
466                 status = NT_STATUS_NO_MEMORY;
467                 goto done;
468         }
469
470         init_lsa_String(&backup_filename, tmp);
471
472         status = dcerpc_eventlog_BackupEventLogW(b, mem_ctx,
473                                                  &handle,
474                                                  &backup_filename,
475                                                  &result);
476         if (!NT_STATUS_IS_OK(status)) {
477                 goto done;
478         }
479         if (!NT_STATUS_IS_OK(result)) {
480                 status = result;
481                 goto done;
482         }
483
484  done:
485         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
486
487         return status;
488 }
489
490 static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli,
491                                      TALLOC_CTX *mem_ctx,
492                                      int argc,
493                                      const char **argv)
494 {
495         NTSTATUS status, result;
496         struct policy_handle handle;
497         uint8_t *buffer = NULL;
498         uint32_t buf_size = 0;
499         uint32_t bytes_needed = 0;
500         struct dcerpc_binding_handle *b = cli->binding_handle;
501
502         if (argc != 2) {
503                 printf("Usage: %s logname\n", argv[0]);
504                 return NT_STATUS_OK;
505         }
506
507         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
508         if (!NT_STATUS_IS_OK(status)) {
509                 return status;
510         }
511
512         status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
513                                                    &handle,
514                                                    0, /* level */
515                                                    buffer,
516                                                    buf_size,
517                                                    &bytes_needed,
518                                                    &result);
519         if (!NT_STATUS_IS_OK(status)) {
520                 goto done;
521         }
522         if (!NT_STATUS_IS_OK(result) &&
523             !NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) {
524                 goto done;
525         }
526
527         buf_size = bytes_needed;
528         buffer = talloc_array(mem_ctx, uint8_t, bytes_needed);
529         if (!buffer) {
530                 status = NT_STATUS_NO_MEMORY;
531                 goto done;
532         }
533
534         status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
535                                                    &handle,
536                                                    0, /* level */
537                                                    buffer,
538                                                    buf_size,
539                                                    &bytes_needed,
540                                                    &result);
541         if (!NT_STATUS_IS_OK(status)) {
542                 goto done;
543         }
544         if (!NT_STATUS_IS_OK(result)) {
545                 status = result;
546                 goto done;
547         }
548
549  done:
550         dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
551
552         return status;
553 }
554
555
556 struct cmd_set eventlog_commands[] = {
557         { "EVENTLOG" },
558         { "eventlog_readlog",           RPC_RTYPE_NTSTATUS,     cmd_eventlog_readlog,           NULL,   &ndr_table_eventlog,    NULL,   "Read Eventlog", "" },
559         { "eventlog_numrecord",         RPC_RTYPE_NTSTATUS,     cmd_eventlog_numrecords,        NULL,   &ndr_table_eventlog,    NULL,   "Get number of records", "" },
560         { "eventlog_oldestrecord",      RPC_RTYPE_NTSTATUS,     cmd_eventlog_oldestrecord,      NULL,   &ndr_table_eventlog,    NULL,   "Get oldest record", "" },
561         { "eventlog_reportevent",       RPC_RTYPE_NTSTATUS,     cmd_eventlog_reportevent,       NULL,   &ndr_table_eventlog,    NULL,   "Report event", "" },
562         { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS,     cmd_eventlog_reporteventsource, NULL,   &ndr_table_eventlog,    NULL,   "Report event and source", "" },
563         { "eventlog_registerevsource",  RPC_RTYPE_NTSTATUS,     cmd_eventlog_registerevsource,  NULL,   &ndr_table_eventlog,    NULL,   "Register event source", "" },
564         { "eventlog_backuplog",         RPC_RTYPE_NTSTATUS,     cmd_eventlog_backuplog,         NULL,   &ndr_table_eventlog,    NULL,   "Backup Eventlog File", "" },
565         { "eventlog_loginfo",           RPC_RTYPE_NTSTATUS,     cmd_eventlog_loginfo,           NULL,   &ndr_table_eventlog,    NULL,   "Get Eventlog Information", "" },
566         { NULL }
567 };