diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c index 3e8010d2c2b9..65f0294fa6c0 100644 --- a/source4/torture/rpc/iremotewinspool.c +++ b/source4/torture/rpc/iremotewinspool.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. test suite for iremotewinspool rpc operations - Copyright (C) Guenther Deschner 2013 + Copyright (C) Guenther Deschner 2013,2023 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 @@ -822,6 +822,108 @@ static bool test_OpenPrinter(struct torture_context *tctx, return true; } +static bool test_object_one_uuid(struct torture_context *tctx, + const struct GUID *object_uuid, + NTSTATUS expected_status, + uint32_t expected_fault_code) +{ + const char *printer_name; + struct spoolss_UserLevel1 client_info; + struct dcerpc_binding *binding; + struct dcerpc_pipe *p; + struct policy_handle server_handle; + + torture_comment(tctx, "Testing with object_uuid: %s\n", + GUID_string(tctx, object_uuid)); + + torture_assert_ntstatus_ok(tctx, + torture_rpc_binding(tctx, &binding), + "failed to retrieve torture binding"); + + if (object_uuid) { + torture_assert_ntstatus_ok(tctx, + dcerpc_binding_set_object(binding, *object_uuid), + "failed to set object_uuid"); + } + + torture_assert_ntstatus_ok(tctx, + torture_rpc_connection_with_binding(tctx, binding, &p, + &ndr_table_iremotewinspool), + "Error connecting to server"); + + printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); + torture_assert(tctx, printer_name, "out of memory"); + + client_info = test_get_client_info(tctx, + WIN_7, 6, 1, "testclient_machine", "testclient_user"); + + torture_assert(tctx, + test_AsyncOpenPrinter_byprinter_expect(tctx, NULL, + p, + printer_name, + SEC_FLAG_MAXIMUM_ALLOWED, + client_info, + expected_status, + WERR_OK, + expected_fault_code, + &server_handle), + "failed to open printserver"); + if (NT_STATUS_IS_OK(expected_status)) { + test_AsyncClosePrinter_byhandle(tctx, NULL, p, &server_handle); + } + + talloc_free(p); + + return true; +} + +static bool test_object_uuid(struct torture_context *tctx, + void *private_data) +{ + struct GUID object_uuid; + + torture_assert(tctx, + test_object_one_uuid(tctx, NULL, + NT_STATUS_RPC_NOT_RPC_ERROR, + DCERPC_NCA_S_UNSUPPORTED_TYPE), + "failed to test NULL object uuid"); + + object_uuid = GUID_zero(); + torture_assert(tctx, + test_object_one_uuid(tctx, &object_uuid, + NT_STATUS_RPC_NOT_RPC_ERROR, + DCERPC_NCA_S_UNSUPPORTED_TYPE), + "failed to test zeroed object uuid"); + + object_uuid = GUID_random(); + torture_assert(tctx, + test_object_one_uuid(tctx, &object_uuid, + NT_STATUS_RPC_NOT_RPC_ERROR, + DCERPC_NCA_S_UNSUPPORTED_TYPE), + "failed to test random object uuid"); + + GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &object_uuid); + torture_assert(tctx, + test_object_one_uuid(tctx, &object_uuid, + NT_STATUS_OK, + 0), + "failed to test IREMOTEWINSPOOL_OBJECT_GUID"); + + torture_assert(tctx, + test_object_one_uuid(tctx, &ndr_table_spoolss.syntax_id.uuid, + NT_STATUS_RPC_NOT_RPC_ERROR, + DCERPC_NCA_S_UNSUPPORTED_TYPE), + "failed to test spoolss interface uuid"); + + torture_assert(tctx, + test_object_one_uuid(tctx, &ndr_table_iremotewinspool.syntax_id.uuid, + NT_STATUS_RPC_NOT_RPC_ERROR, + DCERPC_NCA_S_UNSUPPORTED_TYPE), + "failed to test iremotewinspool interface uuid"); + + return true; +} + struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "iremotewinspool"); @@ -851,5 +953,8 @@ struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx) torture_tcase_add_simple_test(tcase, "OpenPrinter", test_OpenPrinter); + tcase = torture_suite_add_tcase(suite, "protocol"); + torture_tcase_add_simple_test(tcase, "object_uuid", test_object_uuid); + return suite; } diff --git a/source4/torture/rpc/iremotewinspool_common.c b/source4/torture/rpc/iremotewinspool_common.c index 33dd469eef36..d4dd19ac3edb 100644 --- a/source4/torture/rpc/iremotewinspool_common.c +++ b/source4/torture/rpc/iremotewinspool_common.c @@ -51,21 +51,25 @@ struct spoolss_UserLevel1 test_get_client_info(struct torture_context *tctx, return level1; } -bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx, +bool test_AsyncOpenPrinter_byprinter_expect(struct torture_context *tctx, struct test_iremotewinspool_context *ctx, struct dcerpc_pipe *p, const char *printer_name, + uint32_t access_mask, struct spoolss_UserLevel1 cinfo, + NTSTATUS expected_status, + WERROR expected_result, + uint32_t expected_fault_code, struct policy_handle *handle) { struct dcerpc_binding_handle *b = p->binding_handle; struct spoolss_DevmodeContainer devmode_ctr; struct spoolss_UserLevelCtr client_info_ctr; - uint32_t access_mask = SERVER_ALL_ACCESS; struct winspool_AsyncOpenPrinter r; NTSTATUS status; bool ok = true; + ZERO_STRUCT(r); ZERO_STRUCT(devmode_ctr); client_info_ctr.level = 1; @@ -79,16 +83,34 @@ bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx, r.out.pHandle = handle; status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r); - torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncOpenPrinter failed"); - - torture_assert_werr_ok(tctx, r.out.result, + torture_assert_ntstatus_equal(tctx, status, expected_status, "AsyncOpenPrinter failed"); + torture_assert_werr_equal(tctx, r.out.result, expected_result, "AsyncOpenPrinter failed"); - -done: + torture_assert_u32_equal(tctx, p->last_fault_code, expected_fault_code, + "unexpected DCERPC fault code"); return ok; } +bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx, + struct test_iremotewinspool_context *ctx, + struct dcerpc_pipe *p, + const char *printer_name, + struct spoolss_UserLevel1 cinfo, + struct policy_handle *handle) +{ + return test_AsyncOpenPrinter_byprinter_expect(tctx, + ctx, + p, + printer_name, + SERVER_ALL_ACCESS, + cinfo, + NT_STATUS_OK, + WERR_OK, + 0, + handle); +} + bool test_get_environment(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, diff --git a/source4/torture/rpc/iremotewinspool_common.h b/source4/torture/rpc/iremotewinspool_common.h index fb6efd923fd5..5887416d014d 100644 --- a/source4/torture/rpc/iremotewinspool_common.h +++ b/source4/torture/rpc/iremotewinspool_common.h @@ -74,7 +74,16 @@ bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx, const char *printer_name, struct spoolss_UserLevel1 cinfo, struct policy_handle *handle); - +bool test_AsyncOpenPrinter_byprinter_expect(struct torture_context *tctx, + struct test_iremotewinspool_context *ctx, + struct dcerpc_pipe *p, + const char *printer_name, + uint32_t access_mask, + struct spoolss_UserLevel1 cinfo, + NTSTATUS exected_status, + WERROR exected_result, + uint32_t expected_fault_code, + struct policy_handle *handle); bool test_get_environment(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle,