Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for eventlog rpc operations
4 :
5 : Copyright (C) Tim Potter 2003,2005
6 : Copyright (C) Jelmer Vernooij 2004
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/ndr_eventlog.h"
25 : #include "librpc/gen_ndr/ndr_eventlog_c.h"
26 : #include "torture/rpc/torture_rpc.h"
27 : #include "param/param.h"
28 :
29 : #define TEST_BACKUP_NAME "samrtorturetest"
30 :
31 52 : static void init_lsa_String(struct lsa_String *name, const char *s)
32 : {
33 52 : name->string = s;
34 52 : name->length = 2*strlen_m(s);
35 52 : name->size = name->length;
36 52 : }
37 :
38 24 : static bool get_policy_handle(struct torture_context *tctx,
39 : struct dcerpc_binding_handle *b,
40 : struct policy_handle *handle)
41 : {
42 0 : struct eventlog_OpenEventLogW r;
43 0 : struct eventlog_OpenUnknown0 unknown0;
44 0 : struct lsa_String logname, servername;
45 :
46 24 : unknown0.unknown0 = 0x005c;
47 24 : unknown0.unknown1 = 0x0001;
48 :
49 24 : r.in.unknown0 = &unknown0;
50 24 : init_lsa_String(&logname, "dns server");
51 24 : init_lsa_String(&servername, NULL);
52 24 : r.in.logname = &logname;
53 24 : r.in.servername = &servername;
54 24 : r.in.major_version = 0x00000001;
55 24 : r.in.minor_version = 0x00000001;
56 24 : r.out.handle = handle;
57 :
58 24 : torture_assert_ntstatus_ok(tctx,
59 : dcerpc_eventlog_OpenEventLogW_r(b, tctx, &r),
60 : "OpenEventLog failed");
61 :
62 24 : torture_assert_ntstatus_ok(tctx, r.out.result, "OpenEventLog failed");
63 :
64 12 : return true;
65 : }
66 :
67 :
68 :
69 4 : static bool test_GetNumRecords(struct torture_context *tctx, struct dcerpc_pipe *p)
70 : {
71 0 : struct eventlog_GetNumRecords r;
72 0 : struct eventlog_CloseEventLog cr;
73 0 : struct policy_handle handle;
74 4 : uint32_t number = 0;
75 4 : struct dcerpc_binding_handle *b = p->binding_handle;
76 :
77 4 : if (!get_policy_handle(tctx, b, &handle))
78 2 : return false;
79 :
80 2 : ZERO_STRUCT(r);
81 2 : r.in.handle = &handle;
82 2 : r.out.number = &number;
83 :
84 2 : torture_assert_ntstatus_ok(tctx,
85 : dcerpc_eventlog_GetNumRecords_r(b, tctx, &r),
86 : "GetNumRecords failed");
87 2 : torture_assert_ntstatus_ok(tctx, r.out.result,
88 : "GetNumRecords failed");
89 2 : torture_comment(tctx, "%d records\n", *r.out.number);
90 :
91 2 : cr.in.handle = cr.out.handle = &handle;
92 :
93 2 : torture_assert_ntstatus_ok(tctx,
94 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
95 : "CloseEventLog failed");
96 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
97 : "CloseEventLog failed");
98 2 : return true;
99 : }
100 :
101 4 : static bool test_ReadEventLog(struct torture_context *tctx,
102 : struct dcerpc_pipe *p)
103 : {
104 0 : NTSTATUS status;
105 0 : struct eventlog_ReadEventLogW r;
106 0 : struct eventlog_CloseEventLog cr;
107 0 : struct policy_handle handle;
108 4 : struct dcerpc_binding_handle *b = p->binding_handle;
109 :
110 4 : uint32_t sent_size = 0;
111 4 : uint32_t real_size = 0;
112 :
113 4 : if (!get_policy_handle(tctx, b, &handle))
114 2 : return false;
115 :
116 2 : ZERO_STRUCT(r);
117 2 : r.in.offset = 0;
118 2 : r.in.handle = &handle;
119 2 : r.in.flags = 0;
120 2 : r.out.data = NULL;
121 2 : r.out.sent_size = &sent_size;
122 2 : r.out.real_size = &real_size;
123 :
124 2 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
125 : "ReadEventLog failed");
126 :
127 2 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
128 : "ReadEventLog failed");
129 :
130 0 : while (1) {
131 0 : struct EVENTLOGRECORD rec;
132 0 : enum ndr_err_code ndr_err;
133 2 : uint32_t size = 0;
134 2 : uint32_t pos = 0;
135 :
136 : /* Read first for number of bytes in record */
137 :
138 2 : r.in.number_of_bytes = 0;
139 2 : r.in.flags = EVENTLOG_BACKWARDS_READ|EVENTLOG_SEQUENTIAL_READ;
140 2 : r.out.data = NULL;
141 2 : r.out.sent_size = &sent_size;
142 2 : r.out.real_size = &real_size;
143 :
144 2 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
145 : "ReadEventLogW failed");
146 :
147 2 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_END_OF_FILE)) {
148 : /* FIXME: still need to decode then */
149 2 : break;
150 : }
151 :
152 0 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL,
153 : "ReadEventLog failed");
154 :
155 : /* Now read the actual record */
156 :
157 0 : r.in.number_of_bytes = *r.out.real_size;
158 0 : r.out.data = talloc_array(tctx, uint8_t, r.in.number_of_bytes);
159 :
160 0 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_ReadEventLogW_r(b, tctx, &r),
161 : "ReadEventLogW failed");
162 :
163 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "ReadEventLog failed");
164 :
165 : /* Decode a user-marshalled record */
166 0 : size = IVAL(r.out.data, pos);
167 :
168 0 : while (size > 0) {
169 0 : DATA_BLOB blob = data_blob_const(
170 0 : r.out.data + pos, size);
171 0 : dump_data(0, blob.data, blob.length);
172 :
173 0 : ndr_err = ndr_pull_struct_blob_all(&blob, tctx, &rec,
174 : (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
175 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
176 0 : status = ndr_map_error2ntstatus(ndr_err);
177 0 : torture_assert_ntstatus_ok(tctx, status,
178 : "ReadEventLog failed parsing event log record");
179 : }
180 :
181 0 : NDR_PRINT_DEBUG(EVENTLOGRECORD, &rec);
182 :
183 0 : pos += size;
184 :
185 0 : if (pos + 4 > *r.out.sent_size) {
186 0 : break;
187 : }
188 :
189 0 : size = IVAL(r.out.data, pos);
190 : }
191 :
192 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
193 : "ReadEventLog failed parsing event log record");
194 :
195 0 : r.in.offset++;
196 : }
197 :
198 2 : cr.in.handle = cr.out.handle = &handle;
199 :
200 2 : torture_assert_ntstatus_ok(tctx,
201 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
202 : "CloseEventLog failed");
203 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
204 : "CloseEventLog failed");
205 :
206 2 : return true;
207 : }
208 :
209 4 : static bool test_ReportEventLog(struct torture_context *tctx,
210 : struct dcerpc_pipe *p)
211 : {
212 0 : struct eventlog_ReportEventW r;
213 0 : struct eventlog_CloseEventLog cr;
214 0 : struct policy_handle handle;
215 4 : struct dcerpc_binding_handle *b = p->binding_handle;
216 :
217 4 : uint32_t record_number = 0;
218 4 : time_t time_written = 0;
219 0 : struct lsa_String servername, *strings;
220 :
221 4 : if (!get_policy_handle(tctx, b, &handle))
222 2 : return false;
223 :
224 2 : init_lsa_String(&servername, NULL);
225 :
226 2 : strings = talloc_array(tctx, struct lsa_String, 1);
227 2 : init_lsa_String(&strings[0], "Currently tortured by samba 4");
228 :
229 2 : ZERO_STRUCT(r);
230 :
231 2 : r.in.handle = &handle;
232 2 : r.in.timestamp = time(NULL);
233 2 : r.in.event_type = EVENTLOG_INFORMATION_TYPE;
234 2 : r.in.event_category = 0;
235 2 : r.in.event_id = 0;
236 2 : r.in.num_of_strings = 1;
237 2 : r.in.data_size = 0;
238 2 : r.in.servername = &servername;
239 2 : r.in.user_sid = NULL;
240 2 : r.in.strings = &strings;
241 2 : r.in.data = NULL;
242 2 : r.in.flags = 0;
243 2 : r.in.record_number = r.out.record_number = &record_number;
244 2 : r.in.time_written = r.out.time_written = &time_written;
245 :
246 2 : torture_assert_ntstatus_ok(tctx,
247 : dcerpc_eventlog_ReportEventW_r(b, tctx, &r),
248 : "ReportEventW failed");
249 :
250 2 : torture_assert_ntstatus_ok(tctx, r.out.result, "ReportEventW failed");
251 :
252 2 : cr.in.handle = cr.out.handle = &handle;
253 :
254 2 : torture_assert_ntstatus_ok(tctx,
255 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
256 : "CloseEventLog failed");
257 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
258 : "CloseEventLog failed");
259 :
260 2 : return true;
261 : }
262 :
263 4 : static bool test_FlushEventLog(struct torture_context *tctx,
264 : struct dcerpc_pipe *p)
265 : {
266 0 : struct eventlog_FlushEventLog r;
267 0 : struct eventlog_CloseEventLog cr;
268 0 : struct policy_handle handle;
269 4 : struct dcerpc_binding_handle *b = p->binding_handle;
270 :
271 4 : if (!get_policy_handle(tctx, b, &handle))
272 2 : return false;
273 :
274 2 : r.in.handle = &handle;
275 :
276 : /* Huh? Does this RPC always return access denied? */
277 2 : torture_assert_ntstatus_ok(tctx,
278 : dcerpc_eventlog_FlushEventLog_r(b, tctx, &r),
279 : "FlushEventLog failed");
280 :
281 2 : torture_assert_ntstatus_equal(tctx,
282 : r.out.result,
283 : NT_STATUS_ACCESS_DENIED,
284 : "FlushEventLog failed");
285 :
286 2 : cr.in.handle = cr.out.handle = &handle;
287 :
288 2 : torture_assert_ntstatus_ok(tctx,
289 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
290 : "CloseEventLog failed");
291 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
292 : "CloseEventLog failed");
293 :
294 2 : return true;
295 : }
296 :
297 0 : static bool test_ClearEventLog(struct torture_context *tctx,
298 : struct dcerpc_pipe *p)
299 : {
300 0 : struct eventlog_ClearEventLogW r;
301 0 : struct eventlog_CloseEventLog cr;
302 0 : struct policy_handle handle;
303 0 : struct dcerpc_binding_handle *b = p->binding_handle;
304 :
305 0 : if (!get_policy_handle(tctx, b, &handle))
306 0 : return false;
307 :
308 0 : r.in.handle = &handle;
309 0 : r.in.backupfile = NULL;
310 :
311 0 : torture_assert_ntstatus_ok(tctx,
312 : dcerpc_eventlog_ClearEventLogW_r(b, tctx, &r),
313 : "ClearEventLog failed");
314 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
315 : "ClearEventLog failed");
316 :
317 0 : cr.in.handle = cr.out.handle = &handle;
318 :
319 0 : torture_assert_ntstatus_ok(tctx,
320 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
321 : "CloseEventLog failed");
322 0 : torture_assert_ntstatus_ok(tctx, cr.out.result,
323 : "CloseEventLog failed");
324 :
325 0 : return true;
326 : }
327 :
328 4 : static bool test_GetLogInformation(struct torture_context *tctx,
329 : struct dcerpc_pipe *p)
330 : {
331 0 : struct eventlog_GetLogInformation r;
332 0 : struct eventlog_CloseEventLog cr;
333 0 : struct policy_handle handle;
334 4 : uint32_t bytes_needed = 0;
335 4 : struct dcerpc_binding_handle *b = p->binding_handle;
336 :
337 4 : if (!get_policy_handle(tctx, b, &handle))
338 2 : return false;
339 :
340 2 : r.in.handle = &handle;
341 2 : r.in.level = 1;
342 2 : r.in.buf_size = 0;
343 2 : r.out.buffer = NULL;
344 2 : r.out.bytes_needed = &bytes_needed;
345 :
346 2 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
347 : "GetLogInformation failed");
348 :
349 2 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_LEVEL,
350 : "GetLogInformation failed");
351 :
352 2 : r.in.level = 0;
353 :
354 2 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
355 : "GetLogInformation failed");
356 :
357 2 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL,
358 : "GetLogInformation failed");
359 :
360 2 : r.in.buf_size = bytes_needed;
361 2 : r.out.buffer = talloc_array(tctx, uint8_t, bytes_needed);
362 :
363 2 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_GetLogInformation_r(b, tctx, &r),
364 : "GetLogInformation failed");
365 :
366 2 : torture_assert_ntstatus_ok(tctx, r.out.result, "GetLogInformation failed");
367 :
368 2 : cr.in.handle = cr.out.handle = &handle;
369 :
370 2 : torture_assert_ntstatus_ok(tctx,
371 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
372 : "CloseEventLog failed");
373 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
374 : "CloseEventLog failed");
375 :
376 2 : return true;
377 : }
378 :
379 :
380 4 : static bool test_OpenEventLog(struct torture_context *tctx,
381 : struct dcerpc_pipe *p)
382 : {
383 0 : struct policy_handle handle;
384 0 : struct eventlog_CloseEventLog cr;
385 4 : struct dcerpc_binding_handle *b = p->binding_handle;
386 :
387 4 : if (!get_policy_handle(tctx, b, &handle))
388 2 : return false;
389 :
390 2 : cr.in.handle = cr.out.handle = &handle;
391 :
392 2 : torture_assert_ntstatus_ok(tctx,
393 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
394 : "CloseEventLog failed");
395 2 : torture_assert_ntstatus_ok(tctx, cr.out.result,
396 : "CloseEventLog failed");
397 :
398 2 : return true;
399 : }
400 :
401 4 : static bool test_BackupLog(struct torture_context *tctx,
402 : struct dcerpc_pipe *p)
403 : {
404 0 : struct policy_handle handle, backup_handle;
405 0 : struct eventlog_BackupEventLogW r;
406 0 : struct eventlog_OpenBackupEventLogW br;
407 0 : struct eventlog_CloseEventLog cr;
408 0 : const char *tmp;
409 0 : struct lsa_String backup_filename;
410 0 : struct eventlog_OpenUnknown0 unknown0;
411 4 : struct dcerpc_binding_handle *b = p->binding_handle;
412 :
413 4 : if (torture_setting_bool(tctx, "samba3", false)) {
414 4 : torture_skip(tctx, "skipping BackupLog test against samba");
415 : }
416 :
417 0 : if (!get_policy_handle(tctx, b, &handle))
418 0 : return false;
419 :
420 0 : tmp = talloc_asprintf(tctx, "C:\\%s", TEST_BACKUP_NAME);
421 0 : init_lsa_String(&backup_filename, tmp);
422 :
423 0 : r.in.handle = &handle;
424 0 : r.in.backup_filename = &backup_filename;
425 :
426 0 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
427 : "BackupEventLogW failed");
428 0 : torture_assert_ntstatus_equal(tctx, r.out.result,
429 : NT_STATUS_OBJECT_PATH_SYNTAX_BAD, "BackupEventLogW failed");
430 :
431 0 : tmp = talloc_asprintf(tctx, "\\??\\C:\\%s", TEST_BACKUP_NAME);
432 0 : init_lsa_String(&backup_filename, tmp);
433 :
434 0 : r.in.handle = &handle;
435 0 : r.in.backup_filename = &backup_filename;
436 :
437 0 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
438 : "BackupEventLogW failed");
439 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "BackupEventLogW failed");
440 :
441 0 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_BackupEventLogW_r(b, tctx, &r),
442 : "BackupEventLogW failed");
443 0 : torture_assert_ntstatus_equal(tctx, r.out.result,
444 : NT_STATUS_OBJECT_NAME_COLLISION, "BackupEventLogW failed");
445 :
446 0 : cr.in.handle = cr.out.handle = &handle;
447 :
448 0 : torture_assert_ntstatus_ok(tctx,
449 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
450 : "BackupLog failed");
451 0 : torture_assert_ntstatus_ok(tctx, cr.out.result,
452 : "BackupLog failed");
453 :
454 0 : unknown0.unknown0 = 0x005c;
455 0 : unknown0.unknown1 = 0x0001;
456 :
457 0 : br.in.unknown0 = &unknown0;
458 0 : br.in.backup_logname = &backup_filename;
459 0 : br.in.major_version = 1;
460 0 : br.in.minor_version = 1;
461 0 : br.out.handle = &backup_handle;
462 :
463 0 : torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_OpenBackupEventLogW_r(b, tctx, &br),
464 : "OpenBackupEventLogW failed");
465 :
466 0 : torture_assert_ntstatus_ok(tctx, br.out.result, "OpenBackupEventLogW failed");
467 :
468 0 : cr.in.handle = cr.out.handle = &backup_handle;
469 :
470 0 : torture_assert_ntstatus_ok(tctx,
471 : dcerpc_eventlog_CloseEventLog_r(b, tctx, &cr),
472 : "CloseEventLog failed");
473 0 : torture_assert_ntstatus_ok(tctx, cr.out.result,
474 : "CloseEventLog failed");
475 :
476 0 : return true;
477 : }
478 :
479 2354 : struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx)
480 : {
481 125 : struct torture_suite *suite;
482 125 : struct torture_rpc_tcase *tcase;
483 125 : struct torture_test *test;
484 :
485 2354 : suite = torture_suite_create(mem_ctx, "eventlog");
486 2354 : tcase = torture_suite_add_rpc_iface_tcase(suite, "eventlog",
487 : &ndr_table_eventlog);
488 :
489 2354 : torture_rpc_tcase_add_test(tcase, "OpenEventLog", test_OpenEventLog);
490 2354 : test = torture_rpc_tcase_add_test(tcase, "ClearEventLog",
491 : test_ClearEventLog);
492 2354 : test->dangerous = true;
493 2354 : torture_rpc_tcase_add_test(tcase, "GetNumRecords", test_GetNumRecords);
494 2354 : torture_rpc_tcase_add_test(tcase, "ReadEventLog", test_ReadEventLog);
495 2354 : torture_rpc_tcase_add_test(tcase, "ReportEventLog", test_ReportEventLog);
496 2354 : torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog);
497 2354 : torture_rpc_tcase_add_test(tcase, "GetLogIntormation", test_GetLogInformation);
498 2354 : torture_rpc_tcase_add_test(tcase, "BackupLog", test_BackupLog);
499 :
500 2354 : return suite;
501 : }
|