summaryrefslogtreecommitdiffstats
path: root/source4/torture/rpc/iremotewinspool_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/rpc/iremotewinspool_common.c')
-rw-r--r--source4/torture/rpc/iremotewinspool_common.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/source4/torture/rpc/iremotewinspool_common.c b/source4/torture/rpc/iremotewinspool_common.c
new file mode 100644
index 0000000..d4dd19a
--- /dev/null
+++ b/source4/torture/rpc/iremotewinspool_common.c
@@ -0,0 +1,269 @@
+#include "includes.h"
+#include "torture/torture.h"
+#include "librpc/gen_ndr/ndr_winspool.h"
+#include "librpc/gen_ndr/ndr_winspool_c.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "torture/rpc/torture_rpc.h"
+#include "libcli/registry/util_reg.h"
+#include "torture/rpc/iremotewinspool_common.h"
+#include "lib/printer_driver/printer_driver.h"
+
+void init_winreg_String(struct winreg_String *name, const char *s)
+{
+ name->name = s;
+ if (s != NULL) {
+ name->name_len = 2 * (strlen_m(s) + 1);
+ name->name_size = name->name_len;
+ } else {
+ name->name_len = 0;
+ name->name_size = 0;
+ }
+}
+
+struct spoolss_UserLevel1 test_get_client_info(struct torture_context *tctx,
+ enum client_os_version os,
+ enum spoolss_MajorVersion major_number,
+ enum spoolss_MinorVersion minor_number,
+ const char *machine,
+ const char *user)
+{
+ struct spoolss_UserLevel1 level1;
+
+ level1.size = 28;
+ level1.client = talloc_asprintf(tctx, "\\\\%s", machine);
+ level1.user = user;
+ level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
+ level1.major = major_number;
+ level1.minor = minor_number;
+
+ if (os == WIN_SERVER_2016 || os == WIN_10) {
+ level1.build = 10586;
+ } else if (os == WIN_SERVER_2012 || os == WIN_8) {
+ level1.build = 9200;
+ } else if (os == WIN_SERVER_2008R2 || os == WIN_7) {
+ level1.build = 7007;
+ } else if (os == WIN_SERVER_2008 || os == WIN_VISTA) {
+ level1.build = 6000;
+ } else if (os == WIN_2000) {
+ level1.build = 1382;
+ }
+
+ return level1;
+}
+
+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;
+ struct winspool_AsyncOpenPrinter r;
+ NTSTATUS status;
+ bool ok = true;
+
+ ZERO_STRUCT(r);
+ ZERO_STRUCT(devmode_ctr);
+
+ client_info_ctr.level = 1;
+ client_info_ctr.user_info.level1 = &cinfo;
+
+ r.in.pPrinterName = printer_name;
+ r.in.pDatatype = NULL;
+ r.in.pDevModeContainer = &devmode_ctr;
+ r.in.AccessRequired = access_mask;
+ r.in.pClientInfo = &client_info_ctr;
+ r.out.pHandle = handle;
+
+ status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
+ torture_assert_ntstatus_equal(tctx, status, expected_status, "AsyncOpenPrinter failed");
+ torture_assert_werr_equal(tctx, r.out.result, expected_result,
+ "AsyncOpenPrinter failed");
+ 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,
+ const char **architecture)
+{
+ DATA_BLOB blob;
+ enum winreg_Type type;
+ uint8_t *data;
+ uint32_t needed;
+ bool ok;
+
+ ok = test_AsyncGetPrinterData_args(tctx, b, handle, "Architecture", &type, &data, &needed);
+ torture_assert(tctx, ok, "failed to get Architecture");
+
+ torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
+
+ blob = data_blob_const(data, needed);
+
+ torture_assert(tctx,
+ pull_reg_sz(tctx, &blob, architecture),
+ "failed to pull environment");
+
+ return true;
+}
+
+bool test_AsyncClosePrinter_byhandle(struct torture_context *tctx,
+ struct test_iremotewinspool_context *ctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ struct winspool_AsyncClosePrinter r;
+ NTSTATUS status;
+ bool ok = true;
+
+ r.in.phPrinter = handle;
+ r.out.phPrinter = handle;
+
+ status = dcerpc_winspool_AsyncClosePrinter_r(b, tctx, &r);
+ torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncClosePrinter failed");
+
+ torture_assert_werr_ok(tctx, r.out.result,
+ "AsyncClosePrinter failed");
+
+done:
+
+ return ok;
+}
+
+static bool test_AsyncGetPrinterData_checktype(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle,
+ const char *value_name,
+ enum winreg_Type *expected_type,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
+{
+ struct winspool_AsyncGetPrinterData r;
+ enum winreg_Type type;
+ uint32_t needed;
+ NTSTATUS status;
+ bool ok = true;
+
+ r.in.hPrinter = *handle;
+ r.in.pValueName = value_name;
+ r.in.nSize = 0;
+ r.out.pType = &type;
+ r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
+ r.out.pcbNeeded = &needed;
+
+ torture_comment(tctx, "Testing AsyncGetPrinterData(%s)\n",
+ r.in.pValueName);
+
+ status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
+ torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
+ if (expected_type) {
+ torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
+ }
+ r.in.nSize = needed;
+ r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
+
+ status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
+ torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
+ }
+
+ torture_assert_werr_ok(tctx, r.out.result,
+ "AsyncGetPrinterData failed");
+
+ if (type_p) {
+ *type_p = type;
+ }
+
+ if (data_p) {
+ *data_p = r.out.pData;
+ }
+
+ if (needed_p) {
+ *needed_p = needed;
+ }
+
+done:
+
+ return ok;
+}
+
+bool test_AsyncGetPrinterData_args(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle,
+ const char *value_name,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
+{
+ return test_AsyncGetPrinterData_checktype(tctx, b, handle,
+ value_name,
+ NULL,
+ type_p, data_p, needed_p);
+}
+
+/* Parse a driver inf file */
+bool parse_inf_driver(struct torture_context *tctx,
+ const char *driver_name,
+ const char *abs_inf_path,
+ const char *driver_arch,
+ const char *core_driver_inf,
+ struct spoolss_AddDriverInfo8 **_parsed_dinfo)
+{
+ struct spoolss_AddDriverInfo8 *drv_info;
+ const char *source_disk_name = NULL;
+ NTSTATUS status;
+ bool ok = true;
+
+ drv_info = talloc_zero(tctx, struct spoolss_AddDriverInfo8);
+ torture_assert_not_null_goto(tctx, drv_info, ok, done, "Cannot allocate memory");
+
+ status = driver_inf_parse(tctx,
+ core_driver_inf,
+ abs_inf_path,
+ driver_arch,
+ driver_name,
+ drv_info,
+ &source_disk_name);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_DRIVER_INTERNAL_ERROR)) {
+ torture_comment(tctx, "--- Verify the correct torture option:driver_name is provided\n");
+ }
+ torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "Failed to parse driver inf\n");
+
+ *_parsed_dinfo = drv_info;
+done:
+ return ok;
+}