2 Unix SMB/CIFS implementation.
3 test suite for eventlog rpc operations
5 Copyright (C) Tim Potter 2003,2005
6 Copyright (C) Jelmer Vernooij 2004
7 Copyright (C) Guenther Deschner 2009
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.
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.
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/>.
24 #include "librpc/gen_ndr/ndr_eventlog.h"
25 #include "librpc/gen_ndr/ndr_eventlog_c.h"
26 #include "torture/rpc/torture_rpc.h"
27 #include "param/param.h"
29 #define TEST_BACKUP_NAME "samrtorturetest"
31 static void init_lsa_String(struct lsa_String *name, const char *s)
34 name->length = 2*strlen_m(s);
35 name->size = name->length;
38 static bool get_policy_handle(struct torture_context *tctx,
39 struct dcerpc_binding_handle *b,
40 struct policy_handle *handle)
42 struct eventlog_OpenEventLogW r;
43 struct eventlog_OpenUnknown0 unknown0;
44 struct lsa_String logname, servername;
46 unknown0.unknown0 = 0x005c;
47 unknown0.unknown1 = 0x0001;
49 r.in.unknown0 = &unknown0;
50 init_lsa_String(&logname, "dns server");
51 init_lsa_String(&servername, NULL);
52 r.in.logname = &logname;
53 r.in.servername = &servername;
54 r.in.major_version = 0x00000001;
55 r.in.minor_version = 0x00000001;
56 r.out.handle = handle;
58 torture_assert_ntstatus_ok(tctx,
59 dcerpc_eventlog_OpenEventLogW_r(b, tctx, &r),
60 "OpenEventLog failed");
62 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenEventLog failed");
69 static bool test_GetNumRecords(struct torture_context *tctx, struct dcerpc_pipe *p)
71 struct eventlog_GetNumRecords r;
72 struct eventlog_CloseEventLog cr;
73 struct policy_handle handle;
75 struct dcerpc_binding_handle *b = p->binding_handle;
77 if (!get_policy_handle(tctx, b, &handle))
81 r.in.handle = &handle;
82 r.out.number = &number;
84 torture_assert_ntstatus_ok(tctx,
85 dcerpc_eventlog_GetNumRecords_r(b, tctx, &r),
86 "GetNumRecords failed");
87 torture_assert_ntstatus_ok(tctx, r.out.result,
88 "GetNumRecords failed");
89 torture_comment(tctx, "%d records\n", *r.out.number);
91 cr.in.handle = cr.out.handle = &handle;
93 torture_assert_ntstatus_ok(tctx,
94 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
95 "CloseEventLog failed");
96 torture_assert_ntstatus_ok(tctx, cr.out.result,
97 "CloseEventLog failed");
101 static bool test_ReadEventLog(struct torture_context *tctx,
102 struct dcerpc_pipe *p)
105 struct eventlog_ReadEventLogW r;
106 struct eventlog_CloseEventLog cr;
107 struct policy_handle handle;
108 struct dcerpc_binding_handle *b = p->binding_handle;
110 uint32_t sent_size = 0;
111 uint32_t real_size = 0;
113 if (!get_policy_handle(tctx, b, &handle))
118 r.in.handle = &handle;
121 r.out.sent_size = &sent_size;
122 r.out.real_size = &real_size;
124 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
125 "ReadEventLog failed");
127 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
128 "ReadEventLog failed");
132 struct EVENTLOGRECORD rec;
133 enum ndr_err_code ndr_err;
137 /* Read first for number of bytes in record */
139 r.in.number_of_bytes = 0;
140 r.in.flags = EVENTLOG_BACKWARDS_READ|EVENTLOG_SEQUENTIAL_READ;
142 r.out.sent_size = &sent_size;
143 r.out.real_size = &real_size;
145 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
146 "ReadEventLogW failed");
148 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_END_OF_FILE)) {
149 /* FIXME: still need to decode then */
153 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL,
154 "ReadEventLog failed");
156 /* Now read the actual record */
158 r.in.number_of_bytes = *r.out.real_size;
159 r.out.data = talloc_array(tctx, uint8_t, r.in.number_of_bytes);
161 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
162 "ReadEventLogW failed");
164 torture_assert_ntstatus_ok(tctx, r.out.result, "ReadEventLog failed");
166 /* Decode a user-marshalled record */
167 size = IVAL(r.out.data, pos);
171 blob = data_blob_const(r.out.data + pos, size);
172 dump_data(0, blob.data, blob.length);
174 ndr_err = ndr_pull_struct_blob_all(&blob, tctx,
175 lp_iconv_convenience(tctx->lp_ctx), &rec,
176 (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
177 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
178 status = ndr_map_error2ntstatus(ndr_err);
179 torture_assert_ntstatus_ok(tctx, status,
180 "ReadEventLog failed parsing event log record");
183 NDR_PRINT_DEBUG(EVENTLOGRECORD, &rec);
187 if (pos + 4 > *r.out.sent_size) {
191 size = IVAL(r.out.data, pos);
194 torture_assert_ntstatus_ok(tctx, r.out.result,
195 "ReadEventLog failed parsing event log record");
200 cr.in.handle = cr.out.handle = &handle;
202 torture_assert_ntstatus_ok(tctx,
203 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
204 "CloseEventLog failed");
205 torture_assert_ntstatus_ok(tctx, cr.out.result,
206 "CloseEventLog failed");
211 static bool test_ReportEventLog(struct torture_context *tctx,
212 struct dcerpc_pipe *p)
214 struct eventlog_ReportEventW r;
215 struct eventlog_CloseEventLog cr;
216 struct policy_handle handle;
217 struct dcerpc_binding_handle *b = p->binding_handle;
219 uint32_t record_number = 0;
220 time_t time_written = 0;
221 struct lsa_String servername, *strings;
223 if (!get_policy_handle(tctx, b, &handle))
226 init_lsa_String(&servername, NULL);
228 strings = talloc_array(tctx, struct lsa_String, 1);
229 init_lsa_String(&strings[0], "Currently tortured by samba 4");
233 r.in.handle = &handle;
234 r.in.timestamp = time(NULL);
235 r.in.event_type = EVENTLOG_INFORMATION_TYPE;
236 r.in.event_category = 0;
238 r.in.num_of_strings = 1;
240 r.in.servername = &servername;
241 r.in.user_sid = NULL;
242 r.in.strings = &strings;
245 r.in.record_number = r.out.record_number = &record_number;
246 r.in.time_written = r.out.time_written = &time_written;
248 torture_assert_ntstatus_ok(tctx,
249 dcerpc_eventlog_ReportEventW_r(b, tctx, &r),
250 "ReportEventW failed");
252 torture_assert_ntstatus_ok(tctx, r.out.result, "ReportEventW failed");
254 cr.in.handle = cr.out.handle = &handle;
256 torture_assert_ntstatus_ok(tctx,
257 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
258 "CloseEventLog failed");
259 torture_assert_ntstatus_ok(tctx, cr.out.result,
260 "CloseEventLog failed");
265 static bool test_FlushEventLog(struct torture_context *tctx,
266 struct dcerpc_pipe *p)
268 struct eventlog_FlushEventLog r;
269 struct eventlog_CloseEventLog cr;
270 struct policy_handle handle;
271 struct dcerpc_binding_handle *b = p->binding_handle;
273 if (!get_policy_handle(tctx, b, &handle))
276 r.in.handle = &handle;
278 /* Huh? Does this RPC always return access denied? */
279 torture_assert_ntstatus_ok(tctx,
280 dcerpc_eventlog_FlushEventLog_r(b, tctx, &r),
281 "FlushEventLog failed");
283 torture_assert_ntstatus_equal(tctx,
285 NT_STATUS_ACCESS_DENIED,
286 "FlushEventLog failed");
288 cr.in.handle = cr.out.handle = &handle;
290 torture_assert_ntstatus_ok(tctx,
291 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
292 "CloseEventLog failed");
293 torture_assert_ntstatus_ok(tctx, cr.out.result,
294 "CloseEventLog failed");
299 static bool test_ClearEventLog(struct torture_context *tctx,
300 struct dcerpc_pipe *p)
302 struct eventlog_ClearEventLogW r;
303 struct eventlog_CloseEventLog cr;
304 struct policy_handle handle;
305 struct dcerpc_binding_handle *b = p->binding_handle;
307 if (!get_policy_handle(tctx, b, &handle))
310 r.in.handle = &handle;
311 r.in.backupfile = NULL;
313 torture_assert_ntstatus_ok(tctx,
314 dcerpc_eventlog_ClearEventLogW_r(b, tctx, &r),
315 "ClearEventLog failed");
316 torture_assert_ntstatus_ok(tctx, r.out.result,
317 "ClearEventLog failed");
319 cr.in.handle = cr.out.handle = &handle;
321 torture_assert_ntstatus_ok(tctx,
322 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
323 "CloseEventLog failed");
324 torture_assert_ntstatus_ok(tctx, cr.out.result,
325 "CloseEventLog failed");
330 static bool test_GetLogInformation(struct torture_context *tctx,
331 struct dcerpc_pipe *p)
333 struct eventlog_GetLogInformation r;
334 struct eventlog_CloseEventLog cr;
335 struct policy_handle handle;
336 uint32_t bytes_needed = 0;
337 struct dcerpc_binding_handle *b = p->binding_handle;
339 if (!get_policy_handle(tctx, b, &handle))
342 r.in.handle = &handle;
346 r.out.bytes_needed = &bytes_needed;
348 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
349 "GetLogInformation failed");
351 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_LEVEL,
352 "GetLogInformation failed");
356 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
357 "GetLogInformation failed");
359 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL,
360 "GetLogInformation failed");
362 r.in.buf_size = bytes_needed;
363 r.out.buffer = talloc_array(tctx, uint8_t, bytes_needed);
365 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
366 "GetLogInformation failed");
368 torture_assert_ntstatus_ok(tctx, r.out.result, "GetLogInformation failed");
370 cr.in.handle = cr.out.handle = &handle;
372 torture_assert_ntstatus_ok(tctx,
373 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
374 "CloseEventLog failed");
375 torture_assert_ntstatus_ok(tctx, cr.out.result,
376 "CloseEventLog failed");
382 static bool test_OpenEventLog(struct torture_context *tctx,
383 struct dcerpc_pipe *p)
385 struct policy_handle handle;
386 struct eventlog_CloseEventLog cr;
387 struct dcerpc_binding_handle *b = p->binding_handle;
389 if (!get_policy_handle(tctx, b, &handle))
392 cr.in.handle = cr.out.handle = &handle;
394 torture_assert_ntstatus_ok(tctx,
395 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
396 "CloseEventLog failed");
397 torture_assert_ntstatus_ok(tctx, cr.out.result,
398 "CloseEventLog failed");
403 static bool test_BackupLog(struct torture_context *tctx,
404 struct dcerpc_pipe *p)
406 struct policy_handle handle, backup_handle;
407 struct eventlog_BackupEventLogW r;
408 struct eventlog_OpenBackupEventLogW br;
409 struct eventlog_CloseEventLog cr;
411 struct lsa_String backup_filename;
412 struct eventlog_OpenUnknown0 unknown0;
413 struct dcerpc_binding_handle *b = p->binding_handle;
415 if (torture_setting_bool(tctx, "samba3", false)) {
416 torture_skip(tctx, "skipping BackupLog test against samba");
419 if (!get_policy_handle(tctx, b, &handle))
422 tmp = talloc_asprintf(tctx, "C:\\%s", TEST_BACKUP_NAME);
423 init_lsa_String(&backup_filename, tmp);
425 r.in.handle = &handle;
426 r.in.backup_filename = &backup_filename;
428 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
429 "BackupEventLogW failed");
430 torture_assert_ntstatus_equal(tctx, r.out.result,
431 NT_STATUS_OBJECT_PATH_SYNTAX_BAD, "BackupEventLogW failed");
433 tmp = talloc_asprintf(tctx, "\\??\\C:\\%s", TEST_BACKUP_NAME);
434 init_lsa_String(&backup_filename, tmp);
436 r.in.handle = &handle;
437 r.in.backup_filename = &backup_filename;
439 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
440 "BackupEventLogW failed");
441 torture_assert_ntstatus_ok(tctx, r.out.result, "BackupEventLogW failed");
443 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
444 "BackupEventLogW failed");
445 torture_assert_ntstatus_equal(tctx, r.out.result,
446 NT_STATUS_OBJECT_NAME_COLLISION, "BackupEventLogW failed");
448 cr.in.handle = cr.out.handle = &handle;
450 torture_assert_ntstatus_ok(tctx,
451 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
453 torture_assert_ntstatus_ok(tctx, cr.out.result,
456 unknown0.unknown0 = 0x005c;
457 unknown0.unknown1 = 0x0001;
459 br.in.unknown0 = &unknown0;
460 br.in.backup_logname = &backup_filename;
461 br.in.major_version = 1;
462 br.in.minor_version = 1;
463 br.out.handle = &backup_handle;
465 torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_OpenBackupEventLogW_r(b, tctx, &br),
466 "OpenBackupEventLogW failed");
468 torture_assert_ntstatus_ok(tctx, br.out.result, "OpenBackupEventLogW failed");
470 cr.in.handle = cr.out.handle = &backup_handle;
472 torture_assert_ntstatus_ok(tctx,
473 dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
474 "CloseEventLog failed");
475 torture_assert_ntstatus_ok(tctx, cr.out.result,
476 "CloseEventLog failed");
481 struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx)
483 struct torture_suite *suite;
484 struct torture_rpc_tcase *tcase;
485 struct torture_test *test;
487 suite = torture_suite_create(mem_ctx, "EVENTLOG");
488 tcase = torture_suite_add_rpc_iface_tcase(suite, "eventlog",
489 &ndr_table_eventlog);
491 torture_rpc_tcase_add_test(tcase, "OpenEventLog", test_OpenEventLog);
492 test = torture_rpc_tcase_add_test(tcase, "ClearEventLog",
494 test->dangerous = true;
495 torture_rpc_tcase_add_test(tcase, "GetNumRecords", test_GetNumRecords);
496 torture_rpc_tcase_add_test(tcase, "ReadEventLog", test_ReadEventLog);
497 torture_rpc_tcase_add_test(tcase, "ReportEventLog", test_ReportEventLog);
498 torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog);
499 torture_rpc_tcase_add_test(tcase, "GetLogIntormation", test_GetLogInformation);
500 torture_rpc_tcase_add_test(tcase, "BackupLog", test_BackupLog);