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