Line data Source code
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 0 : 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 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
36 :
37 0 : unknown0.unknown0 = 0x005c;
38 0 : unknown0.unknown1 = 0x0001;
39 :
40 0 : init_lsa_String(&logname, log);
41 0 : init_lsa_String(&servername, NULL);
42 :
43 0 : status = dcerpc_eventlog_OpenEventLogW(b, mem_ctx,
44 : &unknown0,
45 : &logname,
46 : &servername,
47 : 0x00000001, /* major */
48 : 0x00000001, /* minor */
49 : handle,
50 : &result);
51 0 : if (!NT_STATUS_IS_OK(status)) {
52 0 : return status;
53 : }
54 :
55 0 : return result;
56 : }
57 :
58 0 : static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
59 : TALLOC_CTX *mem_ctx,
60 : int argc,
61 : const char **argv)
62 : {
63 0 : NTSTATUS status = NT_STATUS_OK;
64 0 : NTSTATUS result = NT_STATUS_OK;
65 : struct policy_handle handle;
66 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
67 :
68 0 : uint32_t flags = EVENTLOG_BACKWARDS_READ |
69 : EVENTLOG_SEQUENTIAL_READ;
70 0 : uint32_t offset = 0;
71 0 : uint32_t number_of_bytes = 0;
72 : uint8_t *data;
73 0 : uint32_t sent_size = 0;
74 0 : uint32_t real_size = 0;
75 :
76 0 : if (argc < 2 || argc > 4) {
77 0 : printf("Usage: %s logname [offset] [number_of_bytes]\n", argv[0]);
78 0 : return NT_STATUS_OK;
79 : }
80 :
81 0 : if (argc >= 3) {
82 0 : offset = atoi(argv[2]);
83 : }
84 :
85 0 : if (argc >= 4) {
86 0 : number_of_bytes = atoi(argv[3]);
87 : }
88 :
89 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
90 0 : if (!NT_STATUS_IS_OK(status)) {
91 0 : return status;
92 : }
93 :
94 0 : data = talloc_array(mem_ctx, uint8_t, number_of_bytes);
95 0 : if (data == NULL) {
96 0 : goto done;
97 : }
98 :
99 : do {
100 :
101 : enum ndr_err_code ndr_err;
102 : DATA_BLOB blob;
103 : struct EVENTLOGRECORD r;
104 0 : uint32_t size = 0;
105 0 : uint32_t pos = 0;
106 :
107 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
117 0 : return status;
118 : }
119 0 : if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) &&
120 0 : real_size > 0 ) {
121 0 : number_of_bytes = real_size;
122 0 : data = talloc_realloc(mem_ctx, data, uint8_t, real_size);
123 0 : if (data == NULL) {
124 0 : goto done;
125 : }
126 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
136 0 : return status;
137 : }
138 : }
139 :
140 0 : if (!NT_STATUS_EQUAL(result, NT_STATUS_END_OF_FILE) &&
141 0 : !NT_STATUS_IS_OK(result)) {
142 0 : goto done;
143 : }
144 :
145 0 : number_of_bytes = 0;
146 :
147 0 : size = IVAL(data, pos);
148 :
149 0 : while (size > 0) {
150 :
151 0 : blob = data_blob_const(data + pos, size);
152 : /* dump_data(0, blob.data, blob.length); */
153 0 : ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &r,
154 : (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
155 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
156 0 : status = ndr_map_error2ntstatus(ndr_err);
157 0 : goto done;
158 : }
159 :
160 0 : NDR_PRINT_DEBUG(EVENTLOGRECORD, &r);
161 :
162 0 : pos += size;
163 :
164 0 : if (pos + 4 > sent_size) {
165 0 : break;
166 : }
167 :
168 0 : size = IVAL(data, pos);
169 : }
170 :
171 0 : offset++;
172 :
173 0 : } while (NT_STATUS_IS_OK(result));
174 :
175 0 : done:
176 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
177 :
178 0 : return status;
179 : }
180 :
181 0 : 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 0 : uint32_t number = 0;
189 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
190 :
191 0 : if (argc != 2) {
192 0 : printf("Usage: %s logname\n", argv[0]);
193 0 : return NT_STATUS_OK;
194 : }
195 :
196 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
197 0 : if (!NT_STATUS_IS_OK(status)) {
198 0 : return status;
199 : }
200 :
201 0 : status = dcerpc_eventlog_GetNumRecords(b, mem_ctx,
202 : &handle,
203 : &number,
204 : &result);
205 0 : if (!NT_STATUS_IS_OK(status)) {
206 0 : goto done;
207 : }
208 0 : if (!NT_STATUS_IS_OK(result)) {
209 0 : status = result;
210 0 : goto done;
211 : }
212 :
213 0 : printf("number of records: %d\n", number);
214 :
215 0 : done:
216 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
217 :
218 0 : return status;
219 : }
220 :
221 0 : 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 0 : uint32_t oldest_entry = 0;
229 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
230 :
231 0 : if (argc != 2) {
232 0 : printf("Usage: %s logname\n", argv[0]);
233 0 : return NT_STATUS_OK;
234 : }
235 :
236 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
237 0 : if (!NT_STATUS_IS_OK(status)) {
238 0 : return status;
239 : }
240 :
241 0 : status = dcerpc_eventlog_GetOldestRecord(b, mem_ctx,
242 : &handle,
243 : &oldest_entry,
244 : &result);
245 0 : if (!NT_STATUS_IS_OK(status)) {
246 0 : goto done;
247 : }
248 0 : if (!NT_STATUS_IS_OK(result)) {
249 0 : status = result;
250 0 : goto done;
251 : }
252 :
253 0 : printf("oldest entry: %d\n", oldest_entry);
254 :
255 0 : done:
256 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
257 :
258 0 : return status;
259 : }
260 :
261 0 : 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 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
269 :
270 0 : uint16_t num_of_strings = 1;
271 0 : uint32_t data_size = 0;
272 : struct lsa_String servername;
273 : struct lsa_String *strings;
274 0 : uint8_t *data = NULL;
275 0 : uint32_t record_number = 0;
276 0 : time_t time_written = 0;
277 :
278 0 : if (argc != 2) {
279 0 : printf("Usage: %s logname\n", argv[0]);
280 0 : return NT_STATUS_OK;
281 : }
282 :
283 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
284 0 : if (!NT_STATUS_IS_OK(status)) {
285 0 : return status;
286 : }
287 :
288 0 : strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
289 0 : if (!strings) {
290 0 : return NT_STATUS_NO_MEMORY;
291 : }
292 :
293 0 : init_lsa_String(&strings[0], "test event written by rpcclient\n");
294 0 : init_lsa_String(&servername, NULL);
295 :
296 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
314 0 : goto done;
315 : }
316 0 : if (!NT_STATUS_IS_OK(result)) {
317 0 : status = result;
318 0 : goto done;
319 : }
320 :
321 0 : printf("entry: %d written at %s\n", record_number,
322 : http_timestring(talloc_tos(), time_written));
323 :
324 0 : done:
325 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
326 :
327 0 : return status;
328 : }
329 :
330 0 : 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 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
338 :
339 0 : uint16_t num_of_strings = 1;
340 0 : uint32_t data_size = 0;
341 : struct lsa_String servername, sourcename;
342 : struct lsa_String *strings;
343 0 : uint8_t *data = NULL;
344 0 : uint32_t record_number = 0;
345 0 : time_t time_written = 0;
346 :
347 0 : if (argc != 2) {
348 0 : printf("Usage: %s logname\n", argv[0]);
349 0 : return NT_STATUS_OK;
350 : }
351 :
352 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
353 0 : if (!NT_STATUS_IS_OK(status)) {
354 0 : return status;
355 : }
356 :
357 0 : strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
358 0 : if (!strings) {
359 0 : return NT_STATUS_NO_MEMORY;
360 : }
361 :
362 0 : init_lsa_String(&strings[0], "test event written by rpcclient\n");
363 0 : init_lsa_String(&servername, NULL);
364 0 : init_lsa_String(&sourcename, "rpcclient");
365 :
366 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
384 0 : goto done;
385 : }
386 0 : if (!NT_STATUS_IS_OK(result)) {
387 0 : status = result;
388 0 : goto done;
389 : }
390 :
391 0 : printf("entry: %d written at %s\n", record_number,
392 : http_timestring(talloc_tos(), time_written));
393 :
394 0 : done:
395 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
396 :
397 0 : return status;
398 : }
399 :
400 0 : 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 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
410 :
411 0 : unknown0.unknown0 = 0x005c;
412 0 : unknown0.unknown1 = 0x0001;
413 :
414 0 : if (argc != 2) {
415 0 : printf("Usage: %s logname\n", argv[0]);
416 0 : return NT_STATUS_OK;
417 : }
418 :
419 0 : init_lsa_String(&module_name, "rpcclient");
420 0 : init_lsa_String(®_module_name, NULL);
421 :
422 0 : status = dcerpc_eventlog_RegisterEventSourceW(b, mem_ctx,
423 : &unknown0,
424 : &module_name,
425 : ®_module_name,
426 : 1, /* major_version */
427 : 1, /* minor_version */
428 : &log_handle,
429 : &result);
430 0 : if (!NT_STATUS_IS_OK(status)) {
431 0 : goto done;
432 : }
433 0 : if (!NT_STATUS_IS_OK(result)) {
434 0 : status = result;
435 0 : goto done;
436 : }
437 :
438 0 : done:
439 0 : dcerpc_eventlog_DeregisterEventSource(b, mem_ctx, &log_handle, &result);
440 :
441 0 : return status;
442 : }
443 :
444 0 : 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 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
454 :
455 0 : if (argc != 3) {
456 0 : printf("Usage: %s logname backupname\n", argv[0]);
457 0 : return NT_STATUS_OK;
458 : }
459 :
460 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
461 0 : if (!NT_STATUS_IS_OK(status)) {
462 0 : return status;
463 : }
464 :
465 0 : tmp = talloc_asprintf(mem_ctx, "\\??\\%s", argv[2]);
466 0 : if (!tmp) {
467 0 : status = NT_STATUS_NO_MEMORY;
468 0 : goto done;
469 : }
470 :
471 0 : init_lsa_String(&backup_filename, tmp);
472 :
473 0 : status = dcerpc_eventlog_BackupEventLogW(b, mem_ctx,
474 : &handle,
475 : &backup_filename,
476 : &result);
477 0 : if (!NT_STATUS_IS_OK(status)) {
478 0 : goto done;
479 : }
480 0 : if (!NT_STATUS_IS_OK(result)) {
481 0 : status = result;
482 0 : goto done;
483 : }
484 :
485 0 : done:
486 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
487 :
488 0 : return status;
489 : }
490 :
491 0 : 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 0 : uint8_t *buffer = NULL;
499 0 : uint32_t buf_size = 0;
500 0 : uint32_t bytes_needed = 0;
501 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
502 :
503 0 : if (argc != 2) {
504 0 : printf("Usage: %s logname\n", argv[0]);
505 0 : return NT_STATUS_OK;
506 : }
507 :
508 0 : status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
509 0 : if (!NT_STATUS_IS_OK(status)) {
510 0 : return status;
511 : }
512 :
513 0 : buffer = talloc_array(mem_ctx, uint8_t, bytes_needed);
514 0 : if (buffer == NULL) {
515 0 : status = NT_STATUS_NO_MEMORY;
516 0 : goto done;
517 : }
518 :
519 0 : status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
520 : &handle,
521 : 0, /* level */
522 : buffer,
523 : buf_size,
524 : &bytes_needed,
525 : &result);
526 0 : if (!NT_STATUS_IS_OK(status)) {
527 0 : goto done;
528 : }
529 0 : if (!NT_STATUS_IS_OK(result) &&
530 0 : !NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) {
531 0 : goto done;
532 : }
533 :
534 0 : buf_size = bytes_needed;
535 0 : buffer = talloc_realloc(mem_ctx, buffer, uint8_t, bytes_needed);
536 0 : if (buffer == NULL) {
537 0 : status = NT_STATUS_NO_MEMORY;
538 0 : goto done;
539 : }
540 :
541 0 : status = dcerpc_eventlog_GetLogInformation(b, mem_ctx,
542 : &handle,
543 : 0, /* level */
544 : buffer,
545 : buf_size,
546 : &bytes_needed,
547 : &result);
548 0 : if (!NT_STATUS_IS_OK(status)) {
549 0 : goto done;
550 : }
551 0 : if (!NT_STATUS_IS_OK(result)) {
552 0 : status = result;
553 0 : goto done;
554 : }
555 :
556 0 : done:
557 0 : dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);
558 :
559 0 : 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 : };
|