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
);
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
);
373 o
->flags
= PRINTER_NOTIFY_OPTIONS_REFRESH
;
376 o
->types
= talloc_zero_array(o
, struct spoolss_NotifyOptionType
, o
->count
);
377 if (o
->types
== 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
) {
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
) {
398 o
->types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_MACHINE_NAME
;
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");
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
,
430 struct test_iremotewinspool_context
*ctx
=
431 talloc_get_type_abort(private_data
, struct test_iremotewinspool_context
);
432 struct policy_handle notify_handle
;
435 test_SyncRegisterForRemoteNotifications_args(tctx
,
436 ctx
->iremotewinspool_pipe
,
439 "failed to test SyncRegisterForRemoteNotifications");
442 test_SyncUnRegisterForRemoteNotifications_args(tctx
,
443 ctx
->iremotewinspool_pipe
,
445 "failed to test UnSyncRegisterForRemoteNotifications");
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");
502 static bool test_SyncRegisterForRemoteNotifications(struct torture_context
*tctx
,
505 struct test_iremotewinspool_context
*ctx
=
506 talloc_get_type_abort(private_data
, struct test_iremotewinspool_context
);
507 struct policy_handle notify_handle
;
510 test_SyncRegisterForRemoteNotifications_args(tctx
,
511 ctx
->iremotewinspool_pipe
,
514 "failed to test SyncRegisterForRemoteNotifications");
516 test_SyncUnRegisterForRemoteNotifications_args(tctx
, ctx
->iremotewinspool_pipe
, ¬ify_handle
);
521 static bool test_AsyncUploadPrinterDriverPackage(struct torture_context
*tctx
,
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
= "";
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");
580 static bool test_AsyncEnumPrinters(struct torture_context
*tctx
,
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 };
596 for (i
= 0; i
< ARRAY_SIZE(levels
); i
++) {
598 r
.in
.Flags
= PRINTER_ENUM_LOCAL
;
600 r
.in
.Level
= levels
[i
];
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");
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");
627 static bool test_AsyncGetPrinterData(struct torture_context
*tctx
,
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
;
644 test_AsyncGetPrinterData_args(tctx
, b
, &ctx
->server_handle
,
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");
654 test_AsyncGetPrinterData_args(tctx
, b
, &ctx
->server_handle
,
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");
669 static bool test_AsyncCorePrinterDriverInstalled(struct torture_context
*tctx
,
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
;
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,
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");
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
;
781 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
783 s
= talloc_zero_array(tctx
, const char *, 2);
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");
804 *package_id
= r
.out
.pCorePrinterDrivers
[0].szPackageID
;
810 static bool test_AsyncDeletePrintDriverPackage(struct torture_context
*tctx
,
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
826 for (i
=0; i
< ARRAY_SIZE(architectures
); i
++) {
828 const char *package_id
;
831 test_get_core_printer_drivers_arch_guid(tctx
, p
,
833 SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV
,
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");
872 static bool test_AsyncGetPrinterDriverDirectory(struct torture_context
*tctx
,
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
;
885 r
.in
.pName
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
886 r
.in
.pEnvironment
= ctx
->environment
;
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
);
905 pull_reg_sz(tctx
, &blob
, &s
),
906 "failed to pull reg_sz");
908 torture_comment(tctx
, "got: %s\n", s
);
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
,
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
);
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");
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
);