Unix SMB/CIFS implementation.
test suite for eventlog rpc operations
- Copyright (C) Tim Potter 2003
+ Copyright (C) Tim Potter 2003,2005
Copyright (C) Jelmer Vernooij 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "torture/torture.h"
#include "librpc/gen_ndr/ndr_eventlog.h"
+#include "librpc/gen_ndr/ndr_eventlog_c.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
+#include "torture/rpc/rpc.h"
+#include "param/param.h"
-static void init_eventlog_String(struct eventlog_String *name, const char *s)
+static void init_lsa_String(struct lsa_String *name, const char *s)
{
- name->name = s;
- name->name_len = 2*strlen_m(s);
- name->name_size = name->name_len;
+ name->string = s;
+ name->length = 2*strlen_m(s);
+ name->size = name->length;
}
-static BOOL test_GetNumRecords(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle)
+static bool get_policy_handle(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct eventlog_OpenEventLogW r;
+ struct eventlog_OpenUnknown0 unknown0;
+ struct lsa_String logname, servername;
+
+ unknown0.unknown0 = 0x005c;
+ unknown0.unknown1 = 0x0001;
+
+ r.in.unknown0 = &unknown0;
+ init_lsa_String(&logname, "dns server");
+ init_lsa_String(&servername, NULL);
+ r.in.logname = &logname;
+ r.in.servername = &servername;
+ r.in.unknown2 = 0x00000001;
+ r.in.unknown3 = 0x00000001;
+ r.out.handle = handle;
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_OpenEventLogW(p, tctx, &r),
+ "OpenEventLog failed");
+
+ torture_assert_ntstatus_ok(tctx, r.out.result, "OpenEventLog failed");
+
+ return true;
+}
+
+
+
+static bool test_GetNumRecords(struct torture_context *tctx, struct dcerpc_pipe *p)
{
- NTSTATUS status;
struct eventlog_GetNumRecords r;
+ struct eventlog_CloseEventLog cr;
+ struct policy_handle handle;
+ uint32_t number = 0;
- printf("\ntesting GetNumRecords\n");
+ if (!get_policy_handle(tctx, p, &handle))
+ return false;
- r.in.handle = handle;
+ ZERO_STRUCT(r);
+ r.in.handle = &handle;
+ r.out.number = &number;
- status = dcerpc_eventlog_GetNumRecords(p, mem_ctx, &r);
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_GetNumRecords(p, tctx, &r),
+ "GetNumRecords failed");
- if (!NT_STATUS_IS_OK(status)) {
- printf("GetNumRecords failed - %s\n", nt_errstr(status));
- return False;
- }
+ torture_comment(tctx, "%d records\n", *r.out.number);
- printf("%d records\n", r.out.number);
+ cr.in.handle = cr.out.handle = &handle;
- return True;
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_CloseEventLog(p, tctx, &cr),
+ "CloseEventLog failed");
+ return true;
}
-static BOOL test_ReadEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, uint32_t offset)
+static bool test_ReadEventLog(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
{
NTSTATUS status;
struct eventlog_ReadEventLogW r;
+ struct eventlog_CloseEventLog cr;
+ struct policy_handle handle;
- printf("\ntesting ReadEventLog\n");
+ if (!get_policy_handle(tctx, p, &handle))
+ return false;
- r.in.flags = 0x0;
- r.in.offset = offset;
- r.in.handle = handle;
- r.in.number_of_bytes = 0x0;
+ ZERO_STRUCT(r);
+ r.in.offset = 0;
+ r.in.handle = &handle;
+ r.in.flags = EVENTLOG_BACKWARDS_READ|EVENTLOG_SEQUENTIAL_READ;
- status = dcerpc_eventlog_ReadEventLogW(p, mem_ctx, &r);
+ while (1) {
+ DATA_BLOB blob;
+ struct eventlog_Record rec;
+ struct ndr_pull *ndr;
+ enum ndr_err_code ndr_err;
+ uint32_t sent_size = 0;
+ uint32_t real_size = 0;
- if (!NT_STATUS_IS_OK(status)) {
- printf("ReadEventLog failed - %s\n", nt_errstr(status));
- return False;
- }
+ /* Read first for number of bytes in record */
- if (NT_STATUS_IS_OK(r.out.result)) {
- /* No data */
- return True;
- }
+ r.in.number_of_bytes = 0;
+ r.out.data = NULL;
+ r.out.sent_size = &sent_size;
+ r.out.real_size = &real_size;
- if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_BUFFER_TOO_SMALL)) {
- printf("ReadEventLog failed - %s\n", nt_errstr(r.out.result));
- return False;
- }
+ status = dcerpc_eventlog_ReadEventLogW(p, tctx, &r);
- r.in.number_of_bytes = r.out.real_size;
+ if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_END_OF_FILE)) {
+ break;
+ }
- status = dcerpc_eventlog_ReadEventLogW(p, mem_ctx, &r);
+ torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL,
+ "ReadEventLog failed");
+
+ /* Now read the actual record */
- if (!NT_STATUS_IS_OK(status)) {
- printf("ReadEventLog failed - %s\n", nt_errstr(status));
- return False;
- }
+ r.in.number_of_bytes = *r.out.real_size;
+ r.out.data = talloc_array(tctx, uint8_t, r.in.number_of_bytes);
+ status = dcerpc_eventlog_ReadEventLogW(p, tctx, &r);
- return True;
-}
+ torture_assert_ntstatus_ok(tctx, status, "ReadEventLog failed");
+
+ /* Decode a user-marshalled record */
-BOOL test_CloseEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle)
-{
- NTSTATUS status;
- struct eventlog_CloseEventLog r;
+ blob.length = *r.out.sent_size;
+ blob.data = talloc_steal(tctx, r.out.data);
+
+ ndr = ndr_pull_init_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx));
- r.in.handle = r.out.handle = handle;
+ ndr_err = ndr_pull_eventlog_Record(
+ ndr, NDR_SCALARS|NDR_BUFFERS, &rec);
+ status = ndr_map_error2ntstatus(ndr_err);
- printf("Testing CloseEventLog\n");
+ NDR_PRINT_DEBUG(eventlog_Record, &rec);
- status = dcerpc_eventlog_CloseEventLog(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- printf("CloseEventLog failed - %s\n", nt_errstr(status));
- return False;
+ torture_assert_ntstatus_ok(tctx, status,
+ "ReadEventLog failed parsing event log record");
+
+ r.in.offset++;
}
- return True;
+ cr.in.handle = cr.out.handle = &handle;
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_CloseEventLog(p, tctx, &cr),
+ "CloseEventLog failed");
+
+ return true;
}
-static BOOL test_OpenEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle)
+static bool test_FlushEventLog(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
{
- NTSTATUS status;
- struct eventlog_OpenEventLogW r;
- struct eventlog_OpenUnknown0 unknown0;
+ struct eventlog_FlushEventLog r;
+ struct eventlog_CloseEventLog cr;
+ struct policy_handle handle;
- printf("\ntesting OpenEventLog\n");
+ if (!get_policy_handle(tctx, p, &handle))
+ return false;
- unknown0.unknown0 = 0x005c;
- unknown0.unknown1 = 0x0001;
-
- r.in.unknown0 = &unknown0;
- init_eventlog_String(&r.in.source, "system");
- init_eventlog_String(&r.in.unknown1, NULL);
- r.in.unknown2 = 0x00000001;
- r.in.unknown3 = 0x00000001;
- r.out.handle = handle;
+ r.in.handle = &handle;
- status = dcerpc_eventlog_OpenEventLogW(p, mem_ctx, &r);
+ /* Huh? Does this RPC always return access denied? */
+ torture_assert_ntstatus_equal(tctx,
+ dcerpc_eventlog_FlushEventLog(p, tctx, &r),
+ NT_STATUS_ACCESS_DENIED,
+ "FlushEventLog failed");
- if (!NT_STATUS_IS_OK(status)) {
- printf("OpenEventLog failed - %s\n", nt_errstr(status));
- return False;
- }
+ cr.in.handle = cr.out.handle = &handle;
- if (!NT_STATUS_IS_OK(r.out.result)) {
- printf("OpenEventLog failed - %s\n", nt_errstr(r.out.result));
- return False;
- }
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_CloseEventLog(p, tctx, &cr),
+ "CloseEventLog failed");
- return True;
+ return true;
}
-BOOL torture_rpc_eventlog(void)
+static bool test_ClearEventLog(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
{
- NTSTATUS status;
- struct dcerpc_pipe *p;
+ struct eventlog_ClearEventLogW r;
+ struct eventlog_CloseEventLog cr;
struct policy_handle handle;
- TALLOC_CTX *mem_ctx;
- BOOL ret = True;
- mem_ctx = talloc_init("torture_rpc_atsvc");
+ if (!get_policy_handle(tctx, p, &handle))
+ return false;
- status = torture_rpc_connection(&p,
- DCERPC_EVENTLOG_NAME,
- DCERPC_EVENTLOG_UUID,
- DCERPC_EVENTLOG_VERSION);
- if (!NT_STATUS_IS_OK(status)) {
- return False;
- }
+ r.in.handle = &handle;
+ r.in.backupfile = NULL;
- if (!test_OpenEventLog(p, mem_ctx, &handle)) {
- return False;
- }
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_ClearEventLogW(p, tctx, &r),
+ "ClearEventLog failed");
+
+ cr.in.handle = cr.out.handle = &handle;
- test_GetNumRecords(p, mem_ctx, &handle);
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_CloseEventLog(p, tctx, &cr),
+ "CloseEventLog failed");
- test_ReadEventLog(p, mem_ctx, &handle, 0);
+ return true;
+}
+
+static bool test_OpenEventLog(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ struct policy_handle handle;
+ struct eventlog_CloseEventLog cr;
- test_CloseEventLog(p, mem_ctx, &handle);
+ if (!get_policy_handle(tctx, p, &handle))
+ return false;
- talloc_destroy(mem_ctx);
+ cr.in.handle = cr.out.handle = &handle;
- torture_rpc_close(p);
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_eventlog_CloseEventLog(p, tctx, &cr),
+ "CloseEventLog failed");
- return ret;
+ return true;
+}
+
+struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite;
+ struct torture_rpc_tcase *tcase;
+ struct torture_test *test;
+
+ suite = torture_suite_create(mem_ctx, "EVENTLOG");
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "eventlog",
+ &ndr_table_eventlog);
+
+ torture_rpc_tcase_add_test(tcase, "OpenEventLog", test_OpenEventLog);
+ test = torture_rpc_tcase_add_test(tcase, "ClearEventLog",
+ test_ClearEventLog);
+ test->dangerous = true;
+ torture_rpc_tcase_add_test(tcase, "GetNumRecords", test_GetNumRecords);
+ torture_rpc_tcase_add_test(tcase, "ReadEventLog", test_ReadEventLog);
+ torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog);
+
+ return suite;
}