2 Unix SMB/CIFS implementation.
3 test suite for iremotewinspool rpc operations
5 Copyright (C) Guenther Deschner 2013
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "torture/torture.h"
23 #include "librpc/gen_ndr/ndr_winspool.h"
24 #include "librpc/gen_ndr/ndr_winspool_c.h"
25 #include "librpc/gen_ndr/ndr_spoolss_c.h"
26 #include "torture/rpc/torture_rpc.h"
27 #include "libcli/registry/util_reg.h"
29 struct test_iremotewinspool_context {
30 struct GUID object_uuid;
31 struct dcerpc_pipe *iremotewinspool_pipe;
32 struct policy_handle server_handle;
33 const char *environment;
36 enum client_os_version
49 static struct spoolss_UserLevel1 test_get_client_info(struct torture_context *tctx,
50 enum client_os_version os,
51 enum spoolss_MajorVersion major_number,
52 enum spoolss_MinorVersion minor_number)
54 struct spoolss_UserLevel1 level1;
57 level1.client = talloc_asprintf(tctx, "\\\\%s", "mthelena");
59 level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
60 level1.major = major_number;
61 level1.minor = minor_number;
72 case WIN_SERVER_2008R2:
90 static bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx,
91 struct test_iremotewinspool_context *ctx,
92 struct dcerpc_pipe *p,
93 const char *printer_name,
94 struct spoolss_UserLevel1 cinfo,
95 struct policy_handle *handle)
97 struct dcerpc_binding_handle *b = p->binding_handle;
98 struct spoolss_DevmodeContainer devmode_ctr;
99 struct spoolss_UserLevelCtr client_info_ctr;
100 uint32_t access_mask = SERVER_ALL_ACCESS;
101 struct winspool_AsyncOpenPrinter r;
103 ZERO_STRUCT(devmode_ctr);
105 client_info_ctr.level = 1;
106 client_info_ctr.user_info.level1 = &cinfo;
108 r.in.pPrinterName = printer_name;
109 r.in.pDatatype = NULL;
110 r.in.pDevModeContainer = &devmode_ctr;
111 r.in.AccessRequired = access_mask;
112 r.in.pClientInfo = &client_info_ctr;
113 r.out.pHandle = handle;
115 torture_assert_ntstatus_ok(tctx,
116 dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r),
117 "AsyncOpenPrinter failed");
118 torture_assert_werr_ok(tctx, r.out.result,
119 "AsyncOpenPrinter failed");
124 static bool test_AsyncClosePrinter_byhandle(struct torture_context *tctx,
125 struct test_iremotewinspool_context *ctx,
126 struct dcerpc_pipe *p,
127 struct policy_handle *handle)
129 struct dcerpc_binding_handle *b = p->binding_handle;
131 struct winspool_AsyncClosePrinter r;
133 r.in.phPrinter = handle;
134 r.out.phPrinter = handle;
136 torture_assert_ntstatus_ok(tctx,
137 dcerpc_winspool_AsyncClosePrinter_r(b, tctx, &r),
138 "AsyncClosePrinter failed");
139 torture_assert_werr_ok(tctx, r.out.result,
140 "AsyncClosePrinter failed");
145 static bool test_AsyncGetPrinterData_checktype(struct torture_context *tctx,
146 struct dcerpc_binding_handle *b,
147 struct policy_handle *handle,
148 const char *value_name,
149 enum winreg_Type *expected_type,
150 enum winreg_Type *type_p,
154 struct winspool_AsyncGetPrinterData r;
155 enum winreg_Type type;
158 r.in.hPrinter = *handle;
159 r.in.pValueName = value_name;
162 r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
163 r.out.pcbNeeded = &needed;
165 torture_comment(tctx, "Testing AsyncGetPrinterData(%s)\n",
168 torture_assert_ntstatus_ok(tctx,
169 dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r),
170 "AsyncGetPrinterData failed");
172 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
174 torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
177 r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
179 torture_assert_ntstatus_ok(tctx,
180 dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r),
181 "AsyncGetPrinterData failed");
184 torture_assert_werr_ok(tctx, r.out.result,
185 "AsyncGetPrinterData failed");
192 *data_p = r.out.pData;
202 static bool test_AsyncGetPrinterData_args(struct torture_context *tctx,
203 struct dcerpc_binding_handle *b,
204 struct policy_handle *handle,
205 const char *value_name,
206 enum winreg_Type *type_p,
210 return test_AsyncGetPrinterData_checktype(tctx, b, handle,
213 type_p, data_p, needed_p);
216 static bool test_get_environment(struct torture_context *tctx,
217 struct dcerpc_binding_handle *b,
218 struct policy_handle *handle,
219 const char **architecture)
222 enum winreg_Type type;
227 test_AsyncGetPrinterData_args(tctx, b, handle, "Architecture", &type, &data, &needed),
228 "failed to get Architecture");
230 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
232 blob = data_blob_const(data, needed);
235 pull_reg_sz(tctx, &blob, architecture),
236 "failed to pull environment");
241 static bool torture_rpc_iremotewinspool_setup_common(struct torture_context *tctx,
242 struct test_iremotewinspool_context *t)
244 const char *printer_name;
245 struct spoolss_UserLevel1 client_info;
246 struct dcerpc_binding *binding;
248 torture_assert_ntstatus_ok(tctx,
249 GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &t->object_uuid),
250 "failed to parse GUID");
252 torture_assert_ntstatus_ok(tctx,
253 torture_rpc_binding(tctx, &binding),
254 "failed to retrieve torture binding");
256 torture_assert_ntstatus_ok(tctx,
257 dcerpc_binding_set_object(binding, t->object_uuid),
258 "failed to set object_uuid");
260 torture_assert_ntstatus_ok(tctx,
261 torture_rpc_connection_with_binding(tctx, binding, &t->iremotewinspool_pipe, &ndr_table_iremotewinspool),
262 "Error connecting to server");
264 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(t->iremotewinspool_pipe));
266 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
269 test_AsyncOpenPrinter_byprinter(tctx, t,
270 t->iremotewinspool_pipe, printer_name,
271 client_info, &t->server_handle),
272 "failed to open printserver");
274 test_get_environment(tctx,
275 t->iremotewinspool_pipe->binding_handle,
276 &t->server_handle, &t->environment),
277 "failed to get environment");
282 static bool torture_rpc_iremotewinspool_setup(struct torture_context *tctx,
285 struct test_iremotewinspool_context *t;
287 *data = t = talloc_zero(tctx, struct test_iremotewinspool_context);
289 return torture_rpc_iremotewinspool_setup_common(tctx, t);
292 static bool torture_rpc_iremotewinspool_teardown_common(struct torture_context *tctx,
293 struct test_iremotewinspool_context *t)
296 test_AsyncClosePrinter_byhandle(tctx, t, t->iremotewinspool_pipe, &t->server_handle);
301 static bool torture_rpc_iremotewinspool_teardown(struct torture_context *tctx,
304 struct test_iremotewinspool_context *t = talloc_get_type(data, struct test_iremotewinspool_context);
307 ret = torture_rpc_iremotewinspool_teardown_common(tctx, t);
313 static bool test_AsyncClosePrinter(struct torture_context *tctx,
316 struct test_iremotewinspool_context *ctx =
317 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
319 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
320 const char *printer_name;
321 struct spoolss_UserLevel1 client_info;
322 struct policy_handle handle;
324 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
326 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
329 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
330 "failed to test AsyncOpenPrinter");
333 test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle),
334 "failed to test AsyncClosePrinter");
339 static bool test_AsyncOpenPrinter(struct torture_context *tctx,
342 struct test_iremotewinspool_context *ctx =
343 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
345 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
346 const char *printer_name;
347 struct spoolss_UserLevel1 client_info;
348 struct policy_handle handle;
350 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
352 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
355 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
356 "failed to test AsyncOpenPrinter");
358 test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
364 * Validate the result of AsyncOpenPrinter calls based on client info
365 * build number. Windows Server 2016 rejects an advertised build
366 * number less than 6000(Windows Vista and Windows Server 2008, or older)
368 static bool test_AsyncOpenPrinterValidateBuildNumber(struct torture_context *tctx,
371 struct test_iremotewinspool_context *ctx =
372 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
374 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
375 const char *printer_name;
376 struct spoolss_UserLevel1 client_info;
377 struct policy_handle handle;
378 struct dcerpc_binding_handle *b = p->binding_handle;
379 struct spoolss_DevmodeContainer devmode_ctr;
380 struct spoolss_UserLevelCtr client_info_ctr = {
383 uint32_t access_mask = SERVER_ALL_ACCESS;
384 struct winspool_AsyncOpenPrinter r;
388 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
389 torture_assert_not_null(tctx, printer_name, "Cannot allocate memory");
391 /* fail with Windows 2000 build number */
392 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
394 ZERO_STRUCT(devmode_ctr);
396 client_info_ctr.user_info.level1 = &client_info;
398 r.in.pPrinterName = printer_name;
399 r.in.pDatatype = NULL;
400 r.in.pDevModeContainer = &devmode_ctr;
401 r.in.AccessRequired = access_mask;
402 r.in.pClientInfo = &client_info_ctr;
403 r.out.pHandle = &handle;
405 status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
406 torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
407 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
408 "AsyncOpenPrinter should have failed");
410 /* succeed with Windows 7 build number */
411 client_info = test_get_client_info(tctx, WIN_7, 3, SPOOLSS_MINOR_VERSION_0);
412 client_info_ctr.user_info.level1 = &client_info;
413 r.in.pClientInfo = &client_info_ctr;
415 status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
416 torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
417 torture_assert_werr_ok(tctx, r.out.result,
418 "AsyncOpenPrinter failed");
420 ok = test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
421 torture_assert(tctx, ok, "failed to AsyncClosePrinter handle");
427 static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct torture_context *tctx)
429 struct spoolss_NotifyOption *o;
431 o = talloc_zero(tctx, struct spoolss_NotifyOption);
437 o->flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
440 o->types = talloc_zero_array(o, struct spoolss_NotifyOptionType, o->count);
441 if (o->types == NULL) {
446 o->types[0].type = PRINTER_NOTIFY_TYPE;
447 o->types[0].count = 1;
448 o->types[0].fields = talloc_array(o->types, union spoolss_Field, o->types[0].count);
449 if (o->types[0].fields == NULL) {
453 o->types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
455 o->types[1].type = JOB_NOTIFY_TYPE;
456 o->types[1].count = 1;
457 o->types[1].fields = talloc_array(o->types, union spoolss_Field, o->types[1].count);
458 if (o->types[1].fields == NULL) {
462 o->types[1].fields[0].field = JOB_NOTIFY_FIELD_MACHINE_NAME;
467 static bool test_SyncUnRegisterForRemoteNotifications_args(struct torture_context *tctx,
468 struct dcerpc_pipe *p,
469 struct policy_handle *notify_handle)
471 struct winspool_SyncUnRegisterForRemoteNotifications r;
472 struct dcerpc_binding_handle *b = p->binding_handle;
474 r.in.phRpcHandle = notify_handle;
475 r.out.phRpcHandle = notify_handle;
477 torture_assert_ntstatus_ok(tctx,
478 dcerpc_winspool_SyncUnRegisterForRemoteNotifications_r(b, tctx, &r),
479 "SyncUnRegisterForRemoteNotifications failed");
480 torture_assert_hresult_ok(tctx, r.out.result,
481 "SyncUnRegisterForRemoteNotifications failed");
486 static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
487 struct dcerpc_pipe *p,
488 struct policy_handle *server_handle,
489 struct policy_handle *notify_handle);
491 static bool test_SyncUnRegisterForRemoteNotifications(struct torture_context *tctx,
494 struct test_iremotewinspool_context *ctx =
495 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
496 struct policy_handle notify_handle;
499 test_SyncRegisterForRemoteNotifications_args(tctx,
500 ctx->iremotewinspool_pipe,
503 "failed to test SyncRegisterForRemoteNotifications");
506 test_SyncUnRegisterForRemoteNotifications_args(tctx,
507 ctx->iremotewinspool_pipe,
509 "failed to test UnSyncRegisterForRemoteNotifications");
514 static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
515 struct dcerpc_pipe *p,
516 struct policy_handle *server_handle,
517 struct policy_handle *notify_handle)
519 struct dcerpc_binding_handle *b = p->binding_handle;
521 struct winspool_SyncRegisterForRemoteNotifications r;
522 struct winspool_PrintPropertiesCollection NotifyFilter;
523 struct winspool_PrintNamedProperty *c;
524 struct spoolss_NotifyOption *options;
526 ZERO_STRUCT(NotifyFilter);
528 options = setup_printserver_NotifyOption(tctx);
529 torture_assert(tctx, options, "out of memory");
531 c = talloc_zero_array(tctx, struct winspool_PrintNamedProperty, 4);
532 torture_assert(tctx, c, "out of memory");
534 c[0].propertyName = "RemoteNotifyFilter Flags";
535 c[0].propertyValue.PropertyType = winspool_PropertyTypeInt32;
536 c[0].propertyValue.value.propertyInt32 = 0xff;
538 c[1].propertyName = "RemoteNotifyFilter Options";
539 c[1].propertyValue.PropertyType = winspool_PropertyTypeInt32;
540 c[1].propertyValue.value.propertyInt32 = 0;
542 c[2].propertyName = "RemoteNotifyFilter Color";
543 c[2].propertyValue.PropertyType = winspool_PropertyTypeInt32;
544 c[2].propertyValue.value.propertyInt32 = 0;
546 c[3].propertyName = "RemoteNotifyFilter NotifyOptions";
547 c[3].propertyValue.PropertyType = winspool_PropertyTypeNotificationOptions;
548 c[3].propertyValue.value.propertyOptionsContainer.pOptions = options;
550 NotifyFilter.numberOfProperties = 4;
551 NotifyFilter.propertiesCollection = c;
553 r.in.hPrinter = *server_handle;
554 r.in.pNotifyFilter = &NotifyFilter;
555 r.out.phRpcHandle = notify_handle;
557 torture_assert_ntstatus_ok(tctx,
558 dcerpc_winspool_SyncRegisterForRemoteNotifications_r(b, tctx, &r),
559 "SyncRegisterForRemoteNotifications failed");
560 torture_assert_hresult_ok(tctx, r.out.result,
561 "SyncRegisterForRemoteNotifications failed");
566 static bool test_SyncRegisterForRemoteNotifications(struct torture_context *tctx,
569 struct test_iremotewinspool_context *ctx =
570 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
571 struct policy_handle notify_handle;
574 test_SyncRegisterForRemoteNotifications_args(tctx,
575 ctx->iremotewinspool_pipe,
578 "failed to test SyncRegisterForRemoteNotifications");
580 test_SyncUnRegisterForRemoteNotifications_args(tctx, ctx->iremotewinspool_pipe, ¬ify_handle);
585 static bool test_AsyncUploadPrinterDriverPackage(struct torture_context *tctx,
588 struct test_iremotewinspool_context *ctx =
589 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
591 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
592 struct dcerpc_binding_handle *b = p->binding_handle;
594 struct winspool_AsyncUploadPrinterDriverPackage r;
595 uint32_t pcchDestInfPath = 0;
597 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
598 r.in.pszInfPath = "";
599 r.in.pszEnvironment = "";
601 r.in.pszDestInfPath = NULL;
602 r.in.pcchDestInfPath = &pcchDestInfPath;
603 r.out.pszDestInfPath = NULL;
604 r.out.pcchDestInfPath = &pcchDestInfPath;
606 torture_assert_ntstatus_ok(tctx,
607 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
608 "AsyncUploadPrinterDriverPackage failed");
609 torture_assert_hresult_equal(tctx, r.out.result, HRES_E_INVALIDARG,
610 "AsyncUploadPrinterDriverPackage failed");
612 pcchDestInfPath = 260;
613 r.in.pszDestInfPath = talloc_zero_array(tctx, uint16_t, pcchDestInfPath);
614 r.out.pszDestInfPath = talloc_zero_array(tctx, uint16_t, pcchDestInfPath);
616 torture_assert_ntstatus_ok(tctx,
617 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
618 "AsyncUploadPrinterDriverPackage failed");
619 torture_assert_werr_equal(tctx,
620 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
621 "AsyncUploadPrinterDriverPackage failed");
623 r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
625 torture_assert_ntstatus_ok(tctx,
626 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
627 "AsyncUploadPrinterDriverPackage failed");
628 torture_assert_werr_equal(tctx,
629 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
630 "AsyncUploadPrinterDriverPackage failed");
632 r.in.pszInfPath = "\\\\mthelena\\print$\\x64\\{BD443844-ED00-4D96-8CAE-95E49492312A}\\prnbrcl1.inf";
634 torture_assert_ntstatus_ok(tctx,
635 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
636 "AsyncUploadPrinterDriverPackage failed");
637 torture_assert_werr_equal(tctx,
638 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
639 "AsyncUploadPrinterDriverPackage failed");
644 static bool test_AsyncEnumPrinters(struct torture_context *tctx,
647 struct test_iremotewinspool_context *ctx =
648 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
650 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
651 struct dcerpc_binding_handle *b = p->binding_handle;
653 struct winspool_AsyncEnumPrinters r;
654 uint32_t levels[] = { 1, 2, /*3,*/ 4, 5 };
660 for (i = 0; i < ARRAY_SIZE(levels); i++) {
662 r.in.Flags = PRINTER_ENUM_LOCAL;
664 r.in.Level = levels[i];
666 r.in.pPrinterEnum = NULL;
667 r.out.pcbNeeded = &needed;
668 r.out.pcReturned = &returned;
669 r.out.pPrinterEnum = NULL;
671 torture_assert_ntstatus_ok(tctx,
672 dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
673 "AsyncEnumPrinters failed");
674 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
675 "AsyncEnumPrinters failed");
678 r.in.pPrinterEnum = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
679 r.out.pPrinterEnum = r.in.pPrinterEnum;
681 torture_assert_ntstatus_ok(tctx,
682 dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
683 "AsyncEnumPrinters failed");
684 torture_assert_werr_ok(tctx, r.out.result,
685 "AsyncEnumPrinters failed");
691 static bool test_AsyncGetPrinterData(struct torture_context *tctx,
694 struct test_iremotewinspool_context *ctx =
695 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
697 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
698 struct dcerpc_binding_handle *b = p->binding_handle;
708 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
710 &pType, &pData, &pcbNeeded),
711 "failed to check for MajorVersion");
713 torture_assert_int_equal(tctx, pcbNeeded, 4, "pcbNeeded");
714 torture_assert_int_equal(tctx, pType, REG_DWORD, "pType");
715 torture_assert_int_equal(tctx, IVAL(pData, 0), 3, "pData");
718 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
720 &pType, &pData, &pcbNeeded),
721 "failed to check for Architecture");
723 blob = data_blob_const(pData, pcbNeeded);
725 torture_assert_int_equal(tctx, pType, REG_SZ, "pType");
726 torture_assert(tctx, pull_reg_sz(tctx, &blob, &s), "");
727 ok = strequal(s, SPOOLSS_ARCHITECTURE_x64) || strequal(s, SPOOLSS_ARCHITECTURE_NT_X86);
728 torture_assert(tctx, ok, "unexpected architecture returned");
733 static bool test_AsyncCorePrinterDriverInstalled(struct torture_context *tctx,
736 struct test_iremotewinspool_context *ctx =
737 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
739 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
740 struct dcerpc_binding_handle *b = p->binding_handle;
742 struct winspool_AsyncCorePrinterDriverInstalled r;
743 int32_t pbDriverInstalled;
746 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
747 r.in.pszEnvironment = "";
748 r.in.CoreDriverGUID = GUID_zero();
749 r.in.ftDriverDate = 0;
750 r.in.dwlDriverVersion = 0;
751 r.out.pbDriverInstalled = &pbDriverInstalled;
753 torture_assert_ntstatus_ok(tctx,
754 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
755 "AsyncCorePrinterDriverInstalled failed");
756 torture_assert_werr_equal(tctx,
757 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
758 "AsyncCorePrinterDriverInstalled failed");
760 r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
762 torture_assert_ntstatus_ok(tctx,
763 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
764 "AsyncCorePrinterDriverInstalled failed");
765 torture_assert_hresult_ok(tctx, r.out.result,
766 "AsyncCorePrinterDriverInstalled failed");
767 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
768 "unexpected driver installed");
770 r.in.CoreDriverGUID = GUID_random();
772 torture_assert_ntstatus_ok(tctx,
773 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
774 "AsyncCorePrinterDriverInstalled failed");
775 torture_assert_hresult_ok(tctx, r.out.result,
776 "AsyncCorePrinterDriverInstalled failed");
777 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
778 "unexpected driver installed");
780 torture_assert_ntstatus_ok(tctx,
781 GUID_from_string(SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV, &guid), "");
783 r.in.CoreDriverGUID = guid;
785 torture_assert_ntstatus_ok(tctx,
786 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
787 "AsyncCorePrinterDriverInstalled failed");
788 torture_assert_hresult_ok(tctx, r.out.result,
789 "AsyncCorePrinterDriverInstalled failed");
790 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
791 "xps core driver not installed?");
793 r.in.dwlDriverVersion = 0xffffffff;
795 torture_assert_ntstatus_ok(tctx,
796 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
797 "AsyncCorePrinterDriverInstalled failed");
798 torture_assert_hresult_ok(tctx, r.out.result,
799 "AsyncCorePrinterDriverInstalled failed");
800 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
801 "xps core driver not installed?");
803 r.in.dwlDriverVersion = 1234;
805 torture_assert_ntstatus_ok(tctx,
806 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
807 "AsyncCorePrinterDriverInstalled failed");
808 torture_assert_hresult_ok(tctx, r.out.result,
809 "AsyncCorePrinterDriverInstalled failed");
810 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
811 "xps core driver not installed?");
813 r.in.ftDriverDate = unix_timespec_to_nt_time(timespec_current());
815 torture_assert_ntstatus_ok(tctx,
816 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
817 "AsyncCorePrinterDriverInstalled failed");
818 torture_assert_hresult_ok(tctx, r.out.result,
819 "AsyncCorePrinterDriverInstalled failed");
820 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
823 r.in.dwlDriverVersion = 0;
825 torture_assert_ntstatus_ok(tctx,
826 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
827 "AsyncCorePrinterDriverInstalled failed");
828 torture_assert_hresult_ok(tctx, r.out.result,
829 "AsyncCorePrinterDriverInstalled failed");
830 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
831 "unexpected driver installed");
836 static bool test_get_core_printer_drivers_arch_guid(struct torture_context *tctx,
837 struct dcerpc_pipe *p,
838 const char *architecture,
839 const char *guid_str,
840 const char **package_id)
842 struct winspool_AsyncGetCorePrinterDrivers r;
845 struct dcerpc_binding_handle *b = p->binding_handle;
847 s = talloc_zero_array(tctx, const char *, 2);
851 push_reg_multi_sz(tctx, &blob, s),
852 "push_reg_multi_sz failed");
854 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
855 r.in.pszEnvironment = architecture;
856 r.in.cchCoreDrivers = blob.length/2;
857 r.in.pszzCoreDriverDependencies = (uint16_t *)blob.data;
858 r.in.cCorePrinterDrivers = 1;
859 r.out.pCorePrinterDrivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.cCorePrinterDrivers);
861 torture_assert_ntstatus_ok(tctx,
862 dcerpc_winspool_AsyncGetCorePrinterDrivers_r(b, tctx, &r),
863 "winspool_AsyncCorePrinterDrivers failed");
864 torture_assert_hresult_ok(tctx, r.out.result,
865 "winspool_AsyncCorePrinterDrivers failed");
868 *package_id = r.out.pCorePrinterDrivers[0].szPackageID;
874 static bool test_AsyncDeletePrintDriverPackage(struct torture_context *tctx,
877 struct test_iremotewinspool_context *ctx =
878 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
880 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
881 struct dcerpc_binding_handle *b = p->binding_handle;
882 struct winspool_AsyncDeletePrinterDriverPackage r;
884 const char *architectures[] = {
885 /* SPOOLSS_ARCHITECTURE_NT_X86, */
886 SPOOLSS_ARCHITECTURE_x64
890 for (i=0; i < ARRAY_SIZE(architectures); i++) {
892 const char *package_id;
895 test_get_core_printer_drivers_arch_guid(tctx, p,
897 SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
899 "failed to get core printer driver");
901 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
902 r.in.pszEnvironment = "";
903 r.in.pszInfPath = "";
905 torture_comment(tctx, "Testing AsyncDeletePrinterDriverPackage(%s, %s, %s)\n",
906 r.in.pszServer, architectures[i], package_id);
908 torture_assert_ntstatus_ok(tctx,
909 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
910 "AsyncDeletePrinterDriverPackage failed");
911 torture_assert_werr_equal(tctx,
912 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_NOT_FOUND,
913 "AsyncDeletePrinterDriverPackage failed");
915 r.in.pszInfPath = package_id;
917 torture_assert_ntstatus_ok(tctx,
918 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
919 "AsyncDeletePrinterDriverPackage failed");
920 torture_assert_werr_equal(tctx,
921 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
922 "AsyncDeletePrinterDriverPackage failed");
924 r.in.pszEnvironment = architectures[i];
926 torture_assert_ntstatus_ok(tctx,
927 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
928 "AsyncDeletePrinterDriverPackage failed");
929 torture_assert_hresult_equal(tctx, r.out.result, HRES_E_ACCESSDENIED,
930 "AsyncDeletePrinterDriverPackage failed");
936 static bool test_AsyncGetPrinterDriverDirectory(struct torture_context *tctx,
939 struct test_iremotewinspool_context *ctx =
940 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
942 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
943 struct dcerpc_binding_handle *b = p->binding_handle;
944 struct winspool_AsyncGetPrinterDriverDirectory r;
949 r.in.pName = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
950 r.in.pEnvironment = ctx->environment;
953 r.in.pDriverDirectory = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
954 r.out.pcbNeeded = &pcbNeeded;
955 r.out.pDriverDirectory = r.in.pDriverDirectory;
957 torture_comment(tctx, "Testing AsyncGetPrinterDriverDirectory(%s, %s)\n",
958 r.in.pName, r.in.pEnvironment);
960 torture_assert_ntstatus_ok(tctx,
961 dcerpc_winspool_AsyncGetPrinterDriverDirectory_r(b, tctx, &r),
962 "AsyncGetPrinterDriverDirectory failed");
963 torture_assert_werr_ok(tctx, r.out.result,
964 "AsyncGetPrinterDriverDirectory failed");
966 blob = data_blob_const(r.out.pDriverDirectory, pcbNeeded);
969 pull_reg_sz(tctx, &blob, &s),
970 "failed to pull reg_sz");
972 torture_comment(tctx, "got: %s\n", s);
978 * Test if one can close a printserver handle that has been acquired via
979 * winspool_AsyncOpenPrinter with a spoolss_ClosePrinter operation.
982 static bool test_OpenPrinter(struct torture_context *tctx,
985 struct test_iremotewinspool_context *ctx =
986 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
988 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
989 const char *printer_name;
990 struct policy_handle handle;
991 struct dcerpc_pipe *s;
992 struct dcerpc_binding *binding;
993 struct spoolss_UserLevel1 client_info;
994 struct spoolss_ClosePrinter r;
996 torture_assert_ntstatus_ok(tctx,
997 torture_rpc_binding(tctx, &binding),
998 "failed to get binding");
1000 torture_assert_ntstatus_ok(tctx,
1001 dcerpc_binding_set_transport(binding, NCACN_NP),
1002 "failed to set ncacn_np transport");
1004 torture_assert_ntstatus_ok(tctx,
1005 dcerpc_binding_set_object(binding, GUID_zero()),
1006 "failed to set object uuid to zero");
1008 torture_assert_ntstatus_ok(tctx,
1009 torture_rpc_connection_with_binding(tctx, binding, &s, &ndr_table_spoolss),
1010 "failed to connect to spoolss");
1012 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1014 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
1016 torture_assert(tctx,
1017 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
1018 "failed to open printserver via winspool");
1021 r.in.handle = &handle;
1022 r.out.handle = &handle;
1024 torture_assert_ntstatus_equal(tctx,
1025 dcerpc_spoolss_ClosePrinter_r(s->binding_handle, tctx, &r),
1026 NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
1027 "ClosePrinter failed");
1034 struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx)
1036 struct torture_suite *suite = torture_suite_create(mem_ctx, "iremotewinspool");
1037 struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
1039 torture_tcase_set_fixture(tcase,
1040 torture_rpc_iremotewinspool_setup,
1041 torture_rpc_iremotewinspool_teardown);
1043 torture_tcase_add_simple_test(tcase, "AsyncOpenPrinter", test_AsyncOpenPrinter);
1044 torture_tcase_add_simple_test(tcase, "SyncRegisterForRemoteNotifications", test_SyncRegisterForRemoteNotifications);
1045 torture_tcase_add_simple_test(tcase, "SyncUnRegisterForRemoteNotifications", test_SyncUnRegisterForRemoteNotifications);
1046 torture_tcase_add_simple_test(tcase, "AsyncClosePrinter", test_AsyncClosePrinter);
1047 torture_tcase_add_simple_test(tcase, "AsyncUploadPrinterDriverPackage", test_AsyncUploadPrinterDriverPackage);
1048 torture_tcase_add_simple_test(tcase, "AsyncEnumPrinters", test_AsyncEnumPrinters);
1049 torture_tcase_add_simple_test(tcase, "AsyncGetPrinterData", test_AsyncGetPrinterData);
1050 torture_tcase_add_simple_test(tcase, "AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
1051 torture_tcase_add_simple_test(tcase, "AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
1052 torture_tcase_add_simple_test(tcase, "AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
1053 torture_tcase_add_simple_test(tcase, "AsyncOpenPrinterValidateBuildNumber", test_AsyncOpenPrinterValidateBuildNumber);
1055 tcase = torture_suite_add_tcase(suite, "handles");
1057 torture_tcase_set_fixture(tcase,
1058 torture_rpc_iremotewinspool_setup,
1059 torture_rpc_iremotewinspool_teardown);
1061 torture_tcase_add_simple_test(tcase, "OpenPrinter", test_OpenPrinter);