iremotewinspool-tests: Allow modification of OS client version information
[Samba.git] / source4 / torture / rpc / iremotewinspool.c
blobd80f2f74c653a441e44c4d68b391373ee3e5e439
1 /*
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/>.
21 #include "includes.h"
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
38 WIN_2000,
39 WIN_VISTA,
40 WIN_SERVER_2008,
41 WIN_7,
42 WIN_SERVER_2008R2,
43 WIN_8,
44 WIN_SERVER_2012,
45 WIN_10,
46 WIN_SERVER_2016
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;
56 level1.size = 28;
57 level1.client = talloc_asprintf(tctx, "\\\\%s", "mthelena");
58 level1.user = "GD";
59 level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
60 level1.major = major_number;
61 level1.minor = minor_number;
63 switch (os) {
64 case WIN_SERVER_2016:
65 case WIN_10:
66 level1.build = 10586;
67 break;
68 case WIN_SERVER_2012:
69 case WIN_8:
70 level1.build = 9200;
71 break;
72 case WIN_SERVER_2008R2:
73 case WIN_7:
74 level1.build = 7007;
75 break;
76 case WIN_SERVER_2008:
77 case WIN_VISTA:
78 level1.build = 6000;
79 break;
80 case WIN_2000:
81 level1.build = 1382;
82 break;
83 default:
84 level1.build = 7007;
87 return level1;
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");
121 return true;
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");
142 return true;
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,
151 uint8_t **data_p,
152 uint32_t *needed_p)
154 struct winspool_AsyncGetPrinterData r;
155 enum winreg_Type type;
156 uint32_t needed;
158 r.in.hPrinter = *handle;
159 r.in.pValueName = value_name;
160 r.in.nSize = 0;
161 r.out.pType = &type;
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",
166 r.in.pValueName);
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)) {
173 if (expected_type) {
174 torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
176 r.in.nSize = needed;
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");
187 if (type_p) {
188 *type_p = type;
191 if (data_p) {
192 *data_p = r.out.pData;
195 if (needed_p) {
196 *needed_p = needed;
199 return true;
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,
207 uint8_t **data_p,
208 uint32_t *needed_p)
210 return test_AsyncGetPrinterData_checktype(tctx, b, handle,
211 value_name,
212 NULL,
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)
221 DATA_BLOB blob;
222 enum winreg_Type type;
223 uint8_t *data;
224 uint32_t needed;
226 torture_assert(tctx,
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);
234 torture_assert(tctx,
235 pull_reg_sz(tctx, &blob, architecture),
236 "failed to pull environment");
238 return true;
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);
268 torture_assert(tctx,
269 test_AsyncOpenPrinter_byprinter(tctx, t,
270 t->iremotewinspool_pipe, printer_name,
271 client_info, &t->server_handle),
272 "failed to open printserver");
273 torture_assert(tctx,
274 test_get_environment(tctx,
275 t->iremotewinspool_pipe->binding_handle,
276 &t->server_handle, &t->environment),
277 "failed to get environment");
279 return true;
282 static bool torture_rpc_iremotewinspool_setup(struct torture_context *tctx,
283 void **data)
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);
298 return true;
301 static bool torture_rpc_iremotewinspool_teardown(struct torture_context *tctx,
302 void *data)
304 struct test_iremotewinspool_context *t = talloc_get_type(data, struct test_iremotewinspool_context);
305 bool ret;
307 ret = torture_rpc_iremotewinspool_teardown_common(tctx, t);
308 talloc_free(t);
310 return ret;
313 static bool test_AsyncClosePrinter(struct torture_context *tctx,
314 void *private_data)
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);
328 torture_assert(tctx,
329 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
330 "failed to test AsyncOpenPrinter");
332 torture_assert(tctx,
333 test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle),
334 "failed to test AsyncClosePrinter");
336 return true;
339 static bool test_AsyncOpenPrinter(struct torture_context *tctx,
340 void *private_data)
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);
354 torture_assert(tctx,
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);
360 return true;
363 static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct torture_context *tctx)
365 struct spoolss_NotifyOption *o;
367 o = talloc_zero(tctx, struct spoolss_NotifyOption);
368 if (o == NULL) {
369 return NULL;
372 o->version = 2;
373 o->flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
375 o->count = 2;
376 o->types = talloc_zero_array(o, struct spoolss_NotifyOptionType, o->count);
377 if (o->types == NULL) {
378 talloc_free(o);
379 return NULL;
382 o->types[0].type = PRINTER_NOTIFY_TYPE;
383 o->types[0].count = 1;
384 o->types[0].fields = talloc_array(o->types, union spoolss_Field, o->types[0].count);
385 if (o->types[0].fields == NULL) {
386 talloc_free(o);
387 return NULL;
389 o->types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
391 o->types[1].type = JOB_NOTIFY_TYPE;
392 o->types[1].count = 1;
393 o->types[1].fields = talloc_array(o->types, union spoolss_Field, o->types[1].count);
394 if (o->types[1].fields == NULL) {
395 talloc_free(o);
396 return NULL;
398 o->types[1].fields[0].field = JOB_NOTIFY_FIELD_MACHINE_NAME;
400 return o;
403 static bool test_SyncUnRegisterForRemoteNotifications_args(struct torture_context *tctx,
404 struct dcerpc_pipe *p,
405 struct policy_handle *notify_handle)
407 struct winspool_SyncUnRegisterForRemoteNotifications r;
408 struct dcerpc_binding_handle *b = p->binding_handle;
410 r.in.phRpcHandle = notify_handle;
411 r.out.phRpcHandle = notify_handle;
413 torture_assert_ntstatus_ok(tctx,
414 dcerpc_winspool_SyncUnRegisterForRemoteNotifications_r(b, tctx, &r),
415 "SyncUnRegisterForRemoteNotifications failed");
416 torture_assert_hresult_ok(tctx, r.out.result,
417 "SyncUnRegisterForRemoteNotifications failed");
419 return true;
422 static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
423 struct dcerpc_pipe *p,
424 struct policy_handle *server_handle,
425 struct policy_handle *notify_handle);
427 static bool test_SyncUnRegisterForRemoteNotifications(struct torture_context *tctx,
428 void *private_data)
430 struct test_iremotewinspool_context *ctx =
431 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
432 struct policy_handle notify_handle;
434 torture_assert(tctx,
435 test_SyncRegisterForRemoteNotifications_args(tctx,
436 ctx->iremotewinspool_pipe,
437 &ctx->server_handle,
438 &notify_handle),
439 "failed to test SyncRegisterForRemoteNotifications");
441 torture_assert(tctx,
442 test_SyncUnRegisterForRemoteNotifications_args(tctx,
443 ctx->iremotewinspool_pipe,
444 &notify_handle),
445 "failed to test UnSyncRegisterForRemoteNotifications");
447 return true;
450 static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
451 struct dcerpc_pipe *p,
452 struct policy_handle *server_handle,
453 struct policy_handle *notify_handle)
455 struct dcerpc_binding_handle *b = p->binding_handle;
457 struct winspool_SyncRegisterForRemoteNotifications r;
458 struct winspool_PrintPropertiesCollection NotifyFilter;
459 struct winspool_PrintNamedProperty *c;
460 struct spoolss_NotifyOption *options;
462 ZERO_STRUCT(NotifyFilter);
464 options = setup_printserver_NotifyOption(tctx);
465 torture_assert(tctx, options, "out of memory");
467 c = talloc_zero_array(tctx, struct winspool_PrintNamedProperty, 4);
468 torture_assert(tctx, c, "out of memory");
470 c[0].propertyName = "RemoteNotifyFilter Flags";
471 c[0].propertyValue.PropertyType = winspool_PropertyTypeInt32;
472 c[0].propertyValue.value.propertyInt32 = 0xff;
474 c[1].propertyName = "RemoteNotifyFilter Options";
475 c[1].propertyValue.PropertyType = winspool_PropertyTypeInt32;
476 c[1].propertyValue.value.propertyInt32 = 0;
478 c[2].propertyName = "RemoteNotifyFilter Color";
479 c[2].propertyValue.PropertyType = winspool_PropertyTypeInt32;
480 c[2].propertyValue.value.propertyInt32 = 0;
482 c[3].propertyName = "RemoteNotifyFilter NotifyOptions";
483 c[3].propertyValue.PropertyType = winspool_PropertyTypeNotificationOptions;
484 c[3].propertyValue.value.propertyOptionsContainer.pOptions = options;
486 NotifyFilter.numberOfProperties = 4;
487 NotifyFilter.propertiesCollection = c;
489 r.in.hPrinter = *server_handle;
490 r.in.pNotifyFilter = &NotifyFilter;
491 r.out.phRpcHandle = notify_handle;
493 torture_assert_ntstatus_ok(tctx,
494 dcerpc_winspool_SyncRegisterForRemoteNotifications_r(b, tctx, &r),
495 "SyncRegisterForRemoteNotifications failed");
496 torture_assert_hresult_ok(tctx, r.out.result,
497 "SyncRegisterForRemoteNotifications failed");
499 return true;
502 static bool test_SyncRegisterForRemoteNotifications(struct torture_context *tctx,
503 void *private_data)
505 struct test_iremotewinspool_context *ctx =
506 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
507 struct policy_handle notify_handle;
509 torture_assert(tctx,
510 test_SyncRegisterForRemoteNotifications_args(tctx,
511 ctx->iremotewinspool_pipe,
512 &ctx->server_handle,
513 &notify_handle),
514 "failed to test SyncRegisterForRemoteNotifications");
516 test_SyncUnRegisterForRemoteNotifications_args(tctx, ctx->iremotewinspool_pipe, &notify_handle);
518 return true;
521 static bool test_AsyncUploadPrinterDriverPackage(struct torture_context *tctx,
522 void *private_data)
524 struct test_iremotewinspool_context *ctx =
525 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
527 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
528 struct dcerpc_binding_handle *b = p->binding_handle;
530 struct winspool_AsyncUploadPrinterDriverPackage r;
531 uint32_t pcchDestInfPath = 0;
533 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
534 r.in.pszInfPath = "";
535 r.in.pszEnvironment = "";
536 r.in.dwFlags = 0;
537 r.in.pszDestInfPath = NULL;
538 r.in.pcchDestInfPath = &pcchDestInfPath;
539 r.out.pszDestInfPath = NULL;
540 r.out.pcchDestInfPath = &pcchDestInfPath;
542 torture_assert_ntstatus_ok(tctx,
543 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
544 "AsyncUploadPrinterDriverPackage failed");
545 torture_assert_hresult_equal(tctx, r.out.result, HRES_E_INVALIDARG,
546 "AsyncUploadPrinterDriverPackage failed");
548 pcchDestInfPath = 260;
549 r.in.pszDestInfPath = talloc_zero_array(tctx, uint16_t, pcchDestInfPath);
550 r.out.pszDestInfPath = talloc_zero_array(tctx, uint16_t, pcchDestInfPath);
552 torture_assert_ntstatus_ok(tctx,
553 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
554 "AsyncUploadPrinterDriverPackage failed");
555 torture_assert_werr_equal(tctx,
556 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
557 "AsyncUploadPrinterDriverPackage failed");
559 r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
561 torture_assert_ntstatus_ok(tctx,
562 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
563 "AsyncUploadPrinterDriverPackage failed");
564 torture_assert_werr_equal(tctx,
565 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
566 "AsyncUploadPrinterDriverPackage failed");
568 r.in.pszInfPath = "\\\\mthelena\\print$\\x64\\{BD443844-ED00-4D96-8CAE-95E49492312A}\\prnbrcl1.inf";
570 torture_assert_ntstatus_ok(tctx,
571 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
572 "AsyncUploadPrinterDriverPackage failed");
573 torture_assert_werr_equal(tctx,
574 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
575 "AsyncUploadPrinterDriverPackage failed");
577 return true;
580 static bool test_AsyncEnumPrinters(struct torture_context *tctx,
581 void *private_data)
583 struct test_iremotewinspool_context *ctx =
584 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
586 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
587 struct dcerpc_binding_handle *b = p->binding_handle;
589 struct winspool_AsyncEnumPrinters r;
590 uint32_t levels[] = { 1, 2, /*3,*/ 4, 5 };
591 int i;
593 uint32_t needed;
594 uint32_t returned;
596 for (i = 0; i < ARRAY_SIZE(levels); i++) {
598 r.in.Flags = PRINTER_ENUM_LOCAL;
599 r.in.pName = NULL;
600 r.in.Level = levels[i];
601 r.in.cbBuf = 0;
602 r.in.pPrinterEnum = NULL;
603 r.out.pcbNeeded = &needed;
604 r.out.pcReturned = &returned;
605 r.out.pPrinterEnum = NULL;
607 torture_assert_ntstatus_ok(tctx,
608 dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
609 "AsyncEnumPrinters failed");
610 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
611 "AsyncEnumPrinters failed");
613 r.in.cbBuf = needed;
614 r.in.pPrinterEnum = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
615 r.out.pPrinterEnum = r.in.pPrinterEnum;
617 torture_assert_ntstatus_ok(tctx,
618 dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
619 "AsyncEnumPrinters failed");
620 torture_assert_werr_ok(tctx, r.out.result,
621 "AsyncEnumPrinters failed");
624 return true;
627 static bool test_AsyncGetPrinterData(struct torture_context *tctx,
628 void *private_data)
630 struct test_iremotewinspool_context *ctx =
631 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
633 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
634 struct dcerpc_binding_handle *b = p->binding_handle;
635 DATA_BLOB blob;
636 const char *s;
637 bool ok;
639 uint32_t pType;
640 uint32_t pcbNeeded;
641 uint8_t *pData;
643 torture_assert(tctx,
644 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
645 "MajorVersion",
646 &pType, &pData, &pcbNeeded),
647 "failed to check for MajorVersion");
649 torture_assert_int_equal(tctx, pcbNeeded, 4, "pcbNeeded");
650 torture_assert_int_equal(tctx, pType, REG_DWORD, "pType");
651 torture_assert_int_equal(tctx, IVAL(pData, 0), 3, "pData");
653 torture_assert(tctx,
654 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
655 "Architecture",
656 &pType, &pData, &pcbNeeded),
657 "failed to check for Architecture");
659 blob = data_blob_const(pData, pcbNeeded);
661 torture_assert_int_equal(tctx, pType, REG_SZ, "pType");
662 torture_assert(tctx, pull_reg_sz(tctx, &blob, &s), "");
663 ok = strequal(s, SPOOLSS_ARCHITECTURE_x64) || strequal(s, SPOOLSS_ARCHITECTURE_NT_X86);
664 torture_assert(tctx, ok, "unexpected architecture returned");
666 return true;
669 static bool test_AsyncCorePrinterDriverInstalled(struct torture_context *tctx,
670 void *private_data)
672 struct test_iremotewinspool_context *ctx =
673 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
675 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
676 struct dcerpc_binding_handle *b = p->binding_handle;
678 struct winspool_AsyncCorePrinterDriverInstalled r;
679 int32_t pbDriverInstalled;
680 struct GUID guid;
682 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
683 r.in.pszEnvironment = "";
684 r.in.CoreDriverGUID = GUID_zero();
685 r.in.ftDriverDate = 0;
686 r.in.dwlDriverVersion = 0;
687 r.out.pbDriverInstalled = &pbDriverInstalled;
689 torture_assert_ntstatus_ok(tctx,
690 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
691 "AsyncCorePrinterDriverInstalled failed");
692 torture_assert_werr_equal(tctx,
693 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
694 "AsyncCorePrinterDriverInstalled failed");
696 r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
698 torture_assert_ntstatus_ok(tctx,
699 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
700 "AsyncCorePrinterDriverInstalled failed");
701 torture_assert_hresult_ok(tctx, r.out.result,
702 "AsyncCorePrinterDriverInstalled failed");
703 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
704 "unexpected driver installed");
706 r.in.CoreDriverGUID = GUID_random();
708 torture_assert_ntstatus_ok(tctx,
709 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
710 "AsyncCorePrinterDriverInstalled failed");
711 torture_assert_hresult_ok(tctx, r.out.result,
712 "AsyncCorePrinterDriverInstalled failed");
713 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
714 "unexpected driver installed");
716 torture_assert_ntstatus_ok(tctx,
717 GUID_from_string(SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV, &guid), "");
719 r.in.CoreDriverGUID = guid;
721 torture_assert_ntstatus_ok(tctx,
722 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
723 "AsyncCorePrinterDriverInstalled failed");
724 torture_assert_hresult_ok(tctx, r.out.result,
725 "AsyncCorePrinterDriverInstalled failed");
726 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
727 "xps core driver not installed?");
729 r.in.dwlDriverVersion = 0xffffffff;
731 torture_assert_ntstatus_ok(tctx,
732 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
733 "AsyncCorePrinterDriverInstalled failed");
734 torture_assert_hresult_ok(tctx, r.out.result,
735 "AsyncCorePrinterDriverInstalled failed");
736 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
737 "xps core driver not installed?");
739 r.in.dwlDriverVersion = 1234;
741 torture_assert_ntstatus_ok(tctx,
742 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
743 "AsyncCorePrinterDriverInstalled failed");
744 torture_assert_hresult_ok(tctx, r.out.result,
745 "AsyncCorePrinterDriverInstalled failed");
746 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
747 "xps core driver not installed?");
749 r.in.ftDriverDate = unix_timespec_to_nt_time(timespec_current());
751 torture_assert_ntstatus_ok(tctx,
752 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
753 "AsyncCorePrinterDriverInstalled failed");
754 torture_assert_hresult_ok(tctx, r.out.result,
755 "AsyncCorePrinterDriverInstalled failed");
756 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
757 "driver too old ?");
759 r.in.dwlDriverVersion = 0;
761 torture_assert_ntstatus_ok(tctx,
762 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
763 "AsyncCorePrinterDriverInstalled failed");
764 torture_assert_hresult_ok(tctx, r.out.result,
765 "AsyncCorePrinterDriverInstalled failed");
766 torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
767 "unexpected driver installed");
769 return true;
772 static bool test_get_core_printer_drivers_arch_guid(struct torture_context *tctx,
773 struct dcerpc_pipe *p,
774 const char *architecture,
775 const char *guid_str,
776 const char **package_id)
778 struct winspool_AsyncGetCorePrinterDrivers r;
779 DATA_BLOB blob;
780 const char **s;
781 struct dcerpc_binding_handle *b = p->binding_handle;
783 s = talloc_zero_array(tctx, const char *, 2);
784 s[0] = guid_str;
786 torture_assert(tctx,
787 push_reg_multi_sz(tctx, &blob, s),
788 "push_reg_multi_sz failed");
790 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
791 r.in.pszEnvironment = architecture;
792 r.in.cchCoreDrivers = blob.length/2;
793 r.in.pszzCoreDriverDependencies = (uint16_t *)blob.data;
794 r.in.cCorePrinterDrivers = 1;
795 r.out.pCorePrinterDrivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.cCorePrinterDrivers);
797 torture_assert_ntstatus_ok(tctx,
798 dcerpc_winspool_AsyncGetCorePrinterDrivers_r(b, tctx, &r),
799 "winspool_AsyncCorePrinterDrivers failed");
800 torture_assert_hresult_ok(tctx, r.out.result,
801 "winspool_AsyncCorePrinterDrivers failed");
803 if (package_id) {
804 *package_id = r.out.pCorePrinterDrivers[0].szPackageID;
807 return true;
810 static bool test_AsyncDeletePrintDriverPackage(struct torture_context *tctx,
811 void *private_data)
813 struct test_iremotewinspool_context *ctx =
814 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
816 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
817 struct dcerpc_binding_handle *b = p->binding_handle;
818 struct winspool_AsyncDeletePrinterDriverPackage r;
820 const char *architectures[] = {
821 /* SPOOLSS_ARCHITECTURE_NT_X86, */
822 SPOOLSS_ARCHITECTURE_x64
824 int i;
826 for (i=0; i < ARRAY_SIZE(architectures); i++) {
828 const char *package_id;
830 torture_assert(tctx,
831 test_get_core_printer_drivers_arch_guid(tctx, p,
832 architectures[i],
833 SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
834 &package_id),
835 "failed to get core printer driver");
837 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
838 r.in.pszEnvironment = "";
839 r.in.pszInfPath = "";
841 torture_comment(tctx, "Testing AsyncDeletePrinterDriverPackage(%s, %s, %s)\n",
842 r.in.pszServer, architectures[i], package_id);
844 torture_assert_ntstatus_ok(tctx,
845 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
846 "AsyncDeletePrinterDriverPackage failed");
847 torture_assert_werr_equal(tctx,
848 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_NOT_FOUND,
849 "AsyncDeletePrinterDriverPackage failed");
851 r.in.pszInfPath = package_id;
853 torture_assert_ntstatus_ok(tctx,
854 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
855 "AsyncDeletePrinterDriverPackage failed");
856 torture_assert_werr_equal(tctx,
857 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
858 "AsyncDeletePrinterDriverPackage failed");
860 r.in.pszEnvironment = architectures[i];
862 torture_assert_ntstatus_ok(tctx,
863 dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
864 "AsyncDeletePrinterDriverPackage failed");
865 torture_assert_hresult_equal(tctx, r.out.result, HRES_E_ACCESSDENIED,
866 "AsyncDeletePrinterDriverPackage failed");
869 return true;
872 static bool test_AsyncGetPrinterDriverDirectory(struct torture_context *tctx,
873 void *private_data)
875 struct test_iremotewinspool_context *ctx =
876 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
878 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
879 struct dcerpc_binding_handle *b = p->binding_handle;
880 struct winspool_AsyncGetPrinterDriverDirectory r;
881 uint32_t pcbNeeded;
882 DATA_BLOB blob;
883 const char *s;
885 r.in.pName = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
886 r.in.pEnvironment = ctx->environment;
887 r.in.Level = 1;
888 r.in.cbBuf = 0x200;
889 r.in.pDriverDirectory = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
890 r.out.pcbNeeded = &pcbNeeded;
891 r.out.pDriverDirectory = r.in.pDriverDirectory;
893 torture_comment(tctx, "Testing AsyncGetPrinterDriverDirectory(%s, %s)\n",
894 r.in.pName, r.in.pEnvironment);
896 torture_assert_ntstatus_ok(tctx,
897 dcerpc_winspool_AsyncGetPrinterDriverDirectory_r(b, tctx, &r),
898 "AsyncGetPrinterDriverDirectory failed");
899 torture_assert_werr_ok(tctx, r.out.result,
900 "AsyncGetPrinterDriverDirectory failed");
902 blob = data_blob_const(r.out.pDriverDirectory, pcbNeeded);
904 torture_assert(tctx,
905 pull_reg_sz(tctx, &blob, &s),
906 "failed to pull reg_sz");
908 torture_comment(tctx, "got: %s\n", s);
910 return true;
914 * Test if one can close a printserver handle that has been acquired via
915 * winspool_AsyncOpenPrinter with a spoolss_ClosePrinter operation.
918 static bool test_OpenPrinter(struct torture_context *tctx,
919 void *private_data)
921 struct test_iremotewinspool_context *ctx =
922 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
924 struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
925 const char *printer_name;
926 struct policy_handle handle;
927 struct dcerpc_pipe *s;
928 struct dcerpc_binding *binding;
929 struct spoolss_UserLevel1 client_info;
930 struct spoolss_ClosePrinter r;
932 torture_assert_ntstatus_ok(tctx,
933 torture_rpc_binding(tctx, &binding),
934 "failed to get binding");
936 torture_assert_ntstatus_ok(tctx,
937 dcerpc_binding_set_transport(binding, NCACN_NP),
938 "failed to set ncacn_np transport");
940 torture_assert_ntstatus_ok(tctx,
941 dcerpc_binding_set_object(binding, GUID_zero()),
942 "failed to set object uuid to zero");
944 torture_assert_ntstatus_ok(tctx,
945 torture_rpc_connection_with_binding(tctx, binding, &s, &ndr_table_spoolss),
946 "failed to connect to spoolss");
948 printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
950 client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
952 torture_assert(tctx,
953 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
954 "failed to open printserver via winspool");
957 r.in.handle = &handle;
958 r.out.handle = &handle;
960 torture_assert_ntstatus_equal(tctx,
961 dcerpc_spoolss_ClosePrinter_r(s->binding_handle, tctx, &r),
962 NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
963 "ClosePrinter failed");
965 talloc_free(s);
967 return true;
970 struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx)
972 struct torture_suite *suite = torture_suite_create(mem_ctx, "iremotewinspool");
973 struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
975 torture_tcase_set_fixture(tcase,
976 torture_rpc_iremotewinspool_setup,
977 torture_rpc_iremotewinspool_teardown);
979 torture_tcase_add_simple_test(tcase, "AsyncOpenPrinter", test_AsyncOpenPrinter);
980 torture_tcase_add_simple_test(tcase, "SyncRegisterForRemoteNotifications", test_SyncRegisterForRemoteNotifications);
981 torture_tcase_add_simple_test(tcase, "SyncUnRegisterForRemoteNotifications", test_SyncUnRegisterForRemoteNotifications);
982 torture_tcase_add_simple_test(tcase, "AsyncClosePrinter", test_AsyncClosePrinter);
983 torture_tcase_add_simple_test(tcase, "AsyncUploadPrinterDriverPackage", test_AsyncUploadPrinterDriverPackage);
984 torture_tcase_add_simple_test(tcase, "AsyncEnumPrinters", test_AsyncEnumPrinters);
985 torture_tcase_add_simple_test(tcase, "AsyncGetPrinterData", test_AsyncGetPrinterData);
986 torture_tcase_add_simple_test(tcase, "AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
987 torture_tcase_add_simple_test(tcase, "AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
988 torture_tcase_add_simple_test(tcase, "AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
990 tcase = torture_suite_add_tcase(suite, "handles");
992 torture_tcase_set_fixture(tcase,
993 torture_rpc_iremotewinspool_setup,
994 torture_rpc_iremotewinspool_teardown);
996 torture_tcase_add_simple_test(tcase, "OpenPrinter", test_OpenPrinter);
998 return suite;