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 "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_eventlog.h"
26 #include "librpc/gen_ndr/ndr_eventlog_c.h"
27 #include "librpc/gen_ndr/ndr_lsa.h"
28 #include "torture/rpc/rpc.h"
29 #include "param/param.h"
31 #define TEST_BACKUP_NAME "samrtorturetest"
33 static void init_lsa_String(struct lsa_String
*name
, const char *s
)
36 name
->length
= 2*strlen_m(s
);
37 name
->size
= name
->length
;
40 static bool get_policy_handle(struct torture_context
*tctx
,
41 struct dcerpc_pipe
*p
,
42 struct policy_handle
*handle
)
44 struct eventlog_OpenEventLogW r
;
45 struct eventlog_OpenUnknown0 unknown0
;
46 struct lsa_String logname
, servername
;
48 unknown0
.unknown0
= 0x005c;
49 unknown0
.unknown1
= 0x0001;
51 r
.in
.unknown0
= &unknown0
;
52 init_lsa_String(&logname
, "dns server");
53 init_lsa_String(&servername
, NULL
);
54 r
.in
.logname
= &logname
;
55 r
.in
.servername
= &servername
;
56 r
.in
.major_version
= 0x00000001;
57 r
.in
.minor_version
= 0x00000001;
58 r
.out
.handle
= handle
;
60 torture_assert_ntstatus_ok(tctx
,
61 dcerpc_eventlog_OpenEventLogW(p
, tctx
, &r
),
62 "OpenEventLog failed");
64 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenEventLog failed");
71 static bool test_GetNumRecords(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
73 struct eventlog_GetNumRecords r
;
74 struct eventlog_CloseEventLog cr
;
75 struct policy_handle handle
;
78 if (!get_policy_handle(tctx
, p
, &handle
))
82 r
.in
.handle
= &handle
;
83 r
.out
.number
= &number
;
85 torture_assert_ntstatus_ok(tctx
,
86 dcerpc_eventlog_GetNumRecords(p
, tctx
, &r
),
87 "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(p
, tctx
, &cr
),
95 "CloseEventLog failed");
99 static bool test_ReadEventLog(struct torture_context
*tctx
,
100 struct dcerpc_pipe
*p
)
103 struct eventlog_ReadEventLogW r
;
104 struct eventlog_CloseEventLog cr
;
105 struct policy_handle handle
;
107 uint32_t sent_size
= 0;
108 uint32_t real_size
= 0;
110 if (!get_policy_handle(tctx
, p
, &handle
))
115 r
.in
.handle
= &handle
;
118 r
.out
.sent_size
= &sent_size
;
119 r
.out
.real_size
= &real_size
;
121 status
= dcerpc_eventlog_ReadEventLogW(p
, tctx
, &r
);
123 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_INVALID_PARAMETER
,
124 "ReadEventLog failed");
128 struct EVENTLOGRECORD rec
;
129 enum ndr_err_code ndr_err
;
133 /* Read first for number of bytes in record */
135 r
.in
.number_of_bytes
= 0;
136 r
.in
.flags
= EVENTLOG_BACKWARDS_READ
|EVENTLOG_SEQUENTIAL_READ
;
138 r
.out
.sent_size
= &sent_size
;
139 r
.out
.real_size
= &real_size
;
141 status
= dcerpc_eventlog_ReadEventLogW(p
, tctx
, &r
);
143 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_END_OF_FILE
)) {
144 /* FIXME: still need to decode then */
148 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_BUFFER_TOO_SMALL
,
149 "ReadEventLog failed");
151 /* Now read the actual record */
153 r
.in
.number_of_bytes
= *r
.out
.real_size
;
154 r
.out
.data
= talloc_array(tctx
, uint8_t, r
.in
.number_of_bytes
);
156 status
= dcerpc_eventlog_ReadEventLogW(p
, tctx
, &r
);
158 torture_assert_ntstatus_ok(tctx
, status
, "ReadEventLog failed");
160 /* Decode a user-marshalled record */
161 size
= IVAL(r
.out
.data
, pos
);
165 blob
= data_blob_const(r
.out
.data
+ pos
, size
);
166 dump_data(0, blob
.data
, blob
.length
);
168 ndr_err
= ndr_pull_struct_blob_all(&blob
, tctx
,
169 lp_iconv_convenience(tctx
->lp_ctx
), &rec
,
170 (ndr_pull_flags_fn_t
)ndr_pull_EVENTLOGRECORD
);
171 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
172 status
= ndr_map_error2ntstatus(ndr_err
);
173 torture_assert_ntstatus_ok(tctx
, status
,
174 "ReadEventLog failed parsing event log record");
177 NDR_PRINT_DEBUG(EVENTLOGRECORD
, &rec
);
181 if (pos
+ 4 > *r
.out
.sent_size
) {
185 size
= IVAL(r
.out
.data
, pos
);
188 torture_assert_ntstatus_ok(tctx
, status
,
189 "ReadEventLog failed parsing event log record");
194 cr
.in
.handle
= cr
.out
.handle
= &handle
;
196 torture_assert_ntstatus_ok(tctx
,
197 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
198 "CloseEventLog failed");
203 static bool test_ReportEventLog(struct torture_context
*tctx
,
204 struct dcerpc_pipe
*p
)
207 struct eventlog_ReportEventW r
;
208 struct eventlog_CloseEventLog cr
;
209 struct policy_handle handle
;
211 uint32_t record_number
= 0;
212 time_t time_written
= 0;
213 struct lsa_String servername
, *strings
;
215 if (!get_policy_handle(tctx
, p
, &handle
))
218 init_lsa_String(&servername
, NULL
);
220 strings
= talloc_array(tctx
, struct lsa_String
, 1);
221 init_lsa_String(&strings
[0], "Currently tortured by samba 4");
225 r
.in
.handle
= &handle
;
226 r
.in
.timestamp
= time(NULL
);
227 r
.in
.event_type
= EVENTLOG_INFORMATION_TYPE
;
228 r
.in
.event_category
= 0;
230 r
.in
.num_of_strings
= 1;
232 r
.in
.servername
= &servername
;
233 r
.in
.user_sid
= NULL
;
234 r
.in
.strings
= &strings
;
237 r
.out
.record_number
= &record_number
;
238 r
.out
.time_written
= &time_written
;
240 status
= dcerpc_eventlog_ReportEventW(p
, tctx
, &r
);
242 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ReportEventW failed");
244 cr
.in
.handle
= cr
.out
.handle
= &handle
;
246 torture_assert_ntstatus_ok(tctx
,
247 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
248 "CloseEventLog failed");
252 static bool test_FlushEventLog(struct torture_context
*tctx
,
253 struct dcerpc_pipe
*p
)
255 struct eventlog_FlushEventLog r
;
256 struct eventlog_CloseEventLog cr
;
257 struct policy_handle handle
;
259 if (!get_policy_handle(tctx
, p
, &handle
))
262 r
.in
.handle
= &handle
;
264 /* Huh? Does this RPC always return access denied? */
265 torture_assert_ntstatus_equal(tctx
,
266 dcerpc_eventlog_FlushEventLog(p
, tctx
, &r
),
267 NT_STATUS_ACCESS_DENIED
,
268 "FlushEventLog failed");
270 cr
.in
.handle
= cr
.out
.handle
= &handle
;
272 torture_assert_ntstatus_ok(tctx
,
273 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
274 "CloseEventLog failed");
279 static bool test_ClearEventLog(struct torture_context
*tctx
,
280 struct dcerpc_pipe
*p
)
282 struct eventlog_ClearEventLogW r
;
283 struct eventlog_CloseEventLog cr
;
284 struct policy_handle handle
;
286 if (!get_policy_handle(tctx
, p
, &handle
))
289 r
.in
.handle
= &handle
;
290 r
.in
.backupfile
= NULL
;
292 torture_assert_ntstatus_ok(tctx
,
293 dcerpc_eventlog_ClearEventLogW(p
, tctx
, &r
),
294 "ClearEventLog failed");
296 cr
.in
.handle
= cr
.out
.handle
= &handle
;
298 torture_assert_ntstatus_ok(tctx
,
299 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
300 "CloseEventLog failed");
305 static bool test_GetLogInformation(struct torture_context
*tctx
,
306 struct dcerpc_pipe
*p
)
309 struct eventlog_GetLogInformation r
;
310 struct eventlog_CloseEventLog cr
;
311 struct policy_handle handle
;
312 uint32_t bytes_needed
= 0;
314 if (!get_policy_handle(tctx
, p
, &handle
))
317 r
.in
.handle
= &handle
;
321 r
.out
.bytes_needed
= &bytes_needed
;
323 status
= dcerpc_eventlog_GetLogInformation(p
, tctx
, &r
);
325 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_INVALID_LEVEL
,
326 "GetLogInformation failed");
330 status
= dcerpc_eventlog_GetLogInformation(p
, tctx
, &r
);
332 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_BUFFER_TOO_SMALL
,
333 "GetLogInformation failed");
335 r
.in
.buf_size
= bytes_needed
;
336 r
.out
.buffer
= talloc_array(tctx
, uint8_t, bytes_needed
);
338 status
= dcerpc_eventlog_GetLogInformation(p
, tctx
, &r
);
340 torture_assert_ntstatus_ok(tctx
, status
, "GetLogInformation failed");
342 cr
.in
.handle
= cr
.out
.handle
= &handle
;
344 torture_assert_ntstatus_ok(tctx
,
345 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
346 "CloseEventLog failed");
352 static bool test_OpenEventLog(struct torture_context
*tctx
,
353 struct dcerpc_pipe
*p
)
355 struct policy_handle handle
;
356 struct eventlog_CloseEventLog cr
;
358 if (!get_policy_handle(tctx
, p
, &handle
))
361 cr
.in
.handle
= cr
.out
.handle
= &handle
;
363 torture_assert_ntstatus_ok(tctx
,
364 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
365 "CloseEventLog failed");
370 static bool test_BackupLog(struct torture_context
*tctx
,
371 struct dcerpc_pipe
*p
)
374 struct policy_handle handle
, backup_handle
;
375 struct eventlog_BackupEventLogW r
;
376 struct eventlog_OpenBackupEventLogW b
;
377 struct eventlog_CloseEventLog cr
;
379 struct lsa_String backup_filename
;
380 struct eventlog_OpenUnknown0 unknown0
;
382 if (!get_policy_handle(tctx
, p
, &handle
))
385 tmp
= talloc_asprintf(tctx
, "C:\\%s", TEST_BACKUP_NAME
);
386 init_lsa_String(&backup_filename
, tmp
);
388 r
.in
.handle
= &handle
;
389 r
.in
.backup_filename
= &backup_filename
;
391 status
= dcerpc_eventlog_BackupEventLogW(p
, tctx
, &r
);
392 torture_assert_ntstatus_equal(tctx
, status
,
393 NT_STATUS_OBJECT_PATH_SYNTAX_BAD
, "BackupEventLogW failed");
395 tmp
= talloc_asprintf(tctx
, "\\??\\C:\\%s", TEST_BACKUP_NAME
);
396 init_lsa_String(&backup_filename
, tmp
);
398 r
.in
.handle
= &handle
;
399 r
.in
.backup_filename
= &backup_filename
;
401 status
= dcerpc_eventlog_BackupEventLogW(p
, tctx
, &r
);
402 torture_assert_ntstatus_ok(tctx
, status
, "BackupEventLogW failed");
404 status
= dcerpc_eventlog_BackupEventLogW(p
, tctx
, &r
);
405 torture_assert_ntstatus_equal(tctx
, status
,
406 NT_STATUS_OBJECT_NAME_COLLISION
, "BackupEventLogW failed");
408 cr
.in
.handle
= cr
.out
.handle
= &handle
;
410 torture_assert_ntstatus_ok(tctx
,
411 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
414 unknown0
.unknown0
= 0x005c;
415 unknown0
.unknown1
= 0x0001;
417 b
.in
.unknown0
= &unknown0
;
418 b
.in
.backup_logname
= &backup_filename
;
419 b
.in
.major_version
= 1;
420 b
.in
.minor_version
= 1;
421 b
.out
.handle
= &backup_handle
;
423 status
= dcerpc_eventlog_OpenBackupEventLogW(p
, tctx
, &b
);
425 torture_assert_ntstatus_ok(tctx
, status
, "OpenBackupEventLogW failed");
427 cr
.in
.handle
= cr
.out
.handle
= &backup_handle
;
429 torture_assert_ntstatus_ok(tctx
,
430 dcerpc_eventlog_CloseEventLog(p
, tctx
, &cr
),
431 "CloseEventLog failed");
436 struct torture_suite
*torture_rpc_eventlog(TALLOC_CTX
*mem_ctx
)
438 struct torture_suite
*suite
;
439 struct torture_rpc_tcase
*tcase
;
440 struct torture_test
*test
;
442 suite
= torture_suite_create(mem_ctx
, "EVENTLOG");
443 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "eventlog",
444 &ndr_table_eventlog
);
446 torture_rpc_tcase_add_test(tcase
, "OpenEventLog", test_OpenEventLog
);
447 test
= torture_rpc_tcase_add_test(tcase
, "ClearEventLog",
449 test
->dangerous
= true;
450 torture_rpc_tcase_add_test(tcase
, "GetNumRecords", test_GetNumRecords
);
451 torture_rpc_tcase_add_test(tcase
, "ReadEventLog", test_ReadEventLog
);
452 torture_rpc_tcase_add_test(tcase
, "ReportEventLog", test_ReportEventLog
);
453 torture_rpc_tcase_add_test(tcase
, "FlushEventLog", test_FlushEventLog
);
454 torture_rpc_tcase_add_test(tcase
, "GetLogIntormation", test_GetLogInformation
);
455 torture_rpc_tcase_add_test(tcase
, "BackupLog", test_BackupLog
);