2 Unix SMB/CIFS implementation.
3 test suite for spoolss rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Stefan Metzmacher 2005
7 Copyright (C) Jelmer Vernooij 2007
8 Copyright (C) Guenther Deschner 2009-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
26 #include "librpc/gen_ndr/ndr_misc.h"
27 #include "librpc/gen_ndr/ndr_spoolss.h"
28 #include "librpc/gen_ndr/ndr_spoolss_c.h"
29 #include "librpc/gen_ndr/ndr_winreg_c.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/torture_rpc.h"
33 #include "param/param.h"
34 #include "lib/registry/registry.h"
35 #include "libcli/libcli.h"
36 #include "libcli/raw/raw_proto.h"
37 #include "libcli/resolve/resolve.h"
38 #include "lib/cmdline/popt_common.h"
39 #include "system/filesys.h"
40 #include "torture/ndr/ndr.h"
42 #define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
43 #define TORTURE_PRINTER "torture_printer"
44 #define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex"
45 #define TORTURE_PRINTER_EX "torture_printer_ex"
46 #define TORTURE_DRIVER "torture_driver"
47 #define TORTURE_DRIVER_EX "torture_driver_ex"
48 #define TORTURE_DRIVER_ADOBE "torture_driver_adobe"
49 #define TORTURE_DRIVER_EX_ADOBE "torture_driver_ex_adobe"
50 #define TORTURE_DRIVER_ADOBE_CUPSADDSMB "torture_driver_adobe_cupsaddsmb"
51 #define TORTURE_DRIVER_TIMESTAMPS "torture_driver_timestamps"
53 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
54 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
55 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
56 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
57 #define TOP_LEVEL_CONTROL_PRINTERS_KEY TOP_LEVEL_CONTROL_KEY "\\Printers"
58 #define TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY TOP_LEVEL_CONTROL_KEY "\\Environments"
60 struct test_spoolss_context
{
61 struct dcerpc_pipe
*spoolss_pipe
;
63 /* server environment */
64 const char *environment
;
66 /* print server handle */
67 struct policy_handle server_handle
;
70 uint32_t port_count
[3];
71 union spoolss_PortInfo
*ports
[3];
73 /* for EnumPrinterDrivers */
74 uint32_t driver_count
[8];
75 union spoolss_DriverInfo
*drivers
[8];
77 /* for EnumMonitors */
78 uint32_t monitor_count
[3];
79 union spoolss_MonitorInfo
*monitors
[3];
81 /* for EnumPrintProcessors */
82 uint32_t print_processor_count
[2];
83 union spoolss_PrintProcessorInfo
*print_processors
[2];
85 /* for EnumPrinters */
86 uint32_t printer_count
[6];
87 union spoolss_PrinterInfo
*printers
[6];
90 struct torture_driver_context
{
92 const char *driver_directory
;
93 const char *environment
;
96 const char *driver_directory
;
97 const char *environment
;
99 struct spoolss_AddDriverInfo8 info8
;
103 struct torture_printer_context
{
104 struct dcerpc_pipe
*spoolss_pipe
;
105 struct spoolss_SetPrinterInfo2 info2
;
106 struct torture_driver_context driver
;
111 struct spoolss_DeviceMode
*devmode
;
112 struct policy_handle handle
;
115 static bool upload_printer_driver(struct torture_context
*tctx
,
116 const char *server_name
,
117 struct torture_driver_context
*d
);
118 static bool remove_printer_driver(struct torture_context
*tctx
,
119 const char *server_name
,
120 struct torture_driver_context
*d
);
121 static bool fillup_printserver_info(struct torture_context
*tctx
,
122 struct dcerpc_pipe
*p
,
123 struct torture_driver_context
*d
);
124 static bool test_AddPrinterDriver_args_level_3(struct torture_context
*tctx
,
125 struct dcerpc_binding_handle
*b
,
126 const char *server_name
,
127 struct spoolss_AddDriverInfo8
*r
,
130 const char *remote_driver_dir
);
132 #define COMPARE_STRING(tctx, c,r,e) \
133 torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
135 /* not every compiler supports __typeof__() */
137 #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
138 if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
139 torture_fail(tctx, #c "." #e "field is not " #type "\n"); \
141 if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
142 torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
146 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
149 #define COMPARE_UINT32(tctx, c, r, e) do {\
150 _CHECK_FIELD_SIZE(c, r, e, uint32_t); \
151 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
154 #define COMPARE_UINT64(tctx, c, r, e) do {\
155 _CHECK_FIELD_SIZE(c, r, e, uint64_t); \
156 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
160 #define COMPARE_NTTIME(tctx, c, r, e) do {\
161 _CHECK_FIELD_SIZE(c, r, e, NTTIME); \
162 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
165 #define COMPARE_STRING_ARRAY(tctx, c,r,e) do {\
167 if (!c.e && !r.e) { \
171 torture_fail(tctx, #r "." #e " field is NULL and " #c "." #e " is not\n"); \
174 torture_fail(tctx, #c "." #e " field is NULL and " #r "." #e " is not\n"); \
176 for (__i=0;c.e[__i] != NULL; __i++) { \
177 torture_assert_str_equal(tctx, c.e[__i], r.e[__i], "invalid value"); \
181 #define CHECK_ALIGN(size, n) do {\
183 torture_warning(tctx, "%d is *NOT* %d byte aligned, should be %d",\
184 size, n, size + n - (size % n));\
188 #define DO_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
190 #define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, needed, align) do { \
191 if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
192 uint32_t size = ndr_size_##fn##_info(tctx, level, count, info);\
193 uint32_t round_size = DO_ROUND(size, align);\
194 if (round_size != needed) {\
195 torture_warning(tctx, __location__": "#fn" level %d (count: %d) got unexpected needed size: %d, we calculated: %d", level, count, needed, round_size);\
196 CHECK_ALIGN(size, align);\
201 #define CHECK_NEEDED_SIZE_ENUM(fn, info, count, needed, align) do { \
202 if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
203 uint32_t size = ndr_size_##fn##_info(tctx, count, info);\
204 uint32_t round_size = DO_ROUND(size, align);\
205 if (round_size != needed) {\
206 torture_warning(tctx, __location__": "#fn" (count: %d) got unexpected needed size: %d, we calculated: %d", count, needed, round_size);\
207 CHECK_ALIGN(size, align);\
212 #define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, needed, align) do { \
213 if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
214 uint32_t size = ndr_size_##fn(info, level, 0);\
215 uint32_t round_size = DO_ROUND(size, align);\
216 if (round_size != needed) {\
217 torture_warning(tctx, __location__": "#fn" level %d got unexpected needed size: %d, we calculated: %d", level, needed, round_size);\
218 CHECK_ALIGN(size, align);\
223 static bool PrinterInfo_to_SetPrinterInfo(struct torture_context
*tctx
,
224 const union spoolss_PrinterInfo
*i
,
226 union spoolss_SetPrinterInfo
*s
)
230 s
->info0
= talloc(tctx
, struct spoolss_SetPrinterInfo0
);
233 s
->info2
= talloc(tctx
, struct spoolss_SetPrinterInfo2
);
234 s
->info2
->servername
= i
->info2
.servername
;
235 s
->info2
->printername
= i
->info2
.printername
;
236 s
->info2
->sharename
= i
->info2
.sharename
;
237 s
->info2
->portname
= i
->info2
.portname
;
238 s
->info2
->drivername
= i
->info2
.drivername
;
239 s
->info2
->comment
= i
->info2
.comment
;
240 s
->info2
->location
= i
->info2
.location
;
241 s
->info2
->devmode_ptr
= 0;
242 s
->info2
->sepfile
= i
->info2
.sepfile
;
243 s
->info2
->printprocessor
= i
->info2
.printprocessor
;
244 s
->info2
->datatype
= i
->info2
.datatype
;
245 s
->info2
->parameters
= i
->info2
.parameters
;
246 s
->info2
->secdesc_ptr
= 0;
247 s
->info2
->attributes
= i
->info2
.attributes
;
248 s
->info2
->priority
= i
->info2
.priority
;
249 s
->info2
->defaultpriority
= i
->info2
.defaultpriority
;
250 s
->info2
->starttime
= i
->info2
.starttime
;
251 s
->info2
->untiltime
= i
->info2
.untiltime
;
252 s
->info2
->status
= i
->info2
.status
;
253 s
->info2
->cjobs
= i
->info2
.cjobs
;
254 s
->info2
->averageppm
= i
->info2
.averageppm
;
270 static bool test_OpenPrinter_server(struct torture_context
*tctx
,
271 struct dcerpc_pipe
*p
,
272 struct policy_handle
*server_handle
)
275 struct spoolss_OpenPrinter op
;
276 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
278 op
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
279 op
.in
.datatype
= NULL
;
280 op
.in
.devmode_ctr
.devmode
= NULL
;
281 op
.in
.access_mask
= 0;
282 op
.out
.handle
= server_handle
;
284 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", op
.in
.printername
);
286 status
= dcerpc_spoolss_OpenPrinter_r(b
, tctx
, &op
);
287 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_OpenPrinter failed");
288 torture_assert_werr_ok(tctx
, op
.out
.result
, "dcerpc_spoolss_OpenPrinter failed");
293 static bool test_EnumPorts(struct torture_context
*tctx
,
296 struct test_spoolss_context
*ctx
=
297 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
298 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
299 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
301 struct spoolss_EnumPorts r
;
302 uint16_t levels
[] = { 1, 2 };
305 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
306 int level
= levels
[i
];
310 union spoolss_PortInfo
*info
;
312 r
.in
.servername
= "";
316 r
.out
.needed
= &needed
;
317 r
.out
.count
= &count
;
320 torture_comment(tctx
, "Testing EnumPorts level %u\n", r
.in
.level
);
322 status
= dcerpc_spoolss_EnumPorts_r(b
, ctx
, &r
);
323 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
324 if (W_ERROR_IS_OK(r
.out
.result
)) {
325 /* TODO: do some more checks here */
328 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
329 "EnumPorts unexpected return code");
331 blob
= data_blob_talloc_zero(ctx
, needed
);
333 r
.in
.offered
= needed
;
335 status
= dcerpc_spoolss_EnumPorts_r(b
, ctx
, &r
);
336 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
338 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPorts failed");
340 torture_assert(tctx
, info
, "EnumPorts returned no info");
342 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts
, info
, r
.in
.level
, count
, needed
, 4);
344 ctx
->port_count
[level
] = count
;
345 ctx
->ports
[level
] = info
;
348 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
349 int level
= levels
[i
];
350 int old_level
= levels
[i
-1];
351 torture_assert_int_equal(tctx
, ctx
->port_count
[level
], ctx
->port_count
[old_level
],
352 "EnumPorts invalid value");
354 /* if the array sizes are not the same we would maybe segfault in the following code */
356 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
357 int level
= levels
[i
];
358 for (j
=0;j
<ctx
->port_count
[level
];j
++) {
359 union spoolss_PortInfo
*cur
= &ctx
->ports
[level
][j
];
360 union spoolss_PortInfo
*ref
= &ctx
->ports
[2][j
];
363 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, port_name
);
366 /* level 2 is our reference, and it makes no sense to compare it to itself */
375 static bool test_GetPrintProcessorDirectory(struct torture_context
*tctx
,
378 struct test_spoolss_context
*ctx
=
379 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
382 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
383 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
384 struct spoolss_GetPrintProcessorDirectory r
;
399 .server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
))
402 .server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
))
408 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
409 int level
= levels
[i
].level
;
412 r
.in
.server
= levels
[i
].server
;
413 r
.in
.environment
= ctx
->environment
;
417 r
.out
.needed
= &needed
;
419 torture_comment(tctx
, "Testing GetPrintProcessorDirectory level %u\n", r
.in
.level
);
421 status
= dcerpc_spoolss_GetPrintProcessorDirectory_r(b
, tctx
, &r
);
422 torture_assert_ntstatus_ok(tctx
, status
,
423 "dcerpc_spoolss_GetPrintProcessorDirectory failed");
424 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
425 "GetPrintProcessorDirectory unexpected return code");
427 blob
= data_blob_talloc_zero(tctx
, needed
);
429 r
.in
.offered
= needed
;
431 status
= dcerpc_spoolss_GetPrintProcessorDirectory_r(b
, tctx
, &r
);
432 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
434 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrintProcessorDirectory failed");
436 CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo
, r
.out
.info
, r
.in
.level
, needed
, 2);
443 static bool test_GetPrinterDriverDirectory(struct torture_context
*tctx
,
446 struct test_spoolss_context
*ctx
=
447 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
450 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
451 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
452 struct spoolss_GetPrinterDriverDirectory r
;
467 .server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
))
470 .server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
))
476 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
477 int level
= levels
[i
].level
;
480 r
.in
.server
= levels
[i
].server
;
481 r
.in
.environment
= ctx
->environment
;
485 r
.out
.needed
= &needed
;
487 torture_comment(tctx
, "Testing GetPrinterDriverDirectory level %u\n", r
.in
.level
);
489 status
= dcerpc_spoolss_GetPrinterDriverDirectory_r(b
, tctx
, &r
);
490 torture_assert_ntstatus_ok(tctx
, status
,
491 "dcerpc_spoolss_GetPrinterDriverDirectory failed");
492 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
493 "GetPrinterDriverDirectory unexpected return code");
495 blob
= data_blob_talloc_zero(tctx
, needed
);
497 r
.in
.offered
= needed
;
499 status
= dcerpc_spoolss_GetPrinterDriverDirectory_r(b
, tctx
, &r
);
500 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
502 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterDriverDirectory failed");
504 CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo
, r
.out
.info
, r
.in
.level
, needed
, 2);
510 static bool test_EnumPrinterDrivers_args(struct torture_context
*tctx
,
511 struct dcerpc_binding_handle
*b
,
512 const char *server_name
,
513 const char *environment
,
516 union spoolss_DriverInfo
**info_p
)
518 struct spoolss_EnumPrinterDrivers r
;
521 union spoolss_DriverInfo
*info
;
523 r
.in
.server
= server_name
;
524 r
.in
.environment
= environment
;
528 r
.out
.needed
= &needed
;
529 r
.out
.count
= &count
;
532 torture_comment(tctx
, "Testing EnumPrinterDrivers(%s) level %u\n",
533 r
.in
.environment
, r
.in
.level
);
535 torture_assert_ntstatus_ok(tctx
,
536 dcerpc_spoolss_EnumPrinterDrivers_r(b
, tctx
, &r
),
537 "EnumPrinterDrivers failed");
538 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
539 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
541 r
.in
.offered
= needed
;
543 torture_assert_ntstatus_ok(tctx
,
544 dcerpc_spoolss_EnumPrinterDrivers_r(b
, tctx
, &r
),
545 "EnumPrinterDrivers failed");
548 torture_assert_werr_ok(tctx
, r
.out
.result
,
549 "EnumPrinterDrivers failed");
558 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers
, info
, r
.in
.level
, count
, needed
, 4);
564 static bool test_EnumPrinterDrivers_findone(struct torture_context
*tctx
,
565 struct dcerpc_binding_handle
*b
,
566 const char *server_name
,
567 const char *environment
,
569 const char *driver_name
,
570 union spoolss_DriverInfo
*info_p
)
573 union spoolss_DriverInfo
*info
;
575 const char *environment_ret
= NULL
;
578 test_EnumPrinterDrivers_args(tctx
, b
, server_name
, environment
, level
, &count
, &info
),
579 "failed to enumerate printer drivers");
581 for (i
=0; i
< count
; i
++) {
582 const char *driver_name_ret
;
585 driver_name_ret
= info
[i
].info1
.driver_name
;
588 driver_name_ret
= info
[i
].info2
.driver_name
;
589 environment_ret
= info
[i
].info2
.architecture
;
592 driver_name_ret
= info
[i
].info3
.driver_name
;
593 environment_ret
= info
[i
].info3
.architecture
;
596 driver_name_ret
= info
[i
].info4
.driver_name
;
597 environment_ret
= info
[i
].info4
.architecture
;
600 driver_name_ret
= info
[i
].info5
.driver_name
;
601 environment_ret
= info
[i
].info5
.architecture
;
604 driver_name_ret
= info
[i
].info6
.driver_name
;
605 environment_ret
= info
[i
].info6
.architecture
;
608 driver_name_ret
= info
[i
].info7
.driver_name
;
611 driver_name_ret
= info
[i
].info8
.driver_name
;
612 environment_ret
= info
[i
].info8
.architecture
;
617 if (environment_ret
) {
618 torture_assert_str_equal(tctx
, environment
, environment_ret
, "architecture mismatch");
620 if (strequal(driver_name
, driver_name_ret
)) {
631 static bool test_EnumPrinterDrivers(struct torture_context
*tctx
,
634 struct test_spoolss_context
*ctx
=
635 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
636 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
637 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
638 uint16_t levels
[] = { 1, 2, 3, 4, 5, 6, 8 };
641 /* FIXME: gd, come back and fix "" as server, and handle
642 * priority of returned error codes in torture test and samba 3
644 const char *server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
645 const char *environments
[2];
647 environments
[0] = SPOOLSS_ARCHITECTURE_ALL
;
648 environments
[1] = ctx
->environment
;
650 for (a
=0;a
<ARRAY_SIZE(environments
);a
++) {
652 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
653 int level
= levels
[i
];
655 union spoolss_DriverInfo
*info
;
658 test_EnumPrinterDrivers_args(tctx
, b
, server_name
, environments
[a
], level
, &count
, &info
),
659 "failed to enumerate drivers");
661 ctx
->driver_count
[level
] = count
;
662 ctx
->drivers
[level
] = info
;
665 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
666 int level
= levels
[i
];
667 int old_level
= levels
[i
-1];
669 torture_assert_int_equal(tctx
, ctx
->driver_count
[level
], ctx
->driver_count
[old_level
],
670 "EnumPrinterDrivers invalid value");
673 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
674 int level
= levels
[i
];
676 for (j
=0;j
<ctx
->driver_count
[level
];j
++) {
677 union spoolss_DriverInfo
*cur
= &ctx
->drivers
[level
][j
];
678 union spoolss_DriverInfo
*ref
= &ctx
->drivers
[8][j
];
682 COMPARE_STRING(tctx
, cur
->info1
, ref
->info8
, driver_name
);
685 COMPARE_UINT32(tctx
, cur
->info2
, ref
->info8
, version
);
686 COMPARE_STRING(tctx
, cur
->info2
, ref
->info8
, driver_name
);
687 COMPARE_STRING(tctx
, cur
->info2
, ref
->info8
, architecture
);
688 COMPARE_STRING(tctx
, cur
->info2
, ref
->info8
, driver_path
);
689 COMPARE_STRING(tctx
, cur
->info2
, ref
->info8
, data_file
);
690 COMPARE_STRING(tctx
, cur
->info2
, ref
->info8
, config_file
);
693 COMPARE_UINT32(tctx
, cur
->info3
, ref
->info8
, version
);
694 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, driver_name
);
695 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, architecture
);
696 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, driver_path
);
697 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, data_file
);
698 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, config_file
);
699 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, help_file
);
700 COMPARE_STRING_ARRAY(tctx
, cur
->info3
, ref
->info8
, dependent_files
);
701 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, monitor_name
);
702 COMPARE_STRING(tctx
, cur
->info3
, ref
->info8
, default_datatype
);
705 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info8
, version
);
706 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, driver_name
);
707 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, architecture
);
708 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, driver_path
);
709 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, data_file
);
710 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, config_file
);
711 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, help_file
);
712 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info8
, dependent_files
);
713 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, monitor_name
);
714 COMPARE_STRING(tctx
, cur
->info4
, ref
->info8
, default_datatype
);
715 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info8
, previous_names
);
718 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info8
, version
);
719 COMPARE_STRING(tctx
, cur
->info5
, ref
->info8
, driver_name
);
720 COMPARE_STRING(tctx
, cur
->info5
, ref
->info8
, architecture
);
721 COMPARE_STRING(tctx
, cur
->info5
, ref
->info8
, driver_path
);
722 COMPARE_STRING(tctx
, cur
->info5
, ref
->info8
, data_file
);
723 COMPARE_STRING(tctx
, cur
->info5
, ref
->info8
, config_file
);
724 /*COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_attributes);*/
725 /*COMPARE_UINT32(tctx, cur->info5, ref->info8, config_version);*/
726 /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_version); */
729 COMPARE_UINT32(tctx
, cur
->info6
, ref
->info8
, version
);
730 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, driver_name
);
731 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, architecture
);
732 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, driver_path
);
733 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, data_file
);
734 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, config_file
);
735 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, help_file
);
736 COMPARE_STRING_ARRAY(tctx
, cur
->info6
, ref
->info8
, dependent_files
);
737 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, monitor_name
);
738 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, default_datatype
);
739 COMPARE_STRING_ARRAY(tctx
, cur
->info6
, ref
->info8
, previous_names
);
740 COMPARE_NTTIME(tctx
, cur
->info6
, ref
->info8
, driver_date
);
741 COMPARE_UINT64(tctx
, cur
->info6
, ref
->info8
, driver_version
);
742 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, manufacturer_name
);
743 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, manufacturer_url
);
744 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, hardware_id
);
745 COMPARE_STRING(tctx
, cur
->info6
, ref
->info8
, provider
);
748 /* level 8 is our reference, and it makes no sense to compare it to itself */
758 static bool test_EnumMonitors(struct torture_context
*tctx
,
761 struct test_spoolss_context
*ctx
=
762 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
763 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
764 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
766 struct spoolss_EnumMonitors r
;
767 uint16_t levels
[] = { 1, 2 };
770 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
771 int level
= levels
[i
];
775 union spoolss_MonitorInfo
*info
;
777 r
.in
.servername
= "";
781 r
.out
.needed
= &needed
;
782 r
.out
.count
= &count
;
785 torture_comment(tctx
, "Testing EnumMonitors level %u\n", r
.in
.level
);
787 status
= dcerpc_spoolss_EnumMonitors_r(b
, ctx
, &r
);
788 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
789 if (W_ERROR_IS_OK(r
.out
.result
)) {
790 /* TODO: do some more checks here */
793 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
794 "EnumMonitors failed");
796 blob
= data_blob_talloc_zero(ctx
, needed
);
798 r
.in
.offered
= needed
;
800 status
= dcerpc_spoolss_EnumMonitors_r(b
, ctx
, &r
);
801 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
803 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumMonitors failed");
805 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors
, info
, r
.in
.level
, count
, needed
, 4);
807 ctx
->monitor_count
[level
] = count
;
808 ctx
->monitors
[level
] = info
;
811 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
812 int level
= levels
[i
];
813 int old_level
= levels
[i
-1];
814 torture_assert_int_equal(tctx
, ctx
->monitor_count
[level
], ctx
->monitor_count
[old_level
],
815 "EnumMonitors invalid value");
818 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
819 int level
= levels
[i
];
820 for (j
=0;j
<ctx
->monitor_count
[level
];j
++) {
821 union spoolss_MonitorInfo
*cur
= &ctx
->monitors
[level
][j
];
822 union spoolss_MonitorInfo
*ref
= &ctx
->monitors
[2][j
];
825 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, monitor_name
);
828 /* level 2 is our reference, and it makes no sense to compare it to itself */
837 static bool test_EnumPrintProcessors_level(struct torture_context
*tctx
,
838 struct dcerpc_binding_handle
*b
,
839 const char *environment
,
842 union spoolss_PrintProcessorInfo
**info_p
,
843 WERROR expected_result
)
845 struct spoolss_EnumPrintProcessors r
;
849 union spoolss_PrintProcessorInfo
*info
;
851 r
.in
.servername
= "";
852 r
.in
.environment
= environment
;
856 r
.out
.needed
= &needed
;
857 r
.out
.count
= &count
;
860 torture_comment(tctx
, "Testing EnumPrintProcessors(%s) level %u\n",
861 r
.in
.environment
, r
.in
.level
);
863 torture_assert_ntstatus_ok(tctx
,
864 dcerpc_spoolss_EnumPrintProcessors_r(b
, tctx
, &r
),
865 "EnumPrintProcessors failed");
866 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
867 blob
= data_blob_talloc_zero(tctx
, needed
);
869 r
.in
.offered
= needed
;
870 torture_assert_ntstatus_ok(tctx
,
871 dcerpc_spoolss_EnumPrintProcessors_r(b
, tctx
, &r
),
872 "EnumPrintProcessors failed");
874 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
875 "EnumPrintProcessors failed");
877 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors
, info
, level
, count
, needed
, 4);
889 static bool test_EnumPrintProcessors(struct torture_context
*tctx
,
892 struct test_spoolss_context
*ctx
=
893 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
895 uint16_t levels
[] = {0, 1, 2, 3, 32, 256 };
896 uint16_t ok
[] = {0, 1, 0, 0, 0, 0 };
898 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
899 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
902 test_EnumPrintProcessors_level(tctx
, b
, "phantasy", 1, NULL
, NULL
, WERR_INVALID_ENVIRONMENT
),
903 "test_EnumPrintProcessors_level failed");
905 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
906 union spoolss_PrintProcessorInfo
*info
;
908 WERROR expected_result
= ok
[i
] ? WERR_OK
: WERR_INVALID_LEVEL
;
911 test_EnumPrintProcessors_level(tctx
, b
, ctx
->environment
, levels
[i
], &count
, &info
, expected_result
),
912 "test_EnumPrintProcessors_level failed");
918 static bool test_EnumPrintProcDataTypes_level(struct torture_context
*tctx
,
919 struct dcerpc_binding_handle
*b
,
920 const char *print_processor_name
,
923 union spoolss_PrintProcDataTypesInfo
**info_p
,
924 WERROR expected_result
)
926 struct spoolss_EnumPrintProcDataTypes r
;
930 union spoolss_PrintProcDataTypesInfo
*info
;
932 r
.in
.servername
= "";
933 r
.in
.print_processor_name
= print_processor_name
;
937 r
.out
.needed
= &needed
;
938 r
.out
.count
= &count
;
941 torture_comment(tctx
, "Testing EnumPrintProcDataTypes(%s) level %u\n",
942 r
.in
.print_processor_name
, r
.in
.level
);
944 torture_assert_ntstatus_ok(tctx
,
945 dcerpc_spoolss_EnumPrintProcDataTypes_r(b
, tctx
, &r
),
946 "EnumPrintProcDataTypes failed");
947 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
948 blob
= data_blob_talloc_zero(tctx
, needed
);
950 r
.in
.offered
= needed
;
951 torture_assert_ntstatus_ok(tctx
,
952 dcerpc_spoolss_EnumPrintProcDataTypes_r(b
, tctx
, &r
),
953 "EnumPrintProcDataTypes failed");
955 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
956 "EnumPrintProcDataTypes failed");
958 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcDataTypes
, info
, level
, count
, needed
, 4);
970 static bool test_EnumPrintProcDataTypes(struct torture_context
*tctx
,
973 struct test_spoolss_context
*ctx
=
974 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
976 uint16_t levels
[] = {0, 1, 2, 3, 32, 256 };
977 uint16_t ok
[] = {0, 1, 0, 0, 0, 0 };
979 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
980 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
983 test_EnumPrintProcDataTypes_level(tctx
, b
, NULL
, 1, NULL
, NULL
, WERR_UNKNOWN_PRINTPROCESSOR
),
984 "test_EnumPrintProcDataTypes_level failed");
987 test_EnumPrintProcDataTypes_level(tctx
, b
, "nonexisting", 1, NULL
, NULL
, WERR_UNKNOWN_PRINTPROCESSOR
),
988 "test_EnumPrintProcDataTypes_level failed");
990 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
991 int level
= levels
[i
];
993 union spoolss_PrintProcDataTypesInfo
*info
;
994 WERROR expected_result
= ok
[i
] ? WERR_OK
: WERR_INVALID_LEVEL
;
997 test_EnumPrintProcDataTypes_level(tctx
, b
, "winprint", level
, &count
, &info
, expected_result
),
998 "test_EnumPrintProcDataTypes_level failed");
1002 union spoolss_PrintProcessorInfo
*info
;
1005 torture_assert(tctx
,
1006 test_EnumPrintProcessors_level(tctx
, b
, ctx
->environment
, 1, &count
, &info
, WERR_OK
),
1007 "test_EnumPrintProcessors_level failed");
1009 for (i
=0; i
< count
; i
++) {
1010 torture_assert(tctx
,
1011 test_EnumPrintProcDataTypes_level(tctx
, b
, info
[i
].info1
.print_processor_name
, 1, NULL
, NULL
, WERR_OK
),
1012 "test_EnumPrintProcDataTypes_level failed");
1020 static bool test_EnumPrinters(struct torture_context
*tctx
,
1023 struct test_spoolss_context
*ctx
=
1024 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
1025 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
1026 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1027 struct spoolss_EnumPrinters r
;
1029 uint16_t levels
[] = { 0, 1, 2, 4, 5 };
1032 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1033 int level
= levels
[i
];
1037 union spoolss_PrinterInfo
*info
;
1039 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
1044 r
.out
.needed
= &needed
;
1045 r
.out
.count
= &count
;
1048 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
1050 status
= dcerpc_spoolss_EnumPrinters_r(b
, ctx
, &r
);
1051 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
1052 if (W_ERROR_IS_OK(r
.out
.result
)) {
1053 /* TODO: do some more checks here */
1056 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
1057 "EnumPrinters unexpected return code");
1059 blob
= data_blob_talloc_zero(ctx
, needed
);
1060 r
.in
.buffer
= &blob
;
1061 r
.in
.offered
= needed
;
1063 status
= dcerpc_spoolss_EnumPrinters_r(b
, ctx
, &r
);
1064 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
1066 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
1068 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters
, info
, r
.in
.level
, count
, needed
, 4);
1070 ctx
->printer_count
[level
] = count
;
1071 ctx
->printers
[level
] = info
;
1074 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
1075 int level
= levels
[i
];
1076 int old_level
= levels
[i
-1];
1077 torture_assert_int_equal(tctx
, ctx
->printer_count
[level
], ctx
->printer_count
[old_level
],
1078 "EnumPrinters invalid value");
1081 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1082 int level
= levels
[i
];
1083 for (j
=0;j
<ctx
->printer_count
[level
];j
++) {
1084 union spoolss_PrinterInfo
*cur
= &ctx
->printers
[level
][j
];
1085 union spoolss_PrinterInfo
*ref
= &ctx
->printers
[2][j
];
1088 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, printername
);
1089 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, servername
);
1090 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, cjobs
);
1091 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
1092 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
1093 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
1094 COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
1095 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
1096 COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
1097 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
1098 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
1099 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
1100 COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
1101 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
1102 COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
1103 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
1104 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
1105 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
1106 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
1107 COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
1108 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
1109 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, status
);
1110 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
1111 COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
1112 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
1113 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
1114 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
1115 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
1116 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
1119 /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
1120 /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
1121 /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
1122 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, comment
);
1125 /* level 2 is our reference, and it makes no sense to compare it to itself */
1128 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, printername
);
1129 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, servername
);
1130 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info2
, attributes
);
1133 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, printername
);
1134 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, portname
);
1135 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info2
, attributes
);
1136 /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
1137 COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
1144 * - verify that the port of a printer was in the list returned by EnumPorts
1150 static bool test_GetPrinterDriver2(struct torture_context
*tctx
,
1151 struct dcerpc_binding_handle
*b
,
1152 struct policy_handle
*handle
,
1153 const char *driver_name
,
1154 const char *environment
);
1156 bool test_GetPrinter_level(struct torture_context
*tctx
,
1157 struct dcerpc_binding_handle
*b
,
1158 struct policy_handle
*handle
,
1160 union spoolss_PrinterInfo
*info
)
1162 struct spoolss_GetPrinter r
;
1165 r
.in
.handle
= handle
;
1169 r
.out
.needed
= &needed
;
1171 torture_comment(tctx
, "Testing GetPrinter level %u\n", r
.in
.level
);
1173 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_GetPrinter_r(b
, tctx
, &r
),
1174 "GetPrinter failed");
1176 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1177 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
1178 r
.in
.buffer
= &blob
;
1179 r
.in
.offered
= needed
;
1181 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_GetPrinter_r(b
, tctx
, &r
),
1182 "GetPrinter failed");
1185 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinter failed");
1187 CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo
, r
.out
.info
, r
.in
.level
, needed
, 4);
1189 if (info
&& r
.out
.info
) {
1190 *info
= *r
.out
.info
;
1197 static bool test_GetPrinter(struct torture_context
*tctx
,
1198 struct dcerpc_binding_handle
*b
,
1199 struct policy_handle
*handle
,
1200 const char *environment
)
1202 uint32_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1205 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1207 union spoolss_PrinterInfo info
;
1211 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, levels
[i
], &info
),
1212 "failed to call GetPrinter");
1214 if ((levels
[i
] == 2) && info
.info2
.drivername
&& strlen(info
.info2
.drivername
)) {
1215 torture_assert(tctx
,
1216 test_GetPrinterDriver2(tctx
, b
, handle
, info
.info2
.drivername
, environment
),
1217 "failed to call test_GetPrinterDriver2");
1224 static bool test_SetPrinter(struct torture_context
*tctx
,
1225 struct dcerpc_binding_handle
*b
,
1226 struct policy_handle
*handle
,
1227 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
1228 struct spoolss_DevmodeContainer
*devmode_ctr
,
1229 struct sec_desc_buf
*secdesc_ctr
,
1230 enum spoolss_PrinterControl command
)
1232 struct spoolss_SetPrinter r
;
1234 r
.in
.handle
= handle
;
1235 r
.in
.info_ctr
= info_ctr
;
1236 r
.in
.devmode_ctr
= devmode_ctr
;
1237 r
.in
.secdesc_ctr
= secdesc_ctr
;
1238 r
.in
.command
= command
;
1240 torture_comment(tctx
, "Testing SetPrinter level %d\n", r
.in
.info_ctr
->level
);
1242 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetPrinter_r(b
, tctx
, &r
),
1243 "failed to call SetPrinter");
1244 torture_assert_werr_ok(tctx
, r
.out
.result
,
1245 "failed to call SetPrinter");
1250 static bool test_SetPrinter_errors(struct torture_context
*tctx
,
1251 struct dcerpc_binding_handle
*b
,
1252 struct policy_handle
*handle
)
1254 struct spoolss_SetPrinter r
;
1255 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1258 struct spoolss_SetPrinterInfoCtr info_ctr
;
1259 struct spoolss_DevmodeContainer devmode_ctr
;
1260 struct sec_desc_buf secdesc_ctr
;
1263 info_ctr
.info
.info0
= NULL
;
1265 ZERO_STRUCT(devmode_ctr
);
1266 ZERO_STRUCT(secdesc_ctr
);
1268 r
.in
.handle
= handle
;
1269 r
.in
.info_ctr
= &info_ctr
;
1270 r
.in
.devmode_ctr
= &devmode_ctr
;
1271 r
.in
.secdesc_ctr
= &secdesc_ctr
;
1274 torture_comment(tctx
, "Testing SetPrinter all zero\n");
1276 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetPrinter_r(b
, tctx
, &r
),
1277 "failed to call SetPrinter");
1278 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1279 "failed to call SetPrinter");
1282 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
1284 struct spoolss_SetPrinterInfo0 info0
;
1285 struct spoolss_SetPrinterInfo1 info1
;
1286 struct spoolss_SetPrinterInfo2 info2
;
1287 struct spoolss_SetPrinterInfo3 info3
;
1288 struct spoolss_SetPrinterInfo4 info4
;
1289 struct spoolss_SetPrinterInfo5 info5
;
1290 struct spoolss_SetPrinterInfo6 info6
;
1291 struct spoolss_SetPrinterInfo7 info7
;
1292 struct spoolss_SetPrinterInfo8 info8
;
1293 struct spoolss_SetPrinterInfo9 info9
;
1296 info_ctr
.level
= levels
[i
];
1297 switch (levels
[i
]) {
1300 info_ctr
.info
.info0
= &info0
;
1304 info_ctr
.info
.info1
= &info1
;
1308 info_ctr
.info
.info2
= &info2
;
1312 info_ctr
.info
.info3
= &info3
;
1316 info_ctr
.info
.info4
= &info4
;
1320 info_ctr
.info
.info5
= &info5
;
1324 info_ctr
.info
.info6
= &info6
;
1328 info_ctr
.info
.info7
= &info7
;
1332 info_ctr
.info
.info8
= &info8
;
1336 info_ctr
.info
.info9
= &info9
;
1340 torture_comment(tctx
, "Testing SetPrinter level %d, command %d\n",
1341 info_ctr
.level
, r
.in
.command
);
1343 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetPrinter_r(b
, tctx
, &r
),
1344 "failed to call SetPrinter");
1346 switch (r
.in
.command
) {
1347 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
: /* 0 */
1348 /* is ignored for all levels other then 0 */
1349 if (info_ctr
.level
> 0) {
1353 case SPOOLSS_PRINTER_CONTROL_PAUSE
: /* 1 */
1354 case SPOOLSS_PRINTER_CONTROL_RESUME
: /* 2 */
1355 case SPOOLSS_PRINTER_CONTROL_PURGE
: /* 3 */
1356 if (info_ctr
.level
> 0) {
1357 /* is invalid for all levels other then 0 */
1358 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PRINTER_COMMAND
,
1359 "unexpected error code returned");
1362 torture_assert_werr_ok(tctx
, r
.out
.result
,
1363 "failed to call SetPrinter with non 0 command");
1368 case SPOOLSS_PRINTER_CONTROL_SET_STATUS
: /* 4 */
1369 /* FIXME: gd needs further investigation */
1371 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PRINTER_COMMAND
,
1372 "unexpected error code returned");
1376 switch (info_ctr
.level
) {
1378 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
,
1379 "unexpected error code returned");
1382 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_PRINTER_DRIVER
,
1383 "unexpected error code returned");
1389 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1390 "unexpected error code returned");
1393 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
1394 "unexpected error code returned");
1397 torture_assert_werr_ok(tctx
, r
.out
.result
,
1398 "failed to call SetPrinter");
1403 if (r
.in
.command
< 5) {
1411 static void clear_info2(struct spoolss_SetPrinterInfoCtr
*r
)
1413 if ((r
->level
== 2) && (r
->info
.info2
)) {
1414 r
->info
.info2
->secdesc_ptr
= 0;
1415 r
->info
.info2
->devmode_ptr
= 0;
1419 static bool test_PrinterInfo(struct torture_context
*tctx
,
1420 struct dcerpc_binding_handle
*b
,
1421 struct policy_handle
*handle
)
1424 struct spoolss_SetPrinter s
;
1425 struct spoolss_GetPrinter q
;
1426 struct spoolss_GetPrinter q0
;
1427 struct spoolss_SetPrinterInfoCtr info_ctr
;
1428 union spoolss_PrinterInfo info
;
1429 struct spoolss_DevmodeContainer devmode_ctr
;
1430 struct sec_desc_buf secdesc_ctr
;
1435 torture_skip(tctx
, "Printer Info test is currently broken, skipping");
1437 uint32_t status_list
[] = {
1438 /* these do not stick
1439 PRINTER_STATUS_PAUSED,
1440 PRINTER_STATUS_ERROR,
1441 PRINTER_STATUS_PENDING_DELETION, */
1442 PRINTER_STATUS_PAPER_JAM
,
1443 PRINTER_STATUS_PAPER_OUT
,
1444 PRINTER_STATUS_MANUAL_FEED
,
1445 PRINTER_STATUS_PAPER_PROBLEM
,
1446 PRINTER_STATUS_OFFLINE
,
1447 PRINTER_STATUS_IO_ACTIVE
,
1448 PRINTER_STATUS_BUSY
,
1449 PRINTER_STATUS_PRINTING
,
1450 PRINTER_STATUS_OUTPUT_BIN_FULL
,
1451 PRINTER_STATUS_NOT_AVAILABLE
,
1452 PRINTER_STATUS_WAITING
,
1453 PRINTER_STATUS_PROCESSING
,
1454 PRINTER_STATUS_INITIALIZING
,
1455 PRINTER_STATUS_WARMING_UP
,
1456 PRINTER_STATUS_TONER_LOW
,
1457 PRINTER_STATUS_NO_TONER
,
1458 PRINTER_STATUS_PAGE_PUNT
,
1459 PRINTER_STATUS_USER_INTERVENTION
,
1460 PRINTER_STATUS_OUT_OF_MEMORY
,
1461 PRINTER_STATUS_DOOR_OPEN
,
1462 PRINTER_STATUS_SERVER_UNKNOWN
,
1463 PRINTER_STATUS_POWER_SAVE
,
1464 /* these do not stick
1473 uint32_t default_attribute
= PRINTER_ATTRIBUTE_LOCAL
;
1474 uint32_t attribute_list
[] = {
1475 PRINTER_ATTRIBUTE_QUEUED
,
1476 /* fails with WERR_INVALID_DATATYPE:
1477 PRINTER_ATTRIBUTE_DIRECT, */
1479 PRINTER_ATTRIBUTE_DEFAULT, */
1480 PRINTER_ATTRIBUTE_SHARED
,
1482 PRINTER_ATTRIBUTE_NETWORK, */
1483 PRINTER_ATTRIBUTE_HIDDEN
,
1484 PRINTER_ATTRIBUTE_LOCAL
,
1485 PRINTER_ATTRIBUTE_ENABLE_DEVQ
,
1486 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
,
1487 PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST
,
1488 PRINTER_ATTRIBUTE_WORK_OFFLINE
,
1490 PRINTER_ATTRIBUTE_ENABLE_BIDI, */
1491 /* fails with WERR_INVALID_DATATYPE:
1492 PRINTER_ATTRIBUTE_RAW_ONLY, */
1493 /* these do not stick
1494 PRINTER_ATTRIBUTE_PUBLISHED,
1495 PRINTER_ATTRIBUTE_FAX,
1496 PRINTER_ATTRIBUTE_TS,
1515 ZERO_STRUCT(devmode_ctr
);
1516 ZERO_STRUCT(secdesc_ctr
);
1518 s
.in
.handle
= handle
;
1520 s
.in
.info_ctr
= &info_ctr
;
1521 s
.in
.devmode_ctr
= &devmode_ctr
;
1522 s
.in
.secdesc_ctr
= &secdesc_ctr
;
1524 q
.in
.handle
= handle
;
1528 #define TESTGETCALL(call, r) \
1529 r.in.buffer = NULL; \
1531 r.out.needed = &needed; \
1532 status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1533 if (!NT_STATUS_IS_OK(status)) { \
1534 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1535 r.in.level, nt_errstr(status), __location__); \
1539 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
1540 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed); \
1541 r.in.buffer = &blob; \
1542 r.in.offered = needed; \
1544 status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1545 if (!NT_STATUS_IS_OK(status)) { \
1546 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1547 r.in.level, nt_errstr(status), __location__); \
1551 if (!W_ERROR_IS_OK(r.out.result)) { \
1552 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1553 r.in.level, win_errstr(r.out.result), __location__); \
1559 #define TESTSETCALL_EXP(call, r, err) \
1560 clear_info2(&info_ctr);\
1561 status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1562 if (!NT_STATUS_IS_OK(status)) { \
1563 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1564 r.in.info_ctr->level, nt_errstr(status), __location__); \
1568 if (!W_ERROR_IS_OK(err)) { \
1569 if (!W_ERROR_EQUAL(err, r.out.result)) { \
1570 torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
1571 r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
1576 if (!W_ERROR_IS_OK(r.out.result)) { \
1577 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1578 r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
1583 #define TESTSETCALL(call, r) \
1584 TESTSETCALL_EXP(call, r, WERR_OK)
1586 #define STRING_EQUAL(s1, s2, field) \
1587 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
1588 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1589 #field, s2, __location__); \
1594 #define MEM_EQUAL(s1, s2, length, field) \
1595 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
1596 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1597 #field, (const char *)s2, __location__); \
1602 #define INT_EQUAL(i1, i2, field) \
1604 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
1605 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
1610 #define SD_EQUAL(sd1, sd2, field) \
1611 if (!security_descriptor_equal(sd1, sd2)) { \
1612 torture_comment(tctx, "Failed to set %s (%s)\n", \
1613 #field, __location__); \
1618 #define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
1619 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1620 q.in.level = lvl1; \
1621 TESTGETCALL(GetPrinter, q) \
1622 info_ctr.level = lvl1; \
1623 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)(void *)&q.out.info->info ## lvl1; \
1624 info_ctr.info.info ## lvl1->field1 = value;\
1625 TESTSETCALL_EXP(SetPrinter, s, err) \
1626 info_ctr.info.info ## lvl1->field1 = ""; \
1627 TESTGETCALL(GetPrinter, q) \
1628 info_ctr.info.info ## lvl1->field1 = value; \
1629 STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
1630 q.in.level = lvl2; \
1631 TESTGETCALL(GetPrinter, q) \
1632 info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)(void *)&q.out.info->info ## lvl2; \
1633 STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
1636 #define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
1637 TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
1640 #define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
1641 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1642 q.in.level = lvl1; \
1643 TESTGETCALL(GetPrinter, q) \
1644 info_ctr.level = lvl1; \
1645 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)(void *)&q.out.info->info ## lvl1; \
1646 info_ctr.info.info ## lvl1->field1 = value; \
1647 TESTSETCALL(SetPrinter, s) \
1648 info_ctr.info.info ## lvl1->field1 = 0; \
1649 TESTGETCALL(GetPrinter, q) \
1650 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)(void *)&q.out.info->info ## lvl1; \
1651 INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
1652 q.in.level = lvl2; \
1653 TESTGETCALL(GetPrinter, q) \
1654 info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)(void *)&q.out.info->info ## lvl2; \
1655 INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
1658 #define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
1659 TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
1663 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1665 TEST_PRINTERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment");
1666 TEST_PRINTERINFO_STRING(2, comment
, 2, comment
, "xx2-2 comment");
1668 /* level 0 printername does not stick */
1669 /* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
1670 TEST_PRINTERINFO_STRING(2, printername
, 1, name
, "xx2-1 printer");
1671 TEST_PRINTERINFO_STRING(2, printername
, 2, printername
, "xx2-2 printer");
1672 TEST_PRINTERINFO_STRING(2, printername
, 4, printername
, "xx2-4 printer");
1673 TEST_PRINTERINFO_STRING(2, printername
, 5, printername
, "xx2-5 printer");
1674 /* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
1675 TEST_PRINTERINFO_STRING(4, printername
, 1, name
, "xx4-1 printer");
1676 TEST_PRINTERINFO_STRING(4, printername
, 2, printername
, "xx4-2 printer");
1677 TEST_PRINTERINFO_STRING(4, printername
, 4, printername
, "xx4-4 printer");
1678 TEST_PRINTERINFO_STRING(4, printername
, 5, printername
, "xx4-5 printer");
1679 /* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
1680 TEST_PRINTERINFO_STRING(5, printername
, 1, name
, "xx5-1 printer");
1681 TEST_PRINTERINFO_STRING(5, printername
, 2, printername
, "xx5-2 printer");
1682 TEST_PRINTERINFO_STRING(5, printername
, 4, printername
, "xx5-4 printer");
1683 TEST_PRINTERINFO_STRING(5, printername
, 5, printername
, "xx5-5 printer");
1685 /* servername can be set but does not stick
1686 TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername");
1687 TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername");
1688 TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername");
1691 /* passing an invalid port will result in WERR_UNKNOWN_PORT */
1692 TEST_PRINTERINFO_STRING_EXP_ERR(2, portname
, 2, portname
, "xx2-2 portname", WERR_UNKNOWN_PORT
);
1693 TEST_PRINTERINFO_STRING_EXP_ERR(2, portname
, 5, portname
, "xx2-5 portname", WERR_UNKNOWN_PORT
);
1694 TEST_PRINTERINFO_STRING_EXP_ERR(5, portname
, 2, portname
, "xx5-2 portname", WERR_UNKNOWN_PORT
);
1695 TEST_PRINTERINFO_STRING_EXP_ERR(5, portname
, 5, portname
, "xx5-5 portname", WERR_UNKNOWN_PORT
);
1697 TEST_PRINTERINFO_STRING(2, sharename
, 2, sharename
, "xx2-2 sharename");
1698 /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
1699 TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername
, 2, drivername
, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER
);
1700 TEST_PRINTERINFO_STRING(2, location
, 2, location
, "xx2-2 location");
1701 /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
1702 TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile
, 2, sepfile
, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE
);
1703 /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
1704 TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor
, 2, printprocessor
, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR
);
1705 TEST_PRINTERINFO_STRING(2, datatype
, 2, datatype
, "xx2-2 datatype");
1706 TEST_PRINTERINFO_STRING(2, parameters
, 2, parameters
, "xx2-2 parameters");
1708 for (i
=0; i
< ARRAY_SIZE(attribute_list
); i
++) {
1709 /* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
1711 (attribute_list[i] | default_attribute)
1713 TEST_PRINTERINFO_INT_EXP(2, attributes
, 2, attributes
,
1715 (attribute_list
[i
] | default_attribute
)
1717 TEST_PRINTERINFO_INT_EXP(2, attributes
, 4, attributes
,
1719 (attribute_list
[i
] | default_attribute
)
1721 TEST_PRINTERINFO_INT_EXP(2, attributes
, 5, attributes
,
1723 (attribute_list
[i
] | default_attribute
)
1725 /* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
1727 (attribute_list[i] | default_attribute)
1729 TEST_PRINTERINFO_INT_EXP(4, attributes
, 2, attributes
,
1731 (attribute_list
[i
] | default_attribute
)
1733 TEST_PRINTERINFO_INT_EXP(4, attributes
, 4, attributes
,
1735 (attribute_list
[i
] | default_attribute
)
1737 TEST_PRINTERINFO_INT_EXP(4, attributes
, 5, attributes
,
1739 (attribute_list
[i
] | default_attribute
)
1741 /* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
1743 (attribute_list[i] | default_attribute)
1745 TEST_PRINTERINFO_INT_EXP(5, attributes
, 2, attributes
,
1747 (attribute_list
[i
] | default_attribute
)
1749 TEST_PRINTERINFO_INT_EXP(5, attributes
, 4, attributes
,
1751 (attribute_list
[i
] | default_attribute
)
1753 TEST_PRINTERINFO_INT_EXP(5, attributes
, 5, attributes
,
1755 (attribute_list
[i
] | default_attribute
)
1759 for (i
=0; i
< ARRAY_SIZE(status_list
); i
++) {
1760 /* level 2 sets do not stick
1761 TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
1762 TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
1763 TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
1764 TEST_PRINTERINFO_INT(6, status
, 0, status
, status_list
[i
]);
1765 TEST_PRINTERINFO_INT(6, status
, 2, status
, status_list
[i
]);
1766 TEST_PRINTERINFO_INT(6, status
, 6, status
, status_list
[i
]);
1769 /* priorities need to be between 0 and 99
1770 passing an invalid priority will result in WERR_INVALID_PRIORITY */
1771 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 0);
1772 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 1);
1773 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 99);
1774 /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
1775 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 0);
1776 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 1);
1777 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 99);
1778 /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
1780 TEST_PRINTERINFO_INT(2, starttime
, 2, starttime
, __LINE__
);
1781 TEST_PRINTERINFO_INT(2, untiltime
, 2, untiltime
, __LINE__
);
1784 TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__);
1785 TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */
1788 TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
1789 TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
1791 /* FIXME: gd also test devmode and secdesc behavior */
1794 /* verify composition of level 1 description field */
1795 const char *description
;
1799 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1801 description
= talloc_strdup(tctx
, q0
.out
.info
->info1
.description
);
1804 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1806 tmp
= talloc_asprintf(tctx
, "%s,%s,%s",
1807 q0
.out
.info
->info2
.printername
,
1808 q0
.out
.info
->info2
.drivername
,
1809 q0
.out
.info
->info2
.location
);
1811 do { STRING_EQUAL(description
, tmp
, "description")} while (0);
1817 static bool test_security_descriptor_equal(struct torture_context
*tctx
,
1818 const struct security_descriptor
*sd1
,
1819 const struct security_descriptor
*sd2
)
1826 torture_comment(tctx
, "%s\n", __location__
);
1830 torture_assert_int_equal(tctx
, sd1
->revision
, sd2
->revision
, "revision mismatch");
1831 torture_assert_int_equal(tctx
, sd1
->type
, sd2
->type
, "type mismatch");
1833 torture_assert_sid_equal(tctx
, sd1
->owner_sid
, sd2
->owner_sid
, "owner mismatch");
1834 torture_assert_sid_equal(tctx
, sd1
->group_sid
, sd2
->group_sid
, "group mismatch");
1836 if (!security_acl_equal(sd1
->sacl
, sd2
->sacl
)) {
1837 torture_comment(tctx
, "%s: sacl mismatch\n", __location__
);
1838 NDR_PRINT_DEBUG(security_acl
, sd1
->sacl
);
1839 NDR_PRINT_DEBUG(security_acl
, sd2
->sacl
);
1842 if (!security_acl_equal(sd1
->dacl
, sd2
->dacl
)) {
1843 torture_comment(tctx
, "%s: dacl mismatch\n", __location__
);
1844 NDR_PRINT_DEBUG(security_acl
, sd1
->dacl
);
1845 NDR_PRINT_DEBUG(security_acl
, sd2
->dacl
);
1852 static bool test_sd_set_level(struct torture_context
*tctx
,
1853 struct dcerpc_binding_handle
*b
,
1854 struct policy_handle
*handle
,
1856 struct security_descriptor
*sd
)
1858 struct spoolss_SetPrinterInfoCtr info_ctr
;
1859 struct spoolss_DevmodeContainer devmode_ctr
;
1860 struct sec_desc_buf secdesc_ctr
;
1861 union spoolss_SetPrinterInfo sinfo
;
1863 ZERO_STRUCT(devmode_ctr
);
1864 ZERO_STRUCT(secdesc_ctr
);
1868 union spoolss_PrinterInfo info
;
1869 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1870 torture_assert(tctx
, PrinterInfo_to_SetPrinterInfo(tctx
, &info
, 2, &sinfo
), "");
1873 info_ctr
.info
= sinfo
;
1878 struct spoolss_SetPrinterInfo3 info3
;
1880 info3
.sec_desc_ptr
= 0;
1883 info_ctr
.info
.info3
= &info3
;
1891 secdesc_ctr
.sd
= sd
;
1893 torture_assert(tctx
,
1894 test_SetPrinter(tctx
, b
, handle
, &info_ctr
, &devmode_ctr
, &secdesc_ctr
, 0), "");
1899 static bool test_PrinterInfo_SDs(struct torture_context
*tctx
,
1900 struct dcerpc_binding_handle
*b
,
1901 struct policy_handle
*handle
)
1903 union spoolss_PrinterInfo info
;
1904 struct security_descriptor
*sd1
, *sd2
;
1907 /* just compare level 2 and level 3 */
1909 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1911 sd1
= info
.info2
.secdesc
;
1913 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 3, &info
), "");
1915 sd2
= info
.info3
.secdesc
;
1917 torture_assert(tctx
, test_security_descriptor_equal(tctx
, sd1
, sd2
),
1918 "SD level 2 != SD level 3");
1921 /* query level 2, set level 2, query level 2 */
1923 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1925 sd1
= info
.info2
.secdesc
;
1927 torture_assert(tctx
, test_sd_set_level(tctx
, b
, handle
, 2, sd1
), "");
1929 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1931 sd2
= info
.info2
.secdesc
;
1932 if (sd1
->type
& SEC_DESC_DACL_DEFAULTED
) {
1933 torture_comment(tctx
, "removing SEC_DESC_DACL_DEFAULTED\n");
1934 sd1
->type
&= ~SEC_DESC_DACL_DEFAULTED
;
1937 torture_assert(tctx
, test_security_descriptor_equal(tctx
, sd1
, sd2
),
1938 "SD level 2 != SD level 2 after SD has been set via level 2");
1941 /* query level 2, set level 3, query level 2 */
1943 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1945 sd1
= info
.info2
.secdesc
;
1947 torture_assert(tctx
, test_sd_set_level(tctx
, b
, handle
, 3, sd1
), "");
1949 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1951 sd2
= info
.info2
.secdesc
;
1953 torture_assert(tctx
, test_security_descriptor_equal(tctx
, sd1
, sd2
),
1954 "SD level 2 != SD level 2 after SD has been set via level 3");
1956 /* set modified sd level 3, query level 2 */
1958 for (i
=0; i
< 93; i
++) {
1959 struct security_ace a
;
1960 const char *sid_string
= talloc_asprintf(tctx
, "S-1-5-32-9999%i", i
);
1961 a
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
1963 a
.size
= 0; /* autogenerated */
1965 a
.trustee
= *dom_sid_parse_talloc(tctx
, sid_string
);
1966 torture_assert_ntstatus_ok(tctx
, security_descriptor_dacl_add(sd1
, &a
), "");
1969 torture_assert(tctx
, test_sd_set_level(tctx
, b
, handle
, 3, sd1
), "");
1971 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
1972 sd2
= info
.info2
.secdesc
;
1974 if (sd1
->type
& SEC_DESC_DACL_DEFAULTED
) {
1975 torture_comment(tctx
, "removing SEC_DESC_DACL_DEFAULTED\n");
1976 sd1
->type
&= ~SEC_DESC_DACL_DEFAULTED
;
1979 torture_assert(tctx
, test_security_descriptor_equal(tctx
, sd1
, sd2
),
1980 "modified SD level 2 != SD level 2 after SD has been set via level 3");
1987 * wrapper call that saves original sd, runs tests, and restores sd
1990 static bool test_PrinterInfo_SD(struct torture_context
*tctx
,
1991 struct dcerpc_binding_handle
*b
,
1992 struct policy_handle
*handle
)
1994 union spoolss_PrinterInfo info
;
1995 struct security_descriptor
*sd
;
1998 torture_comment(tctx
, "Testing Printer Security Descriptors\n");
2000 /* save original sd */
2002 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
2003 "failed to get initial security descriptor");
2005 sd
= security_descriptor_copy(tctx
, info
.info2
.secdesc
);
2009 ret
= test_PrinterInfo_SDs(tctx
, b
, handle
);
2011 /* restore original sd */
2013 torture_assert(tctx
, test_sd_set_level(tctx
, b
, handle
, 3, sd
),
2014 "failed to restore initial security descriptor");
2016 torture_comment(tctx
, "Printer Security Descriptors test %s\n\n",
2017 ret
? "succeeded" : "failed");
2023 static bool test_devmode_set_level(struct torture_context
*tctx
,
2024 struct dcerpc_binding_handle
*b
,
2025 struct policy_handle
*handle
,
2027 struct spoolss_DeviceMode
*devmode
)
2029 struct spoolss_SetPrinterInfoCtr info_ctr
;
2030 struct spoolss_DevmodeContainer devmode_ctr
;
2031 struct sec_desc_buf secdesc_ctr
;
2032 union spoolss_SetPrinterInfo sinfo
;
2034 ZERO_STRUCT(devmode_ctr
);
2035 ZERO_STRUCT(secdesc_ctr
);
2039 union spoolss_PrinterInfo info
;
2040 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
2041 torture_assert(tctx
, PrinterInfo_to_SetPrinterInfo(tctx
, &info
, 2, &sinfo
), "");
2044 info_ctr
.info
= sinfo
;
2049 struct spoolss_SetPrinterInfo8 info8
;
2051 info8
.devmode_ptr
= 0;
2054 info_ctr
.info
.info8
= &info8
;
2062 devmode_ctr
.devmode
= devmode
;
2064 torture_assert(tctx
,
2065 test_SetPrinter(tctx
, b
, handle
, &info_ctr
, &devmode_ctr
, &secdesc_ctr
, 0), "");
2071 static bool test_devicemode_equal(struct torture_context
*tctx
,
2072 const struct spoolss_DeviceMode
*d1
,
2073 const struct spoolss_DeviceMode
*d2
)
2080 torture_comment(tctx
, "%s\n", __location__
);
2083 torture_assert_str_equal(tctx
, d1
->devicename
, d2
->devicename
, "devicename mismatch");
2084 torture_assert_int_equal(tctx
, d1
->specversion
, d2
->specversion
, "specversion mismatch");
2085 torture_assert_int_equal(tctx
, d1
->driverversion
, d2
->driverversion
, "driverversion mismatch");
2086 torture_assert_int_equal(tctx
, d1
->size
, d2
->size
, "size mismatch");
2087 torture_assert_int_equal(tctx
, d1
->__driverextra_length
, d2
->__driverextra_length
, "__driverextra_length mismatch");
2088 torture_assert_int_equal(tctx
, d1
->fields
, d2
->fields
, "fields mismatch");
2089 torture_assert_int_equal(tctx
, d1
->orientation
, d2
->orientation
, "orientation mismatch");
2090 torture_assert_int_equal(tctx
, d1
->papersize
, d2
->papersize
, "papersize mismatch");
2091 torture_assert_int_equal(tctx
, d1
->paperlength
, d2
->paperlength
, "paperlength mismatch");
2092 torture_assert_int_equal(tctx
, d1
->paperwidth
, d2
->paperwidth
, "paperwidth mismatch");
2093 torture_assert_int_equal(tctx
, d1
->scale
, d2
->scale
, "scale mismatch");
2094 torture_assert_int_equal(tctx
, d1
->copies
, d2
->copies
, "copies mismatch");
2095 torture_assert_int_equal(tctx
, d1
->defaultsource
, d2
->defaultsource
, "defaultsource mismatch");
2096 torture_assert_int_equal(tctx
, d1
->printquality
, d2
->printquality
, "printquality mismatch");
2097 torture_assert_int_equal(tctx
, d1
->color
, d2
->color
, "color mismatch");
2098 torture_assert_int_equal(tctx
, d1
->duplex
, d2
->duplex
, "duplex mismatch");
2099 torture_assert_int_equal(tctx
, d1
->yresolution
, d2
->yresolution
, "yresolution mismatch");
2100 torture_assert_int_equal(tctx
, d1
->ttoption
, d2
->ttoption
, "ttoption mismatch");
2101 torture_assert_int_equal(tctx
, d1
->collate
, d2
->collate
, "collate mismatch");
2102 torture_assert_str_equal(tctx
, d1
->formname
, d2
->formname
, "formname mismatch");
2103 torture_assert_int_equal(tctx
, d1
->logpixels
, d2
->logpixels
, "logpixels mismatch");
2104 torture_assert_int_equal(tctx
, d1
->bitsperpel
, d2
->bitsperpel
, "bitsperpel mismatch");
2105 torture_assert_int_equal(tctx
, d1
->pelswidth
, d2
->pelswidth
, "pelswidth mismatch");
2106 torture_assert_int_equal(tctx
, d1
->pelsheight
, d2
->pelsheight
, "pelsheight mismatch");
2107 torture_assert_int_equal(tctx
, d1
->displayflags
, d2
->displayflags
, "displayflags mismatch");
2108 torture_assert_int_equal(tctx
, d1
->displayfrequency
, d2
->displayfrequency
, "displayfrequency mismatch");
2109 torture_assert_int_equal(tctx
, d1
->icmmethod
, d2
->icmmethod
, "icmmethod mismatch");
2110 torture_assert_int_equal(tctx
, d1
->icmintent
, d2
->icmintent
, "icmintent mismatch");
2111 torture_assert_int_equal(tctx
, d1
->mediatype
, d2
->mediatype
, "mediatype mismatch");
2112 torture_assert_int_equal(tctx
, d1
->dithertype
, d2
->dithertype
, "dithertype mismatch");
2113 torture_assert_int_equal(tctx
, d1
->reserved1
, d2
->reserved1
, "reserved1 mismatch");
2114 torture_assert_int_equal(tctx
, d1
->reserved2
, d2
->reserved2
, "reserved2 mismatch");
2115 torture_assert_int_equal(tctx
, d1
->panningwidth
, d2
->panningwidth
, "panningwidth mismatch");
2116 torture_assert_int_equal(tctx
, d1
->panningheight
, d2
->panningheight
, "panningheight mismatch");
2117 torture_assert_data_blob_equal(tctx
, d1
->driverextra_data
, d2
->driverextra_data
, "driverextra_data mismatch");
2122 static bool test_devicemode_full(struct torture_context
*tctx
,
2123 struct dcerpc_binding_handle
*b
,
2124 struct policy_handle
*handle
)
2126 struct spoolss_SetPrinter s
;
2127 struct spoolss_GetPrinter q
;
2128 struct spoolss_GetPrinter q0
;
2129 struct spoolss_SetPrinterInfoCtr info_ctr
;
2130 struct spoolss_SetPrinterInfo8 info8
;
2131 union spoolss_PrinterInfo info
;
2132 struct spoolss_DevmodeContainer devmode_ctr
;
2133 struct sec_desc_buf secdesc_ctr
;
2138 #define TEST_DEVMODE_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
2139 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
2140 q.in.level = lvl1; \
2141 TESTGETCALL(GetPrinter, q) \
2142 info_ctr.level = lvl1; \
2144 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)(void *)&q.out.info->info ## lvl1; \
2145 } else if (lvl1 == 8) {\
2146 info_ctr.info.info ## lvl1 = &info8; \
2148 devmode_ctr.devmode = q.out.info->info ## lvl1.devmode; \
2149 devmode_ctr.devmode->field1 = value; \
2150 TESTSETCALL(SetPrinter, s) \
2151 TESTGETCALL(GetPrinter, q) \
2152 INT_EQUAL(q.out.info->info ## lvl1.devmode->field1, exp_value, field1); \
2153 q.in.level = lvl2; \
2154 TESTGETCALL(GetPrinter, q) \
2155 INT_EQUAL(q.out.info->info ## lvl2.devmode->field2, exp_value, field1); \
2158 #define TEST_DEVMODE_INT(lvl1, field1, lvl2, field2, value) do { \
2159 TEST_DEVMODE_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
2162 ZERO_STRUCT(devmode_ctr
);
2163 ZERO_STRUCT(secdesc_ctr
);
2166 s
.in
.handle
= handle
;
2168 s
.in
.info_ctr
= &info_ctr
;
2169 s
.in
.devmode_ctr
= &devmode_ctr
;
2170 s
.in
.secdesc_ctr
= &secdesc_ctr
;
2172 q
.in
.handle
= handle
;
2177 const char *devicename
;/* [charset(UTF16)] */
2178 enum spoolss_DeviceModeSpecVersion specversion
;
2179 uint16_t driverversion
;
2181 uint16_t __driverextra_length
;/* [value(r->driverextra_data.length)] */
2185 TEST_DEVMODE_INT(8, orientation
, 8, orientation
, __LINE__
);
2186 TEST_DEVMODE_INT(8, papersize
, 8, papersize
, __LINE__
);
2187 TEST_DEVMODE_INT(8, paperlength
, 8, paperlength
, __LINE__
);
2188 TEST_DEVMODE_INT(8, paperwidth
, 8, paperwidth
, __LINE__
);
2189 TEST_DEVMODE_INT(8, scale
, 8, scale
, __LINE__
);
2190 TEST_DEVMODE_INT(8, copies
, 8, copies
, __LINE__
);
2191 TEST_DEVMODE_INT(8, defaultsource
, 8, defaultsource
, __LINE__
);
2192 TEST_DEVMODE_INT(8, printquality
, 8, printquality
, __LINE__
);
2193 TEST_DEVMODE_INT(8, color
, 8, color
, __LINE__
);
2194 TEST_DEVMODE_INT(8, duplex
, 8, duplex
, __LINE__
);
2195 TEST_DEVMODE_INT(8, yresolution
, 8, yresolution
, __LINE__
);
2196 TEST_DEVMODE_INT(8, ttoption
, 8, ttoption
, __LINE__
);
2197 TEST_DEVMODE_INT(8, collate
, 8, collate
, __LINE__
);
2199 const char *formname
;/* [charset(UTF16)] */
2201 TEST_DEVMODE_INT(8, logpixels
, 8, logpixels
, __LINE__
);
2202 TEST_DEVMODE_INT(8, bitsperpel
, 8, bitsperpel
, __LINE__
);
2203 TEST_DEVMODE_INT(8, pelswidth
, 8, pelswidth
, __LINE__
);
2204 TEST_DEVMODE_INT(8, pelsheight
, 8, pelsheight
, __LINE__
);
2205 TEST_DEVMODE_INT(8, displayflags
, 8, displayflags
, __LINE__
);
2206 TEST_DEVMODE_INT(8, displayfrequency
, 8, displayfrequency
, __LINE__
);
2207 TEST_DEVMODE_INT(8, icmmethod
, 8, icmmethod
, __LINE__
);
2208 TEST_DEVMODE_INT(8, icmintent
, 8, icmintent
, __LINE__
);
2209 TEST_DEVMODE_INT(8, mediatype
, 8, mediatype
, __LINE__
);
2210 TEST_DEVMODE_INT(8, dithertype
, 8, dithertype
, __LINE__
);
2211 TEST_DEVMODE_INT(8, reserved1
, 8, reserved1
, __LINE__
);
2212 TEST_DEVMODE_INT(8, reserved2
, 8, reserved2
, __LINE__
);
2213 TEST_DEVMODE_INT(8, panningwidth
, 8, panningwidth
, __LINE__
);
2214 TEST_DEVMODE_INT(8, panningheight
, 8, panningheight
, __LINE__
);
2219 static bool call_OpenPrinterEx(struct torture_context
*tctx
,
2220 struct dcerpc_pipe
*p
,
2222 struct spoolss_DeviceMode
*devmode
,
2223 struct policy_handle
*handle
);
2225 static bool test_PrinterInfo_DevModes(struct torture_context
*tctx
,
2226 struct dcerpc_pipe
*p
,
2227 struct policy_handle
*handle
,
2230 union spoolss_PrinterInfo info
;
2231 struct spoolss_DeviceMode
*devmode
;
2232 struct spoolss_DeviceMode
*devmode2
;
2233 struct policy_handle handle_devmode
;
2234 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2236 /* simply compare level8 and level2 devmode */
2238 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 8, &info
), "");
2240 devmode
= info
.info8
.devmode
;
2242 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
2244 devmode2
= info
.info2
.devmode
;
2246 torture_assert(tctx
, test_devicemode_equal(tctx
, devmode
, devmode2
),
2247 "DM level 8 != DM level 2");
2250 /* set devicemode level 8 and see if it persists */
2252 devmode
->copies
= 93;
2253 devmode
->formname
= talloc_strdup(tctx
, "Legal");
2255 torture_assert(tctx
, test_devmode_set_level(tctx
, b
, handle
, 8, devmode
), "");
2257 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 8, &info
), "");
2259 devmode2
= info
.info8
.devmode
;
2261 torture_assert(tctx
, test_devicemode_equal(tctx
, devmode
, devmode2
),
2262 "modified DM level 8 != DM level 8 after DM has been set via level 8");
2264 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
2266 devmode2
= info
.info2
.devmode
;
2268 torture_assert(tctx
, test_devicemode_equal(tctx
, devmode
, devmode2
),
2269 "modified DM level 8 != DM level 2");
2272 /* set devicemode level 2 and see if it persists */
2274 devmode
->copies
= 39;
2275 devmode
->formname
= talloc_strdup(tctx
, "Executive");
2277 torture_assert(tctx
, test_devmode_set_level(tctx
, b
, handle
, 2, devmode
), "");
2279 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 8, &info
), "");
2281 devmode2
= info
.info8
.devmode
;
2283 torture_assert(tctx
, test_devicemode_equal(tctx
, devmode
, devmode2
),
2284 "modified DM level 8 != DM level 8 after DM has been set via level 2");
2286 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
), "");
2288 devmode2
= info
.info2
.devmode
;
2290 torture_assert(tctx
, test_devicemode_equal(tctx
, devmode
, devmode2
),
2291 "modified DM level 8 != DM level 2");
2294 /* check every single bit in public part of devicemode */
2296 torture_assert(tctx
, test_devicemode_full(tctx
, b
, handle
),
2297 "failed to set every single devicemode component");
2300 /* change formname upon open and see if it persists in getprinter calls */
2302 devmode
->formname
= talloc_strdup(tctx
, "A4");
2303 devmode
->copies
= 42;
2305 torture_assert(tctx
, call_OpenPrinterEx(tctx
, p
, name
, devmode
, &handle_devmode
),
2306 "failed to open printer handle");
2308 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, &handle_devmode
, 8, &info
), "");
2310 devmode2
= info
.info8
.devmode
;
2312 if (strequal(devmode
->devicename
, devmode2
->devicename
)) {
2313 torture_warning(tctx
, "devicenames are the same\n");
2315 torture_comment(tctx
, "devicename passed in for open: %s\n", devmode
->devicename
);
2316 torture_comment(tctx
, "devicename after level 8 get: %s\n", devmode2
->devicename
);
2319 if (strequal(devmode
->formname
, devmode2
->formname
)) {
2320 torture_warning(tctx
, "formname are the same\n");
2322 torture_comment(tctx
, "formname passed in for open: %s\n", devmode
->formname
);
2323 torture_comment(tctx
, "formname after level 8 get: %s\n", devmode2
->formname
);
2326 if (devmode
->copies
== devmode2
->copies
) {
2327 torture_warning(tctx
, "copies are the same\n");
2329 torture_comment(tctx
, "copies passed in for open: %d\n", devmode
->copies
);
2330 torture_comment(tctx
, "copies after level 8 get: %d\n", devmode2
->copies
);
2333 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, &handle_devmode
, 2, &info
), "");
2335 devmode2
= info
.info2
.devmode
;
2337 if (strequal(devmode
->devicename
, devmode2
->devicename
)) {
2338 torture_warning(tctx
, "devicenames are the same\n");
2340 torture_comment(tctx
, "devicename passed in for open: %s\n", devmode
->devicename
);
2341 torture_comment(tctx
, "devicename after level 2 get: %s\n", devmode2
->devicename
);
2344 if (strequal(devmode
->formname
, devmode2
->formname
)) {
2345 torture_warning(tctx
, "formname is the same\n");
2347 torture_comment(tctx
, "formname passed in for open: %s\n", devmode
->formname
);
2348 torture_comment(tctx
, "formname after level 2 get: %s\n", devmode2
->formname
);
2351 if (devmode
->copies
== devmode2
->copies
) {
2352 torture_warning(tctx
, "copies are the same\n");
2354 torture_comment(tctx
, "copies passed in for open: %d\n", devmode
->copies
);
2355 torture_comment(tctx
, "copies after level 2 get: %d\n", devmode2
->copies
);
2358 test_ClosePrinter(tctx
, b
, &handle_devmode
);
2364 * wrapper call that saves original devmode, runs tests, and restores devmode
2367 static bool test_PrinterInfo_DevMode(struct torture_context
*tctx
,
2368 struct dcerpc_pipe
*p
,
2369 struct policy_handle
*handle
,
2371 struct spoolss_DeviceMode
*addprinter_devmode
)
2373 union spoolss_PrinterInfo info
;
2374 struct spoolss_DeviceMode
*devmode
;
2376 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2378 torture_comment(tctx
, "Testing Printer Devicemodes\n");
2380 /* save original devmode */
2382 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 8, &info
),
2383 "failed to get initial global devicemode");
2385 devmode
= info
.info8
.devmode
;
2387 if (addprinter_devmode
) {
2388 if (!test_devicemode_equal(tctx
, devmode
, addprinter_devmode
)) {
2389 torture_warning(tctx
, "current global DM is != DM provided in addprinter");
2395 ret
= test_PrinterInfo_DevModes(tctx
, p
, handle
, name
);
2397 /* restore original devmode */
2399 torture_assert(tctx
, test_devmode_set_level(tctx
, b
, handle
, 8, devmode
),
2400 "failed to restore initial global device mode");
2402 torture_comment(tctx
, "Printer Devicemodes test %s\n\n",
2403 ret
? "succeeded" : "failed");
2409 bool test_ClosePrinter(struct torture_context
*tctx
,
2410 struct dcerpc_binding_handle
*b
,
2411 struct policy_handle
*handle
)
2414 struct spoolss_ClosePrinter r
;
2416 r
.in
.handle
= handle
;
2417 r
.out
.handle
= handle
;
2419 torture_comment(tctx
, "Testing ClosePrinter\n");
2421 status
= dcerpc_spoolss_ClosePrinter_r(b
, tctx
, &r
);
2422 torture_assert_ntstatus_ok(tctx
, status
, "ClosePrinter failed");
2423 torture_assert_werr_ok(tctx
, r
.out
.result
, "ClosePrinter failed");
2428 static bool test_GetForm_args(struct torture_context
*tctx
,
2429 struct dcerpc_binding_handle
*b
,
2430 struct policy_handle
*handle
,
2431 const char *form_name
,
2433 union spoolss_FormInfo
*info_p
)
2436 struct spoolss_GetForm r
;
2439 r
.in
.handle
= handle
;
2440 r
.in
.form_name
= form_name
;
2444 r
.out
.needed
= &needed
;
2446 torture_comment(tctx
, "Testing GetForm(%s) level %d\n", form_name
, r
.in
.level
);
2448 status
= dcerpc_spoolss_GetForm_r(b
, tctx
, &r
);
2449 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
2451 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2452 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
2453 r
.in
.buffer
= &blob
;
2454 r
.in
.offered
= needed
;
2455 status
= dcerpc_spoolss_GetForm_r(b
, tctx
, &r
);
2456 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
2458 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
2460 torture_assert(tctx
, r
.out
.info
, "No form info returned");
2463 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
2465 CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo
, r
.out
.info
, r
.in
.level
, needed
, 4);
2468 *info_p
= *r
.out
.info
;
2474 static bool test_GetForm(struct torture_context
*tctx
,
2475 struct dcerpc_binding_handle
*b
,
2476 struct policy_handle
*handle
,
2477 const char *form_name
,
2480 return test_GetForm_args(tctx
, b
, handle
, form_name
, level
, NULL
);
2483 static bool test_EnumForms(struct torture_context
*tctx
,
2484 struct dcerpc_binding_handle
*b
,
2485 struct policy_handle
*handle
,
2489 union spoolss_FormInfo
**info_p
)
2491 struct spoolss_EnumForms r
;
2494 union spoolss_FormInfo
*info
;
2496 r
.in
.handle
= handle
;
2500 r
.out
.needed
= &needed
;
2501 r
.out
.count
= &count
;
2504 torture_comment(tctx
, "Testing EnumForms level %d\n", r
.in
.level
);
2506 torture_assert_ntstatus_ok(tctx
,
2507 dcerpc_spoolss_EnumForms_r(b
, tctx
, &r
),
2508 "EnumForms failed");
2510 if ((r
.in
.level
== 2) && (W_ERROR_EQUAL(r
.out
.result
, WERR_UNKNOWN_LEVEL
))) {
2511 torture_skip(tctx
, "EnumForms level 2 not supported");
2514 if (print_server
&& W_ERROR_EQUAL(r
.out
.result
, WERR_BADFID
)) {
2515 torture_fail(tctx
, "EnumForms on the PrintServer isn't supported by test server (NT4)");
2518 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2519 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
2520 r
.in
.buffer
= &blob
;
2521 r
.in
.offered
= needed
;
2523 torture_assert_ntstatus_ok(tctx
,
2524 dcerpc_spoolss_EnumForms_r(b
, tctx
, &r
),
2525 "EnumForms failed");
2527 torture_assert(tctx
, info
, "No forms returned");
2530 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumForms failed");
2532 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms
, info
, r
.in
.level
, count
, needed
, 4);
2544 static bool test_EnumForms_all(struct torture_context
*tctx
,
2545 struct dcerpc_binding_handle
*b
,
2546 struct policy_handle
*handle
,
2549 uint32_t levels
[] = { 1, 2 };
2552 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2555 union spoolss_FormInfo
*info
= NULL
;
2557 torture_assert(tctx
,
2558 test_EnumForms(tctx
, b
, handle
, print_server
, levels
[i
], &count
, &info
),
2559 "failed to enum forms");
2561 for (j
= 0; j
< count
; j
++) {
2562 if (!print_server
) {
2563 torture_assert(tctx
,
2564 test_GetForm(tctx
, b
, handle
, info
[j
].info1
.form_name
, levels
[i
]),
2565 "failed to get form");
2573 static bool test_EnumForms_find_one(struct torture_context
*tctx
,
2574 struct dcerpc_binding_handle
*b
,
2575 struct policy_handle
*handle
,
2577 const char *form_name
)
2579 union spoolss_FormInfo
*info
;
2584 torture_assert(tctx
,
2585 test_EnumForms(tctx
, b
, handle
, print_server
, 1, &count
, &info
),
2586 "failed to enumerate forms");
2588 for (i
=0; i
<count
; i
++) {
2589 if (strequal(form_name
, info
[i
].info1
.form_name
)) {
2598 static bool test_DeleteForm(struct torture_context
*tctx
,
2599 struct dcerpc_binding_handle
*b
,
2600 struct policy_handle
*handle
,
2601 const char *form_name
,
2602 WERROR expected_result
)
2604 struct spoolss_DeleteForm r
;
2606 r
.in
.handle
= handle
;
2607 r
.in
.form_name
= form_name
;
2609 torture_comment(tctx
, "Testing DeleteForm(%s)\n", form_name
);
2611 torture_assert_ntstatus_ok(tctx
,
2612 dcerpc_spoolss_DeleteForm_r(b
, tctx
, &r
),
2613 "DeleteForm failed");
2614 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
2615 "DeleteForm gave unexpected result");
2616 if (W_ERROR_IS_OK(r
.out
.result
)) {
2617 torture_assert_ntstatus_ok(tctx
,
2618 dcerpc_spoolss_DeleteForm_r(b
, tctx
, &r
),
2619 "2nd DeleteForm failed");
2620 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_FORM_NAME
,
2621 "2nd DeleteForm failed");
2627 static bool test_AddForm(struct torture_context
*tctx
,
2628 struct dcerpc_binding_handle
*b
,
2629 struct policy_handle
*handle
,
2631 union spoolss_AddFormInfo
*info
,
2632 WERROR expected_result
)
2634 struct spoolss_AddForm r
;
2637 torture_skip(tctx
, "only level 1 supported");
2640 r
.in
.handle
= handle
;
2644 torture_comment(tctx
, "Testing AddForm(%s) level %d, type %d\n",
2645 r
.in
.info
.info1
->form_name
, r
.in
.level
,
2646 r
.in
.info
.info1
->flags
);
2648 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_AddForm_r(b
, tctx
, &r
),
2650 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
2651 "AddForm gave unexpected result");
2653 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_AddForm_r(b
, tctx
, &r
),
2654 "2nd AddForm failed");
2655 if (W_ERROR_EQUAL(expected_result
, WERR_INVALID_PARAM
)) {
2656 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
2657 "2nd AddForm gave unexpected result");
2659 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_FILE_EXISTS
,
2660 "2nd AddForm gave unexpected result");
2666 static bool test_SetForm(struct torture_context
*tctx
,
2667 struct dcerpc_binding_handle
*b
,
2668 struct policy_handle
*handle
,
2669 const char *form_name
,
2671 union spoolss_AddFormInfo
*info
)
2673 struct spoolss_SetForm r
;
2675 r
.in
.handle
= handle
;
2676 r
.in
.form_name
= form_name
;
2680 torture_comment(tctx
, "Testing SetForm(%s) level %d\n",
2681 form_name
, r
.in
.level
);
2683 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetForm_r(b
, tctx
, &r
),
2686 torture_assert_werr_ok(tctx
, r
.out
.result
,
2692 static bool test_GetForm_winreg(struct torture_context
*tctx
,
2693 struct dcerpc_binding_handle
*b
,
2694 struct policy_handle
*handle
,
2695 const char *key_name
,
2696 const char *form_name
,
2697 enum winreg_Type
*w_type
,
2702 static bool test_Forms_args(struct torture_context
*tctx
,
2703 struct dcerpc_binding_handle
*b
,
2704 struct policy_handle
*handle
,
2706 const char *printer_name
,
2707 struct dcerpc_binding_handle
*winreg_handle
,
2708 struct policy_handle
*hive_handle
,
2709 const char *form_name
,
2710 struct spoolss_AddFormInfo1
*info1
,
2711 WERROR expected_add_result
,
2712 WERROR expected_delete_result
)
2714 union spoolss_FormInfo info
;
2715 union spoolss_AddFormInfo add_info
;
2717 enum winreg_Type w_type
;
2722 add_info
.info1
= info1
;
2724 torture_assert(tctx
,
2725 test_AddForm(tctx
, b
, handle
, 1, &add_info
, expected_add_result
),
2726 "failed to add form");
2728 if (winreg_handle
&& hive_handle
&& W_ERROR_IS_OK(expected_add_result
)) {
2730 struct spoolss_FormInfo1 i1
;
2732 torture_assert(tctx
,
2733 test_GetForm_winreg(tctx
, winreg_handle
, hive_handle
, TOP_LEVEL_CONTROL_FORMS_KEY
, form_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2734 "failed to get form via winreg");
2736 i1
.size
.width
= IVAL(w_data
, 0);
2737 i1
.size
.height
= IVAL(w_data
, 4);
2738 i1
.area
.left
= IVAL(w_data
, 8);
2739 i1
.area
.top
= IVAL(w_data
, 12);
2740 i1
.area
.right
= IVAL(w_data
, 16);
2741 i1
.area
.bottom
= IVAL(w_data
, 20);
2742 /* skip index here */
2743 i1
.flags
= IVAL(w_data
, 28);
2745 torture_assert_int_equal(tctx
, w_type
, REG_BINARY
, "unexpected type");
2746 torture_assert_int_equal(tctx
, w_size
, 0x20, "unexpected size");
2747 torture_assert_int_equal(tctx
, w_length
, 0x20, "unexpected length");
2748 torture_assert_int_equal(tctx
, i1
.size
.width
, add_info
.info1
->size
.width
, "width mismatch");
2749 torture_assert_int_equal(tctx
, i1
.size
.height
, add_info
.info1
->size
.height
, "height mismatch");
2750 torture_assert_int_equal(tctx
, i1
.area
.left
, add_info
.info1
->area
.left
, "left mismatch");
2751 torture_assert_int_equal(tctx
, i1
.area
.top
, add_info
.info1
->area
.top
, "top mismatch");
2752 torture_assert_int_equal(tctx
, i1
.area
.right
, add_info
.info1
->area
.right
, "right mismatch");
2753 torture_assert_int_equal(tctx
, i1
.area
.bottom
, add_info
.info1
->area
.bottom
, "bottom mismatch");
2754 torture_assert_int_equal(tctx
, i1
.flags
, add_info
.info1
->flags
, "flags mismatch");
2757 if (!print_server
&& W_ERROR_IS_OK(expected_add_result
)) {
2758 torture_assert(tctx
,
2759 test_GetForm_args(tctx
, b
, handle
, form_name
, 1, &info
),
2760 "failed to get added form");
2762 torture_assert_int_equal(tctx
, info
.info1
.size
.width
, add_info
.info1
->size
.width
, "width mismatch");
2763 torture_assert_int_equal(tctx
, info
.info1
.size
.height
, add_info
.info1
->size
.height
, "height mismatch");
2764 torture_assert_int_equal(tctx
, info
.info1
.area
.left
, add_info
.info1
->area
.left
, "left mismatch");
2765 torture_assert_int_equal(tctx
, info
.info1
.area
.top
, add_info
.info1
->area
.top
, "top mismatch");
2766 torture_assert_int_equal(tctx
, info
.info1
.area
.right
, add_info
.info1
->area
.right
, "right mismatch");
2767 torture_assert_int_equal(tctx
, info
.info1
.area
.bottom
, add_info
.info1
->area
.bottom
, "bottom mismatch");
2768 torture_assert_int_equal(tctx
, info
.info1
.flags
, add_info
.info1
->flags
, "flags mismatch");
2770 if (winreg_handle
&& hive_handle
) {
2772 struct spoolss_FormInfo1 i1
;
2774 i1
.size
.width
= IVAL(w_data
, 0);
2775 i1
.size
.height
= IVAL(w_data
, 4);
2776 i1
.area
.left
= IVAL(w_data
, 8);
2777 i1
.area
.top
= IVAL(w_data
, 12);
2778 i1
.area
.right
= IVAL(w_data
, 16);
2779 i1
.area
.bottom
= IVAL(w_data
, 20);
2780 /* skip index here */
2781 i1
.flags
= IVAL(w_data
, 28);
2783 torture_assert_int_equal(tctx
, i1
.size
.width
, info
.info1
.size
.width
, "width mismatch");
2784 torture_assert_int_equal(tctx
, i1
.size
.height
, info
.info1
.size
.height
, "height mismatch");
2785 torture_assert_int_equal(tctx
, i1
.area
.left
, info
.info1
.area
.left
, "left mismatch");
2786 torture_assert_int_equal(tctx
, i1
.area
.top
, info
.info1
.area
.top
, "top mismatch");
2787 torture_assert_int_equal(tctx
, i1
.area
.right
, info
.info1
.area
.right
, "right mismatch");
2788 torture_assert_int_equal(tctx
, i1
.area
.bottom
, info
.info1
.area
.bottom
, "bottom mismatch");
2789 torture_assert_int_equal(tctx
, i1
.flags
, info
.info1
.flags
, "flags mismatch");
2792 add_info
.info1
->size
.width
= 1234;
2794 torture_assert(tctx
,
2795 test_SetForm(tctx
, b
, handle
, form_name
, 1, &add_info
),
2796 "failed to set form");
2797 torture_assert(tctx
,
2798 test_GetForm_args(tctx
, b
, handle
, form_name
, 1, &info
),
2799 "failed to get setted form");
2801 torture_assert_int_equal(tctx
, info
.info1
.size
.width
, add_info
.info1
->size
.width
, "width mismatch");
2804 if (!W_ERROR_EQUAL(expected_add_result
, WERR_INVALID_PARAM
)) {
2805 torture_assert(tctx
,
2806 test_EnumForms_find_one(tctx
, b
, handle
, print_server
, form_name
),
2807 "Newly added form not found in enum call");
2810 torture_assert(tctx
,
2811 test_DeleteForm(tctx
, b
, handle
, form_name
, expected_delete_result
),
2812 "failed to delete form");
2817 static bool test_Forms(struct torture_context
*tctx
,
2818 struct dcerpc_binding_handle
*b
,
2819 struct policy_handle
*handle
,
2821 const char *printer_name
,
2822 struct dcerpc_binding_handle
*winreg_handle
,
2823 struct policy_handle
*hive_handle
)
2825 const struct spoolss_FormSize size
= {
2829 const struct spoolss_FormArea area
= {
2838 struct spoolss_AddFormInfo1 info1
;
2839 WERROR expected_add_result
;
2840 WERROR expected_delete_result
;
2844 .flags
= SPOOLSS_FORM_USER
,
2845 .form_name
= "testform_user",
2849 .expected_add_result
= WERR_OK
,
2850 .expected_delete_result
= WERR_OK
2853 weird, we can add a builtin form but we can never remove it
2858 .flags = SPOOLSS_FORM_BUILTIN,
2859 .form_name = "testform_builtin",
2863 .expected_add_result = WERR_OK,
2864 .expected_delete_result = WERR_INVALID_PARAM,
2869 .flags
= SPOOLSS_FORM_PRINTER
,
2870 .form_name
= "testform_printer",
2874 .expected_add_result
= WERR_OK
,
2875 .expected_delete_result
= WERR_OK
2879 .flags
= SPOOLSS_FORM_USER
,
2880 .form_name
= "Letter",
2884 .expected_add_result
= WERR_FILE_EXISTS
,
2885 .expected_delete_result
= WERR_INVALID_PARAM
2889 .flags
= SPOOLSS_FORM_BUILTIN
,
2890 .form_name
= "Letter",
2894 .expected_add_result
= WERR_FILE_EXISTS
,
2895 .expected_delete_result
= WERR_INVALID_PARAM
2899 .flags
= SPOOLSS_FORM_PRINTER
,
2900 .form_name
= "Letter",
2904 .expected_add_result
= WERR_FILE_EXISTS
,
2905 .expected_delete_result
= WERR_INVALID_PARAM
2910 .form_name
= "invalid_flags",
2914 .expected_add_result
= WERR_INVALID_PARAM
,
2915 .expected_delete_result
= WERR_INVALID_FORM_NAME
2920 for (i
=0; i
< ARRAY_SIZE(forms
); i
++) {
2921 torture_assert(tctx
,
2922 test_Forms_args(tctx
, b
, handle
, print_server
, printer_name
,
2923 winreg_handle
, hive_handle
,
2924 forms
[i
].info1
.form_name
,
2926 forms
[i
].expected_add_result
,
2927 forms
[i
].expected_delete_result
),
2928 talloc_asprintf(tctx
, "failed to test form '%s'", forms
[i
].info1
.form_name
));
2934 static bool test_EnumPorts_old(struct torture_context
*tctx
,
2937 struct test_spoolss_context
*ctx
=
2938 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
2941 struct spoolss_EnumPorts r
;
2944 union spoolss_PortInfo
*info
;
2945 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
2946 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2948 r
.in
.servername
= talloc_asprintf(tctx
, "\\\\%s",
2949 dcerpc_server_name(p
));
2953 r
.out
.needed
= &needed
;
2954 r
.out
.count
= &count
;
2957 torture_comment(tctx
, "Testing EnumPorts\n");
2959 status
= dcerpc_spoolss_EnumPorts_r(b
, tctx
, &r
);
2961 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
2963 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2964 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
2965 r
.in
.buffer
= &blob
;
2966 r
.in
.offered
= needed
;
2968 status
= dcerpc_spoolss_EnumPorts_r(b
, tctx
, &r
);
2969 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
2970 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPorts failed");
2972 torture_assert(tctx
, info
, "No ports returned");
2975 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPorts failed");
2977 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts
, info
, 2, count
, needed
, 4);
2982 static bool test_AddPort(struct torture_context
*tctx
,
2985 struct test_spoolss_context
*ctx
=
2986 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
2989 struct spoolss_AddPort r
;
2990 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
2991 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2993 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
2994 dcerpc_server_name(p
));
2996 r
.in
.monitor_name
= "foo";
2998 torture_comment(tctx
, "Testing AddPort\n");
3000 status
= dcerpc_spoolss_AddPort_r(b
, tctx
, &r
);
3002 torture_assert_ntstatus_ok(tctx
, status
, "AddPort failed");
3004 /* win2k3 returns WERR_NOT_SUPPORTED */
3008 if (!W_ERROR_IS_OK(r
.out
.result
)) {
3009 printf("AddPort failed - %s\n", win_errstr(r
.out
.result
));
3018 static bool test_GetJob_args(struct torture_context
*tctx
,
3019 struct dcerpc_binding_handle
*b
,
3020 struct policy_handle
*handle
,
3023 union spoolss_JobInfo
*info_p
)
3026 struct spoolss_GetJob r
;
3027 union spoolss_JobInfo info
;
3030 r
.in
.handle
= handle
;
3031 r
.in
.job_id
= job_id
;
3035 r
.out
.needed
= &needed
;
3038 torture_comment(tctx
, "Testing GetJob(%d), level %d\n", job_id
, r
.in
.level
);
3040 status
= dcerpc_spoolss_GetJob_r(b
, tctx
, &r
);
3041 torture_assert_ntstatus_ok(tctx
, status
, "GetJob failed");
3043 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
, "Unexpected return code");
3046 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
3047 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
3048 r
.in
.buffer
= &blob
;
3049 r
.in
.offered
= needed
;
3051 status
= dcerpc_spoolss_GetJob_r(b
, tctx
, &r
);
3052 torture_assert_ntstatus_ok(tctx
, status
, "GetJob failed");
3055 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetJob failed");
3056 torture_assert(tctx
, r
.out
.info
, "No job info returned");
3058 CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo
, r
.out
.info
, r
.in
.level
, needed
, 4);
3061 *info_p
= *r
.out
.info
;
3067 static bool test_GetJob(struct torture_context
*tctx
,
3068 struct dcerpc_binding_handle
*b
,
3069 struct policy_handle
*handle
,
3072 uint32_t levels
[] = {0, 1, 2 /* 3, 4 */};
3075 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
3076 torture_assert(tctx
,
3077 test_GetJob_args(tctx
, b
, handle
, job_id
, levels
[i
], NULL
),
3084 static bool test_SetJob(struct torture_context
*tctx
,
3085 struct dcerpc_binding_handle
*b
,
3086 struct policy_handle
*handle
,
3088 struct spoolss_JobInfoContainer
*ctr
,
3089 enum spoolss_JobControl command
)
3092 struct spoolss_SetJob r
;
3094 r
.in
.handle
= handle
;
3095 r
.in
.job_id
= job_id
;
3097 r
.in
.command
= command
;
3100 case SPOOLSS_JOB_CONTROL_PAUSE
:
3101 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_PAUSE\n", job_id
);
3103 case SPOOLSS_JOB_CONTROL_RESUME
:
3104 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESUME\n", job_id
);
3106 case SPOOLSS_JOB_CONTROL_CANCEL
:
3107 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_CANCEL\n", job_id
);
3109 case SPOOLSS_JOB_CONTROL_RESTART
:
3110 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESTART\n", job_id
);
3112 case SPOOLSS_JOB_CONTROL_DELETE
:
3113 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_DELETE\n", job_id
);
3115 case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
:
3116 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n", job_id
);
3118 case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
:
3119 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n", job_id
);
3121 case SPOOLSS_JOB_CONTROL_RETAIN
:
3122 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RETAIN\n", job_id
);
3124 case SPOOLSS_JOB_CONTROL_RELEASE
:
3125 torture_comment(tctx
, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RELEASE\n", job_id
);
3128 torture_comment(tctx
, "Testing SetJob(%d)\n", job_id
);
3132 status
= dcerpc_spoolss_SetJob_r(b
, tctx
, &r
);
3133 torture_assert_ntstatus_ok(tctx
, status
, "SetJob failed");
3134 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetJob failed");
3139 static bool test_AddJob(struct torture_context
*tctx
,
3140 struct dcerpc_binding_handle
*b
,
3141 struct policy_handle
*handle
)
3144 struct spoolss_AddJob r
;
3148 r
.in
.handle
= handle
;
3150 r
.out
.needed
= &needed
;
3151 r
.in
.buffer
= r
.out
.buffer
= NULL
;
3153 torture_comment(tctx
, "Testing AddJob\n");
3155 status
= dcerpc_spoolss_AddJob_r(b
, tctx
, &r
);
3156 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
, "AddJob failed");
3160 status
= dcerpc_spoolss_AddJob_r(b
, tctx
, &r
);
3161 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
, "AddJob failed");
3167 static bool test_EnumJobs_args(struct torture_context
*tctx
,
3168 struct dcerpc_binding_handle
*b
,
3169 struct policy_handle
*handle
,
3172 union spoolss_JobInfo
**info_p
)
3175 struct spoolss_EnumJobs r
;
3178 union spoolss_JobInfo
*info
;
3180 r
.in
.handle
= handle
;
3182 r
.in
.numjobs
= 0xffffffff;
3186 r
.out
.needed
= &needed
;
3187 r
.out
.count
= &count
;
3190 torture_comment(tctx
, "Testing EnumJobs level %d\n", level
);
3192 status
= dcerpc_spoolss_EnumJobs_r(b
, tctx
, &r
);
3194 torture_assert_ntstatus_ok(tctx
, status
, "EnumJobs failed");
3196 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
3197 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
3198 r
.in
.buffer
= &blob
;
3199 r
.in
.offered
= needed
;
3201 status
= dcerpc_spoolss_EnumJobs_r(b
, tctx
, &r
);
3203 torture_assert_ntstatus_ok(tctx
, status
, "EnumJobs failed");
3204 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumJobs failed");
3205 torture_assert(tctx
, info
, "No jobs returned");
3207 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs
, *r
.out
.info
, r
.in
.level
, count
, needed
, 4);
3210 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumJobs failed");
3223 static bool test_DoPrintTest_add_one_job(struct torture_context
*tctx
,
3224 struct dcerpc_binding_handle
*b
,
3225 struct policy_handle
*handle
,
3229 struct spoolss_StartDocPrinter s
;
3230 struct spoolss_DocumentInfo1 info1
;
3231 struct spoolss_StartPagePrinter sp
;
3232 struct spoolss_WritePrinter w
;
3233 struct spoolss_EndPagePrinter ep
;
3234 struct spoolss_EndDocPrinter e
;
3236 uint32_t num_written
;
3238 torture_comment(tctx
, "Testing StartDocPrinter\n");
3240 s
.in
.handle
= handle
;
3242 s
.in
.info
.info1
= &info1
;
3243 s
.out
.job_id
= job_id
;
3244 info1
.document_name
= "TorturePrintJob";
3245 info1
.output_file
= NULL
;
3246 info1
.datatype
= "RAW";
3248 status
= dcerpc_spoolss_StartDocPrinter_r(b
, tctx
, &s
);
3249 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_StartDocPrinter failed");
3250 torture_assert_werr_ok(tctx
, s
.out
.result
, "StartDocPrinter failed");
3252 for (i
=1; i
< 4; i
++) {
3253 torture_comment(tctx
, "Testing StartPagePrinter: Page[%d], JobId[%d]\n", i
, *job_id
);
3255 sp
.in
.handle
= handle
;
3257 status
= dcerpc_spoolss_StartPagePrinter_r(b
, tctx
, &sp
);
3258 torture_assert_ntstatus_ok(tctx
, status
,
3259 "dcerpc_spoolss_StartPagePrinter failed");
3260 torture_assert_werr_ok(tctx
, sp
.out
.result
, "StartPagePrinter failed");
3262 torture_comment(tctx
, "Testing WritePrinter: Page[%d], JobId[%d]\n", i
, *job_id
);
3264 w
.in
.handle
= handle
;
3265 w
.in
.data
= data_blob_string_const(talloc_asprintf(tctx
,"TortureTestPage: %d\nData\n",i
));
3266 w
.out
.num_written
= &num_written
;
3268 status
= dcerpc_spoolss_WritePrinter_r(b
, tctx
, &w
);
3269 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_WritePrinter failed");
3270 torture_assert_werr_ok(tctx
, w
.out
.result
, "WritePrinter failed");
3272 torture_comment(tctx
, "Testing EndPagePrinter: Page[%d], JobId[%d]\n", i
, *job_id
);
3274 ep
.in
.handle
= handle
;
3276 status
= dcerpc_spoolss_EndPagePrinter_r(b
, tctx
, &ep
);
3277 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndPagePrinter failed");
3278 torture_assert_werr_ok(tctx
, ep
.out
.result
, "EndPagePrinter failed");
3281 torture_comment(tctx
, "Testing EndDocPrinter: JobId[%d]\n", *job_id
);
3283 e
.in
.handle
= handle
;
3285 status
= dcerpc_spoolss_EndDocPrinter_r(b
, tctx
, &e
);
3286 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndDocPrinter failed");
3287 torture_assert_werr_ok(tctx
, e
.out
.result
, "EndDocPrinter failed");
3292 static bool test_DoPrintTest_check_jobs(struct torture_context
*tctx
,
3293 struct dcerpc_binding_handle
*b
,
3294 struct policy_handle
*handle
,
3299 union spoolss_JobInfo
*info
= NULL
;
3302 torture_assert(tctx
,
3303 test_AddJob(tctx
, b
, handle
),
3306 torture_assert(tctx
,
3307 test_EnumJobs_args(tctx
, b
, handle
, 1, &count
, &info
),
3308 "EnumJobs level 1 failed");
3310 torture_assert_int_equal(tctx
, count
, num_jobs
, "unexpected number of jobs in queue");
3312 for (i
=0; i
< num_jobs
; i
++) {
3313 union spoolss_JobInfo ginfo
;
3314 const char *document_name
;
3315 const char *new_document_name
= "any_other_docname";
3316 struct spoolss_JobInfoContainer ctr
;
3317 struct spoolss_SetJobInfo1 info1
;
3319 torture_assert_int_equal(tctx
, info
[i
].info1
.job_id
, job_ids
[i
], "job id mismatch");
3321 torture_assert(tctx
,
3322 test_GetJob_args(tctx
, b
, handle
, info
[i
].info1
.job_id
, 1, &ginfo
),
3323 "failed to call test_GetJob");
3325 torture_assert_int_equal(tctx
, ginfo
.info1
.job_id
, info
[i
].info1
.job_id
, "job id mismatch");
3327 document_name
= ginfo
.info1
.document_name
;
3329 info1
.job_id
= ginfo
.info1
.job_id
;
3330 info1
.printer_name
= ginfo
.info1
.printer_name
;
3331 info1
.server_name
= ginfo
.info1
.server_name
;
3332 info1
.user_name
= ginfo
.info1
.user_name
;
3333 info1
.document_name
= new_document_name
;
3334 info1
.data_type
= ginfo
.info1
.data_type
;
3335 info1
.text_status
= ginfo
.info1
.text_status
;
3336 info1
.status
= ginfo
.info1
.status
;
3337 info1
.priority
= ginfo
.info1
.priority
;
3338 info1
.position
= ginfo
.info1
.position
;
3339 info1
.total_pages
= ginfo
.info1
.total_pages
;
3340 info1
.pages_printed
= ginfo
.info1
.pages_printed
;
3341 info1
.submitted
= ginfo
.info1
.submitted
;
3344 ctr
.info
.info1
= &info1
;
3346 torture_assert(tctx
,
3347 test_SetJob(tctx
, b
, handle
, info
[i
].info1
.job_id
, &ctr
, 0),
3348 "failed to call test_SetJob level 1");
3350 torture_assert(tctx
,
3351 test_GetJob_args(tctx
, b
, handle
, info
[i
].info1
.job_id
, 1, &ginfo
),
3352 "failed to call test_GetJob");
3354 if (strequal(ginfo
.info1
.document_name
, document_name
)) {
3355 torture_warning(tctx
,
3356 "document_name did *NOT* change from '%s' to '%s'\n",
3357 document_name
, new_document_name
);
3361 for (i
=0; i
< num_jobs
; i
++) {
3362 if (!test_SetJob(tctx
, b
, handle
, info
[i
].info1
.job_id
, NULL
, SPOOLSS_JOB_CONTROL_PAUSE
)) {
3363 torture_warning(tctx
, "failed to pause printjob\n");
3365 if (!test_SetJob(tctx
, b
, handle
, info
[i
].info1
.job_id
, NULL
, SPOOLSS_JOB_CONTROL_RESUME
)) {
3366 torture_warning(tctx
, "failed to resume printjob\n");
3373 static bool test_DoPrintTest(struct torture_context
*tctx
,
3374 struct dcerpc_binding_handle
*b
,
3375 struct policy_handle
*handle
)
3378 uint32_t num_jobs
= 8;
3382 torture_comment(tctx
, "Testing real print operations\n");
3384 job_ids
= talloc_zero_array(tctx
, uint32_t, num_jobs
);
3386 for (i
=0; i
< num_jobs
; i
++) {
3387 ret
&= test_DoPrintTest_add_one_job(tctx
, b
, handle
, &job_ids
[i
]);
3390 for (i
=0; i
< num_jobs
; i
++) {
3391 ret
&= test_SetJob(tctx
, b
, handle
, job_ids
[i
], NULL
, SPOOLSS_JOB_CONTROL_DELETE
);
3395 torture_comment(tctx
, "real print operations test succeeded\n\n");
3401 static bool test_DoPrintTest_extended(struct torture_context
*tctx
,
3402 struct dcerpc_binding_handle
*b
,
3403 struct policy_handle
*handle
)
3406 uint32_t num_jobs
= 8;
3409 torture_comment(tctx
, "Testing real print operations (extended)\n");
3411 job_ids
= talloc_zero_array(tctx
, uint32_t, num_jobs
);
3413 for (i
=0; i
< num_jobs
; i
++) {
3414 ret
&= test_DoPrintTest_add_one_job(tctx
, b
, handle
, &job_ids
[i
]);
3417 ret
&= test_DoPrintTest_check_jobs(tctx
, b
, handle
, num_jobs
, job_ids
);
3419 for (i
=0; i
< num_jobs
; i
++) {
3420 ret
&= test_SetJob(tctx
, b
, handle
, job_ids
[i
], NULL
, SPOOLSS_JOB_CONTROL_DELETE
);
3424 torture_comment(tctx
, "real print operations (extended) test succeeded\n\n");
3430 static bool test_PausePrinter(struct torture_context
*tctx
,
3431 struct dcerpc_binding_handle
*b
,
3432 struct policy_handle
*handle
)
3435 struct spoolss_SetPrinter r
;
3436 struct spoolss_SetPrinterInfoCtr info_ctr
;
3437 struct spoolss_DevmodeContainer devmode_ctr
;
3438 struct sec_desc_buf secdesc_ctr
;
3441 info_ctr
.info
.info0
= NULL
;
3443 ZERO_STRUCT(devmode_ctr
);
3444 ZERO_STRUCT(secdesc_ctr
);
3446 r
.in
.handle
= handle
;
3447 r
.in
.info_ctr
= &info_ctr
;
3448 r
.in
.devmode_ctr
= &devmode_ctr
;
3449 r
.in
.secdesc_ctr
= &secdesc_ctr
;
3450 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_PAUSE
;
3452 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
3454 status
= dcerpc_spoolss_SetPrinter_r(b
, tctx
, &r
);
3456 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
3458 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
3463 static bool test_ResumePrinter(struct torture_context
*tctx
,
3464 struct dcerpc_binding_handle
*b
,
3465 struct policy_handle
*handle
)
3468 struct spoolss_SetPrinter r
;
3469 struct spoolss_SetPrinterInfoCtr info_ctr
;
3470 struct spoolss_DevmodeContainer devmode_ctr
;
3471 struct sec_desc_buf secdesc_ctr
;
3474 info_ctr
.info
.info0
= NULL
;
3476 ZERO_STRUCT(devmode_ctr
);
3477 ZERO_STRUCT(secdesc_ctr
);
3479 r
.in
.handle
= handle
;
3480 r
.in
.info_ctr
= &info_ctr
;
3481 r
.in
.devmode_ctr
= &devmode_ctr
;
3482 r
.in
.secdesc_ctr
= &secdesc_ctr
;
3483 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_RESUME
;
3485 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
3487 status
= dcerpc_spoolss_SetPrinter_r(b
, tctx
, &r
);
3489 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
3491 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
3496 static bool test_GetPrinterData_checktype(struct torture_context
*tctx
,
3497 struct dcerpc_binding_handle
*b
,
3498 struct policy_handle
*handle
,
3499 const char *value_name
,
3500 enum winreg_Type
*expected_type
,
3501 enum winreg_Type
*type_p
,
3506 struct spoolss_GetPrinterData r
;
3508 enum winreg_Type type
;
3509 union spoolss_PrinterData data
;
3511 r
.in
.handle
= handle
;
3512 r
.in
.value_name
= value_name
;
3514 r
.out
.needed
= &needed
;
3516 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, r
.in
.offered
);
3518 torture_comment(tctx
, "Testing GetPrinterData(%s)\n", r
.in
.value_name
);
3520 status
= dcerpc_spoolss_GetPrinterData_r(b
, tctx
, &r
);
3521 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
3523 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
3524 if (expected_type
) {
3525 torture_assert_int_equal(tctx
, type
, *expected_type
, "unexpected type");
3527 r
.in
.offered
= needed
;
3528 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, r
.in
.offered
);
3529 status
= dcerpc_spoolss_GetPrinterData_r(b
, tctx
, &r
);
3530 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
3533 torture_assert_werr_ok(tctx
, r
.out
.result
,
3534 talloc_asprintf(tctx
, "GetPrinterData(%s) failed", r
.in
.value_name
));
3536 CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData
, &data
, type
, needed
, 1);
3543 *data_p
= r
.out
.data
;
3553 static bool test_GetPrinterData(struct torture_context
*tctx
,
3554 struct dcerpc_binding_handle
*b
,
3555 struct policy_handle
*handle
,
3556 const char *value_name
,
3557 enum winreg_Type
*type_p
,
3561 return test_GetPrinterData_checktype(tctx
, b
, handle
, value_name
,
3562 NULL
, type_p
, data_p
, needed_p
);
3565 static bool test_GetPrinterDataEx_checktype(struct torture_context
*tctx
,
3566 struct dcerpc_pipe
*p
,
3567 struct policy_handle
*handle
,
3568 const char *key_name
,
3569 const char *value_name
,
3570 enum winreg_Type
*expected_type
,
3571 enum winreg_Type
*type_p
,
3576 struct spoolss_GetPrinterDataEx r
;
3577 enum winreg_Type type
;
3579 union spoolss_PrinterData data
;
3580 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3582 r
.in
.handle
= handle
;
3583 r
.in
.key_name
= key_name
;
3584 r
.in
.value_name
= value_name
;
3587 r
.out
.needed
= &needed
;
3588 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, r
.in
.offered
);
3590 torture_comment(tctx
, "Testing GetPrinterDataEx(%s - %s)\n",
3591 r
.in
.key_name
, r
.in
.value_name
);
3593 status
= dcerpc_spoolss_GetPrinterDataEx_r(b
, tctx
, &r
);
3594 if (!NT_STATUS_IS_OK(status
)) {
3595 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
3596 torture_skip(tctx
, "GetPrinterDataEx not supported by server\n");
3598 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
3601 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
3602 if (expected_type
) {
3603 torture_assert_int_equal(tctx
, type
, *expected_type
, "unexpected type");
3605 r
.in
.offered
= needed
;
3606 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, r
.in
.offered
);
3607 status
= dcerpc_spoolss_GetPrinterDataEx_r(b
, tctx
, &r
);
3608 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
3611 torture_assert_werr_ok(tctx
, r
.out
.result
,
3612 talloc_asprintf(tctx
, "GetPrinterDataEx(%s - %s) failed", r
.in
.key_name
, r
.in
.value_name
));
3614 CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData
, &data
, type
, needed
, 1);
3621 *data_p
= r
.out
.data
;
3631 static bool test_GetPrinterDataEx(struct torture_context
*tctx
,
3632 struct dcerpc_pipe
*p
,
3633 struct policy_handle
*handle
,
3634 const char *key_name
,
3635 const char *value_name
,
3636 enum winreg_Type
*type_p
,
3640 return test_GetPrinterDataEx_checktype(tctx
, p
, handle
, key_name
, value_name
,
3641 NULL
, type_p
, data_p
, needed_p
);
3644 static bool test_get_environment(struct torture_context
*tctx
,
3645 struct dcerpc_binding_handle
*b
,
3646 struct policy_handle
*handle
,
3647 const char **architecture
)
3650 enum winreg_Type type
;
3654 torture_assert(tctx
,
3655 test_GetPrinterData(tctx
, b
, handle
, "Architecture", &type
, &data
, &needed
),
3656 "failed to get Architecture");
3658 torture_assert_int_equal(tctx
, type
, REG_SZ
, "unexpected type");
3660 blob
= data_blob_const(data
, needed
);
3661 *architecture
= reg_val_data_string(tctx
, REG_SZ
, blob
);
3666 static bool test_GetPrinterData_list(struct torture_context
*tctx
,
3669 struct test_spoolss_context
*ctx
=
3670 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
3671 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
3672 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3673 const char *list
[] = {
3677 /* "NetPopup", not on w2k8 */
3678 /* "NetPopupToComputer", not on w2k8 */
3681 "DefaultSpoolDirectory",
3685 /* "OSVersionEx", not on s3 */
3690 for (i
=0; i
< ARRAY_SIZE(list
); i
++) {
3691 enum winreg_Type type
, type_ex
;
3692 uint8_t *data
, *data_ex
;
3693 uint32_t needed
, needed_ex
;
3695 torture_assert(tctx
, test_GetPrinterData(tctx
, b
, &ctx
->server_handle
, list
[i
], &type
, &data
, &needed
),
3696 talloc_asprintf(tctx
, "GetPrinterData failed on %s\n", list
[i
]));
3697 torture_assert(tctx
, test_GetPrinterDataEx(tctx
, p
, &ctx
->server_handle
, "random_string", list
[i
], &type_ex
, &data_ex
, &needed_ex
),
3698 talloc_asprintf(tctx
, "GetPrinterDataEx failed on %s\n", list
[i
]));
3699 torture_assert_int_equal(tctx
, type
, type_ex
, "type mismatch");
3700 torture_assert_int_equal(tctx
, needed
, needed_ex
, "needed mismatch");
3701 torture_assert_mem_equal(tctx
, data
, data_ex
, needed
, "data mismatch");
3707 static bool test_EnumPrinterData(struct torture_context
*tctx
,
3708 struct dcerpc_pipe
*p
,
3709 struct policy_handle
*handle
,
3710 uint32_t enum_index
,
3711 uint32_t value_offered
,
3712 uint32_t data_offered
,
3713 enum winreg_Type
*type_p
,
3714 uint32_t *value_needed_p
,
3715 uint32_t *data_needed_p
,
3716 const char **value_name_p
,
3720 struct spoolss_EnumPrinterData r
;
3721 uint32_t data_needed
;
3722 uint32_t value_needed
;
3723 enum winreg_Type type
;
3724 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3726 r
.in
.handle
= handle
;
3727 r
.in
.enum_index
= enum_index
;
3728 r
.in
.value_offered
= value_offered
;
3729 r
.in
.data_offered
= data_offered
;
3730 r
.out
.data_needed
= &data_needed
;
3731 r
.out
.value_needed
= &value_needed
;
3733 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, r
.in
.data_offered
);
3734 r
.out
.value_name
= talloc_zero_array(tctx
, const char, r
.in
.value_offered
);
3736 torture_comment(tctx
, "Testing EnumPrinterData(%d)\n", enum_index
);
3738 torture_assert_ntstatus_ok(tctx
,
3739 dcerpc_spoolss_EnumPrinterData_r(b
, tctx
, &r
),
3740 "EnumPrinterData failed");
3745 if (value_needed_p
) {
3746 *value_needed_p
= value_needed
;
3748 if (data_needed_p
) {
3749 *data_needed_p
= data_needed
;
3752 *value_name_p
= r
.out
.value_name
;
3755 *data_p
= r
.out
.data
;
3758 *result_p
= r
.out
.result
;
3765 static bool test_EnumPrinterData_all(struct torture_context
*tctx
,
3766 struct dcerpc_pipe
*p
,
3767 struct policy_handle
*handle
)
3769 uint32_t enum_index
= 0;
3770 enum winreg_Type type
;
3771 uint32_t value_needed
;
3772 uint32_t data_needed
;
3774 const char *value_name
;
3777 torture_comment(tctx
, "Testing EnumPrinterData\n");
3780 torture_assert(tctx
,
3781 test_EnumPrinterData(tctx
, p
, handle
, enum_index
, 0, 0,
3782 &type
, &value_needed
, &data_needed
,
3783 &value_name
, &data
, &result
),
3784 "EnumPrinterData failed");
3786 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
)) {
3790 torture_assert(tctx
,
3791 test_EnumPrinterData(tctx
, p
, handle
, enum_index
, value_needed
, data_needed
,
3792 &type
, &value_needed
, &data_needed
,
3793 &value_name
, &data
, &result
),
3794 "EnumPrinterData failed");
3796 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
)) {
3802 } while (W_ERROR_IS_OK(result
));
3804 torture_comment(tctx
, "EnumPrinterData test succeeded\n");
3809 static bool test_EnumPrinterDataEx(struct torture_context
*tctx
,
3810 struct dcerpc_binding_handle
*b
,
3811 struct policy_handle
*handle
,
3812 const char *key_name
,
3814 struct spoolss_PrinterEnumValues
**info_p
)
3816 struct spoolss_EnumPrinterDataEx r
;
3817 struct spoolss_PrinterEnumValues
*info
;
3821 r
.in
.handle
= handle
;
3822 r
.in
.key_name
= key_name
;
3824 r
.out
.needed
= &needed
;
3825 r
.out
.count
= &count
;
3828 torture_comment(tctx
, "Testing EnumPrinterDataEx(%s)\n", key_name
);
3830 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinterDataEx_r(b
, tctx
, &r
),
3831 "EnumPrinterDataEx failed");
3832 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
3833 r
.in
.offered
= needed
;
3834 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinterDataEx_r(b
, tctx
, &r
),
3835 "EnumPrinterDataEx failed");
3838 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinterDataEx failed");
3840 CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx
, info
, count
, needed
, 1);
3852 static bool test_SetPrinterData(struct torture_context
*tctx
,
3853 struct dcerpc_binding_handle
*b
,
3854 struct policy_handle
*handle
,
3855 const char *value_name
,
3856 enum winreg_Type type
,
3859 static bool test_DeletePrinterData(struct torture_context
*tctx
,
3860 struct dcerpc_binding_handle
*b
,
3861 struct policy_handle
*handle
,
3862 const char *value_name
);
3864 static bool test_EnumPrinterData_consistency(struct torture_context
*tctx
,
3865 struct dcerpc_pipe
*p
,
3866 struct policy_handle
*handle
)
3869 struct spoolss_PrinterEnumValues
*info
;
3871 uint32_t value_needed
, data_needed
;
3872 uint32_t value_offered
, data_offered
;
3874 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3876 enum winreg_Type type
;
3879 torture_comment(tctx
, "Testing EnumPrinterData vs EnumPrinterDataEx consistency\n");
3881 torture_assert(tctx
, push_reg_sz(tctx
, &blob
, "torture_data1"), "");
3884 torture_assert(tctx
,
3885 test_SetPrinterData(tctx
, b
, handle
, "torture_value1", type
, blob
.data
, blob
.length
),
3886 "SetPrinterData failed");
3888 blob
= data_blob_string_const("torture_data2");
3890 torture_assert(tctx
,
3891 test_SetPrinterData(tctx
, b
, handle
, "torture_value2", REG_BINARY
, blob
.data
, blob
.length
),
3892 "SetPrinterData failed");
3894 blob
= data_blob_talloc(tctx
, NULL
, 4);
3895 SIVAL(blob
.data
, 0, 0x11223344);
3897 torture_assert(tctx
,
3898 test_SetPrinterData(tctx
, b
, handle
, "torture_value3", type
, blob
.data
, blob
.length
),
3899 "SetPrinterData failed");
3901 torture_assert(tctx
,
3902 test_EnumPrinterDataEx(tctx
, b
, handle
, "PrinterDriverData", &count
, &info
),
3903 "failed to call EnumPrinterDataEx");
3905 /* get the max sizes for value and data */
3907 torture_assert(tctx
,
3908 test_EnumPrinterData(tctx
, p
, handle
, 0, 0, 0,
3909 NULL
, &value_needed
, &data_needed
,
3910 NULL
, NULL
, &result
),
3911 "EnumPrinterData failed");
3912 torture_assert_werr_ok(tctx
, result
, "unexpected result");
3914 /* check if the reply from the EnumPrinterData really matches max values */
3916 for (i
=0; i
< count
; i
++) {
3917 if (info
[i
].value_name_len
> value_needed
) {
3919 talloc_asprintf(tctx
,
3920 "EnumPrinterDataEx gave a reply with value length %d which is larger then expected max value length %d from EnumPrinterData",
3921 info
[i
].value_name_len
, value_needed
));
3923 if (info
[i
].data_length
> data_needed
) {
3925 talloc_asprintf(tctx
,
3926 "EnumPrinterDataEx gave a reply with data length %d which is larger then expected max data length %d from EnumPrinterData",
3927 info
[i
].data_length
, data_needed
));
3931 /* assuming that both EnumPrinterData and EnumPrinterDataEx do either
3932 * sort or not sort the replies by value name, we should be able to do
3933 * the following entry comparison */
3935 data_offered
= data_needed
;
3936 value_offered
= value_needed
;
3938 for (i
=0; i
< count
; i
++) {
3940 const char *value_name
;
3943 torture_assert(tctx
,
3944 test_EnumPrinterData(tctx
, p
, handle
, i
, value_offered
, data_offered
,
3945 &type
, &value_needed
, &data_needed
,
3946 &value_name
, &data
, &result
),
3947 "EnumPrinterData failed");
3949 if (i
-1 == count
) {
3950 torture_assert_werr_equal(tctx
, result
, WERR_NO_MORE_ITEMS
,
3951 "unexpected result");
3954 torture_assert_werr_ok(tctx
, result
, "unexpected result");
3957 torture_assert_int_equal(tctx
, type
, info
[i
].type
, "type mismatch");
3958 torture_assert_int_equal(tctx
, value_needed
, info
[i
].value_name_len
, "value name length mismatch");
3959 torture_assert_str_equal(tctx
, value_name
, info
[i
].value_name
, "value name mismatch");
3960 torture_assert_int_equal(tctx
, data_needed
, info
[i
].data_length
, "data length mismatch");
3961 torture_assert_mem_equal(tctx
, data
, info
[i
].data
->data
, info
[i
].data_length
, "data mismatch");
3964 torture_assert(tctx
,
3965 test_DeletePrinterData(tctx
, b
, handle
, "torture_value1"),
3966 "DeletePrinterData failed");
3967 torture_assert(tctx
,
3968 test_DeletePrinterData(tctx
, b
, handle
, "torture_value2"),
3969 "DeletePrinterData failed");
3970 torture_assert(tctx
,
3971 test_DeletePrinterData(tctx
, b
, handle
, "torture_value3"),
3972 "DeletePrinterData failed");
3974 torture_comment(tctx
, "EnumPrinterData vs EnumPrinterDataEx consistency test succeeded\n\n");
3979 static bool test_DeletePrinterData(struct torture_context
*tctx
,
3980 struct dcerpc_binding_handle
*b
,
3981 struct policy_handle
*handle
,
3982 const char *value_name
)
3985 struct spoolss_DeletePrinterData r
;
3987 r
.in
.handle
= handle
;
3988 r
.in
.value_name
= value_name
;
3990 torture_comment(tctx
, "Testing DeletePrinterData(%s)\n",
3993 status
= dcerpc_spoolss_DeletePrinterData_r(b
, tctx
, &r
);
3995 torture_assert_ntstatus_ok(tctx
, status
, "DeletePrinterData failed");
3996 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeletePrinterData failed");
4001 static bool test_DeletePrinterDataEx(struct torture_context
*tctx
,
4002 struct dcerpc_binding_handle
*b
,
4003 struct policy_handle
*handle
,
4004 const char *key_name
,
4005 const char *value_name
)
4007 struct spoolss_DeletePrinterDataEx r
;
4009 r
.in
.handle
= handle
;
4010 r
.in
.key_name
= key_name
;
4011 r
.in
.value_name
= value_name
;
4013 torture_comment(tctx
, "Testing DeletePrinterDataEx(%s - %s)\n",
4014 r
.in
.key_name
, r
.in
.value_name
);
4016 torture_assert_ntstatus_ok(tctx
,
4017 dcerpc_spoolss_DeletePrinterDataEx_r(b
, tctx
, &r
),
4018 "DeletePrinterDataEx failed");
4019 torture_assert_werr_ok(tctx
, r
.out
.result
,
4020 "DeletePrinterDataEx failed");
4025 static bool test_DeletePrinterKey(struct torture_context
*tctx
,
4026 struct dcerpc_binding_handle
*b
,
4027 struct policy_handle
*handle
,
4028 const char *key_name
)
4030 struct spoolss_DeletePrinterKey r
;
4032 r
.in
.handle
= handle
;
4033 r
.in
.key_name
= key_name
;
4035 torture_comment(tctx
, "Testing DeletePrinterKey(%s)\n", r
.in
.key_name
);
4037 if (strequal(key_name
, "") && !torture_setting_bool(tctx
, "dangerous", false)) {
4038 torture_skip(tctx
, "not wiping out printer registry - enable dangerous tests to use\n");
4042 torture_assert_ntstatus_ok(tctx
,
4043 dcerpc_spoolss_DeletePrinterKey_r(b
, tctx
, &r
),
4044 "DeletePrinterKey failed");
4045 torture_assert_werr_ok(tctx
, r
.out
.result
,
4046 "DeletePrinterKey failed");
4051 static bool test_winreg_OpenHKLM(struct torture_context
*tctx
,
4052 struct dcerpc_binding_handle
*b
,
4053 struct policy_handle
*handle
)
4055 struct winreg_OpenHKLM r
;
4057 r
.in
.system_name
= NULL
;
4058 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4059 r
.out
.handle
= handle
;
4061 torture_comment(tctx
, "Testing winreg_OpenHKLM\n");
4063 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenHKLM_r(b
, tctx
, &r
), "OpenHKLM failed");
4064 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenHKLM failed");
4069 static void init_winreg_String(struct winreg_String
*name
, const char *s
)
4073 name
->name_len
= 2 * (strlen_m(s
) + 1);
4074 name
->name_size
= name
->name_len
;
4077 name
->name_size
= 0;
4081 static bool test_winreg_OpenKey_opts(struct torture_context
*tctx
,
4082 struct dcerpc_binding_handle
*b
,
4083 struct policy_handle
*hive_handle
,
4084 const char *keyname
,
4086 struct policy_handle
*key_handle
)
4088 struct winreg_OpenKey r
;
4090 r
.in
.parent_handle
= hive_handle
;
4091 init_winreg_String(&r
.in
.keyname
, keyname
);
4092 r
.in
.options
= options
;
4093 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4094 r
.out
.handle
= key_handle
;
4096 torture_comment(tctx
, "Testing winreg_OpenKey(%s)\n", keyname
);
4098 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenKey_r(b
, tctx
, &r
), "OpenKey failed");
4099 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenKey failed");
4104 static bool test_winreg_OpenKey(struct torture_context
*tctx
,
4105 struct dcerpc_binding_handle
*b
,
4106 struct policy_handle
*hive_handle
,
4107 const char *keyname
,
4108 struct policy_handle
*key_handle
)
4110 return test_winreg_OpenKey_opts(tctx
, b
, hive_handle
, keyname
,
4111 REG_OPTION_NON_VOLATILE
, key_handle
);
4114 static bool test_winreg_CloseKey(struct torture_context
*tctx
,
4115 struct dcerpc_binding_handle
*b
,
4116 struct policy_handle
*handle
)
4118 struct winreg_CloseKey r
;
4120 r
.in
.handle
= handle
;
4121 r
.out
.handle
= handle
;
4123 torture_comment(tctx
, "Testing winreg_CloseKey\n");
4125 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CloseKey_r(b
, tctx
, &r
), "CloseKey failed");
4126 torture_assert_werr_ok(tctx
, r
.out
.result
, "CloseKey failed");
4131 bool test_winreg_QueryValue(struct torture_context
*tctx
,
4132 struct dcerpc_binding_handle
*b
,
4133 struct policy_handle
*handle
,
4134 const char *value_name
,
4135 enum winreg_Type
*type_p
,
4136 uint32_t *data_size_p
,
4137 uint32_t *data_length_p
,
4140 struct winreg_QueryValue r
;
4141 enum winreg_Type type
= REG_NONE
;
4142 uint32_t data_size
= 0;
4143 uint32_t data_length
= 0;
4144 struct winreg_String valuename
;
4145 uint8_t *data
= NULL
;
4147 init_winreg_String(&valuename
, value_name
);
4149 data
= talloc_zero_array(tctx
, uint8_t, 0);
4151 r
.in
.handle
= handle
;
4152 r
.in
.value_name
= &valuename
;
4154 r
.in
.data_size
= &data_size
;
4155 r
.in
.data_length
= &data_length
;
4159 r
.out
.data_size
= &data_size
;
4160 r
.out
.data_length
= &data_length
;
4162 torture_comment(tctx
, "Testing winreg_QueryValue(%s)\n", value_name
);
4164 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
), "QueryValue failed");
4165 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
4166 *r
.in
.data_size
= *r
.out
.data_size
;
4167 data
= talloc_zero_array(tctx
, uint8_t, *r
.in
.data_size
);
4170 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
), "QueryValue failed");
4172 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
4175 *type_p
= *r
.out
.type
;
4178 *data_size_p
= *r
.out
.data_size
;
4180 if (data_length_p
) {
4181 *data_length_p
= *r
.out
.data_length
;
4184 *data_p
= r
.out
.data
;
4190 static bool test_winreg_query_printerdata(struct torture_context
*tctx
,
4191 struct dcerpc_binding_handle
*b
,
4192 struct policy_handle
*handle
,
4193 const char *printer_name
,
4194 const char *key_name
,
4195 const char *value_name
,
4196 enum winreg_Type
*w_type
,
4201 const char *printer_key
;
4202 struct policy_handle key_handle
;
4204 printer_key
= talloc_asprintf(tctx
, "%s\\%s\\%s",
4205 TOP_LEVEL_PRINT_PRINTERS_KEY
, printer_name
, key_name
);
4207 torture_assert(tctx
,
4208 test_winreg_OpenKey(tctx
, b
, handle
, printer_key
, &key_handle
), "");
4210 torture_assert(tctx
,
4211 test_winreg_QueryValue(tctx
, b
, &key_handle
, value_name
, w_type
, w_size
, w_length
, w_data
), "");
4213 torture_assert(tctx
,
4214 test_winreg_CloseKey(tctx
, b
, &key_handle
), "");
4219 static bool test_GetForm_winreg(struct torture_context
*tctx
,
4220 struct dcerpc_binding_handle
*b
,
4221 struct policy_handle
*handle
,
4222 const char *key_name
,
4223 const char *form_name
,
4224 enum winreg_Type
*w_type
,
4229 struct policy_handle key_handle
;
4231 torture_assert(tctx
,
4232 test_winreg_OpenKey(tctx
, b
, handle
, key_name
, &key_handle
), "");
4234 torture_assert(tctx
,
4235 test_winreg_QueryValue(tctx
, b
, &key_handle
, form_name
, w_type
, w_size
, w_length
, w_data
), "");
4237 torture_assert(tctx
,
4238 test_winreg_CloseKey(tctx
, b
, &key_handle
), "");
4243 static bool test_winreg_symbolic_link(struct torture_context
*tctx
,
4244 struct dcerpc_binding_handle
*b
,
4245 struct policy_handle
*handle
,
4246 const char *symlink_keyname
,
4247 const char *symlink_destination
)
4249 /* check if the first key is a symlink to the second key */
4251 enum winreg_Type w_type
;
4255 struct policy_handle key_handle
;
4259 if (torture_setting_bool(tctx
, "samba3", false)) {
4260 torture_skip(tctx
, "skip winreg symlink test against samba");
4263 torture_assert(tctx
,
4264 test_winreg_OpenKey_opts(tctx
, b
, handle
, symlink_keyname
, REG_OPTION_OPEN_LINK
, &key_handle
),
4265 "failed to open key link");
4267 torture_assert(tctx
,
4268 test_winreg_QueryValue(tctx
, b
, &key_handle
,
4269 "SymbolicLinkValue",
4270 &w_type
, &w_size
, &w_length
, &w_data
),
4271 "failed to query for 'SymbolicLinkValue' attribute");
4273 torture_assert_int_equal(tctx
, w_type
, REG_LINK
, "unexpected type");
4275 blob
= data_blob(w_data
, w_size
);
4276 str
= reg_val_data_string(tctx
, REG_SZ
, blob
);
4278 torture_assert_str_equal(tctx
, str
, symlink_destination
, "unexpected symlink target string");
4280 torture_assert(tctx
,
4281 test_winreg_CloseKey(tctx
, b
, &key_handle
),
4282 "failed to close key link");
4287 static const char *strip_unc(const char *unc
)
4295 if (unc
[0] == '\\' && unc
[1] == '\\') {
4299 name
= strchr(unc
, '\\');
4307 static bool test_GetPrinterInfo_winreg(struct torture_context
*tctx
,
4308 struct dcerpc_binding_handle
*b
,
4309 struct policy_handle
*handle
,
4310 const char *printer_name
,
4311 struct dcerpc_binding_handle
*winreg_handle
,
4312 struct policy_handle
*hive_handle
)
4314 union spoolss_PrinterInfo info
;
4315 const char *keys
[] = {
4316 TOP_LEVEL_CONTROL_PRINTERS_KEY
,
4317 TOP_LEVEL_PRINT_PRINTERS_KEY
4320 const char *printername
, *sharename
;
4322 torture_comment(tctx
, "Testing Printer Info and winreg consistency\n");
4324 torture_assert(tctx
,
4325 test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
4326 "failed to get printer info level 2");
4328 printername
= strip_unc(info
.info2
.printername
);
4329 sharename
= strip_unc(info
.info2
.sharename
);
4331 #define test_sz(wname, iname) \
4335 enum winreg_Type w_type;\
4339 torture_assert(tctx,\
4340 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4341 &w_type, &w_size, &w_length, &w_data),\
4342 "failed to query winreg");\
4343 torture_assert_int_equal(tctx, w_type, REG_SZ, "unexpected type");\
4344 blob = data_blob(w_data, w_size);\
4345 str = reg_val_data_string(tctx, REG_SZ, blob);\
4346 if (w_size == 2 && iname == NULL) {\
4347 /*torture_comment(tctx, "%s: \"\", %s: (null)\n", #wname, #iname);\ */\
4349 torture_assert_str_equal(tctx, str, iname,\
4350 talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4354 #define test_dword(wname, iname) \
4357 enum winreg_Type w_type;\
4361 torture_assert(tctx,\
4362 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4363 &w_type, &w_size, &w_length, &w_data),\
4364 "failed to query winreg");\
4365 torture_assert_int_equal(tctx, w_type, REG_DWORD, "unexpected type");\
4366 torture_assert_int_equal(tctx, w_size, 4, "unexpected size");\
4367 torture_assert_int_equal(tctx, w_length, 4, "unexpected length");\
4368 value = IVAL(w_data, 0);\
4369 torture_assert_int_equal(tctx, value, iname,\
4370 talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4373 #define test_binary(wname, iname) \
4375 enum winreg_Type w_type;\
4379 torture_assert(tctx,\
4380 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4381 &w_type, &w_size, &w_length, &w_data),\
4382 "failed to query winreg");\
4383 torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4384 torture_assert_int_equal(tctx, w_size, iname.length, "unexpected length");\
4385 torture_assert_mem_equal(tctx, w_data, iname.data, w_size, \
4390 #define test_dm(wname, iname) \
4393 struct spoolss_DeviceMode dm;\
4394 enum ndr_err_code ndr_err;\
4395 enum winreg_Type w_type;\
4399 torture_assert(tctx,\
4400 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4401 &w_type, &w_size, &w_length, &w_data),\
4402 "failed to query winreg");\
4403 torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4404 blob = data_blob(w_data, w_size);\
4405 ndr_err = ndr_pull_struct_blob(&blob, tctx, &dm,\
4406 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);\
4407 torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall dm");\
4408 torture_assert(tctx, test_devicemode_equal(tctx, &dm, iname),\
4412 #define test_sd(wname, iname) \
4415 struct security_descriptor sd;\
4416 enum ndr_err_code ndr_err;\
4417 enum winreg_Type w_type;\
4421 torture_assert(tctx,\
4422 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4423 &w_type, &w_size, &w_length, &w_data),\
4424 "failed to query winreg");\
4425 torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4426 blob = data_blob(w_data, w_size);\
4427 ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,\
4428 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);\
4429 torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall sd");\
4430 torture_assert(tctx, test_security_descriptor_equal(tctx, &sd, iname),\
4434 #define test_multi_sz(wname, iname) \
4437 const char **array;\
4438 enum winreg_Type w_type;\
4443 torture_assert(tctx,\
4444 test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4445 &w_type, &w_size, &w_length, &w_data),\
4446 "failed to query winreg");\
4447 torture_assert_int_equal(tctx, w_type, REG_MULTI_SZ, "unexpected type");\
4448 blob = data_blob(w_data, w_size);\
4449 torture_assert(tctx, \
4450 pull_reg_multi_sz(tctx, &blob, &array),\
4451 "failed to pull multi sz");\
4452 for (i=0; array[i] != NULL; i++) {\
4453 torture_assert_str_equal(tctx, array[i], iname[i],\
4454 talloc_asprintf(tctx, "%s - %s mismatch", #wname, iname[i]));\
4458 if (!test_winreg_symbolic_link(tctx
, winreg_handle
, hive_handle
,
4459 TOP_LEVEL_CONTROL_PRINTERS_KEY
,
4460 "\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"))
4462 torture_warning(tctx
, "failed to check for winreg symlink");
4465 for (i
=0; i
< ARRAY_SIZE(keys
); i
++) {
4467 const char *printer_key
;
4468 struct policy_handle key_handle
;
4470 printer_key
= talloc_asprintf(tctx
, "%s\\%s",
4471 keys
[i
], printer_name
);
4473 torture_assert(tctx
,
4474 test_winreg_OpenKey(tctx
, winreg_handle
, hive_handle
, printer_key
, &key_handle
), "");
4476 test_sz("Name", printername
);
4477 test_sz("Share Name", sharename
);
4478 test_sz("Port", info
.info2
.portname
);
4479 test_sz("Printer Driver", info
.info2
.drivername
);
4480 test_sz("Description", info
.info2
.comment
);
4481 test_sz("Location", info
.info2
.location
);
4482 test_sz("Separator File", info
.info2
.sepfile
);
4483 test_sz("Print Processor", info
.info2
.printprocessor
);
4484 test_sz("Datatype", info
.info2
.datatype
);
4485 test_sz("Parameters", info
.info2
.parameters
);
4486 /* winreg: 0, spoolss not */
4487 /* test_dword("Attributes", info.info2.attributes); */
4488 test_dword("Priority", info
.info2
.priority
);
4489 test_dword("Default Priority", info
.info2
.defaultpriority
);
4490 /* winreg: 60, spoolss: 0 */
4491 /* test_dword("StartTime", info.info2.starttime); */
4492 /* test_dword("UntilTime", info.info2.untiltime); */
4493 /* winreg != spoolss */
4494 /* test_dword("Status", info.info2.status); */
4495 test_dm("Default DevMode", info
.info2
.devmode
);
4496 test_sd("Security", info
.info2
.secdesc
);
4498 torture_assert(tctx
,
4499 test_winreg_CloseKey(tctx
, winreg_handle
, &key_handle
), "");
4505 torture_comment(tctx
, "Printer Info and winreg consistency test succeeded\n\n");
4510 static bool test_PrintProcessors(struct torture_context
*tctx
,
4511 struct dcerpc_binding_handle
*b
,
4512 const char *environment
,
4513 struct dcerpc_binding_handle
*winreg_handle
,
4514 struct policy_handle
*hive_handle
)
4516 union spoolss_PrintProcessorInfo
*info
;
4520 torture_comment(tctx
, "Testing Print Processor Info and winreg consistency\n");
4522 torture_assert(tctx
,
4523 test_EnumPrintProcessors_level(tctx
, b
, environment
, 1, &count
, &info
, WERR_OK
),
4524 "failed to enum print processors level 1");
4526 for (i
=0; i
< count
; i
++) {
4528 const char *processor_key
;
4529 struct policy_handle key_handle
;
4531 processor_key
= talloc_asprintf(tctx
, "%s\\%s\\Print Processors\\%s",
4532 TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY
,
4534 info
[i
].info1
.print_processor_name
);
4536 torture_assert(tctx
,
4537 test_winreg_OpenKey(tctx
, winreg_handle
, hive_handle
, processor_key
, &key_handle
), "");
4539 /* nothing to check in there so far */
4541 torture_assert(tctx
,
4542 test_winreg_CloseKey(tctx
, winreg_handle
, &key_handle
), "");
4545 torture_comment(tctx
, "Print Processor Info and winreg consistency test succeeded\n\n");
4550 static bool test_GetPrinterDriver2_level(struct torture_context
*tctx
,
4551 struct dcerpc_binding_handle
*b
,
4552 struct policy_handle
*handle
,
4553 const char *driver_name
,
4554 const char *architecture
,
4556 uint32_t client_major_version
,
4557 uint32_t client_minor_version
,
4558 union spoolss_DriverInfo
*info_p
,
4561 static const char *strip_path(const char *path
)
4569 p
= strrchr(path
, '\\');
4577 static const char **strip_paths(const char **path_array
)
4581 if (path_array
== NULL
) {
4585 for (i
=0; path_array
[i
] != NULL
; i
++) {
4586 path_array
[i
] = strip_path(path_array
[i
]);
4592 static const char *driver_winreg_date(TALLOC_CTX
*mem_ctx
, NTTIME nt
)
4598 return talloc_strdup(mem_ctx
, "01/01/1601");
4601 t
= nt_time_to_unix(nt
);
4604 return talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
4605 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
4608 static const char *driver_winreg_version(TALLOC_CTX
*mem_ctx
, uint64_t v
)
4610 return talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
4611 (unsigned)((v
>> 48) & 0xFFFF),
4612 (unsigned)((v
>> 32) & 0xFFFF),
4613 (unsigned)((v
>> 16) & 0xFFFF),
4614 (unsigned)(v
& 0xFFFF));
4617 static bool test_GetDriverInfo_winreg(struct torture_context
*tctx
,
4618 struct dcerpc_binding_handle
*b
,
4619 struct policy_handle
*handle
,
4620 const char *printer_name
,
4621 const char *driver_name
,
4622 const char *environment
,
4623 enum spoolss_DriverOSVersion version
,
4624 struct dcerpc_binding_handle
*winreg_handle
,
4625 struct policy_handle
*hive_handle
,
4626 const char *server_name_slash
)
4629 union spoolss_DriverInfo info
;
4630 const char *driver_key
;
4631 struct policy_handle key_handle
;
4633 const char *driver_path
;
4634 const char *data_file
;
4635 const char *config_file
;
4636 const char *help_file
;
4637 const char **dependent_files
;
4639 const char *driver_date
;
4640 const char *inbox_driver_date
;
4642 const char *driver_version
;
4643 const char *inbox_driver_version
;
4645 torture_comment(tctx
, "Testing Driver Info and winreg consistency\n");
4647 driver_key
= talloc_asprintf(tctx
, "%s\\%s\\Drivers\\Version-%d\\%s",
4648 TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY
,
4653 torture_assert(tctx
,
4654 test_winreg_OpenKey(tctx
, winreg_handle
, hive_handle
, driver_key
, &key_handle
),
4655 "failed to open driver key");
4657 if (torture_setting_bool(tctx
, "samba3", false)) {
4661 if (torture_setting_bool(tctx
, "w2k3", false)) {
4666 torture_assert(tctx
,
4667 test_GetPrinterDriver2_level(tctx
, b
, handle
, driver_name
, environment
, 8, version
, 0, &info
, &result
),
4668 "failed to get driver info level 8");
4670 torture_assert(tctx
,
4671 test_EnumPrinterDrivers_findone(tctx
, b
, server_name_slash
, environment
, 8, driver_name
, &info
),
4672 "failed to get driver info level 8");
4675 if (W_ERROR_EQUAL(result
, WERR_INVALID_LEVEL
)) {
4679 driver_path
= strip_path(info
.info8
.driver_path
);
4680 data_file
= strip_path(info
.info8
.data_file
);
4681 config_file
= strip_path(info
.info8
.config_file
);
4682 help_file
= strip_path(info
.info8
.help_file
);
4683 dependent_files
= strip_paths(info
.info8
.dependent_files
);
4685 driver_date
= driver_winreg_date(tctx
, info
.info8
.driver_date
);
4686 inbox_driver_date
= driver_winreg_date(tctx
, info
.info8
.min_inbox_driver_ver_date
);
4688 driver_version
= driver_winreg_version(tctx
, info
.info8
.driver_version
);
4689 inbox_driver_version
= driver_winreg_version(tctx
, info
.info8
.min_inbox_driver_ver_version
);
4691 test_sz("Configuration File", config_file
);
4692 test_sz("Data File", data_file
);
4693 test_sz("Datatype", info
.info8
.default_datatype
);
4694 test_sz("Driver", driver_path
);
4695 test_sz("DriverDate", driver_date
);
4696 test_sz("DriverVersion", driver_version
);
4697 test_sz("HardwareID", info
.info8
.hardware_id
);
4698 test_sz("Help File", help_file
);
4699 test_sz("InfPath", info
.info8
.inf_path
);
4700 test_sz("Manufacturer", info
.info8
.manufacturer_name
);
4701 test_sz("MinInboxDriverVerDate", inbox_driver_date
);
4702 test_sz("MinInboxDriverVerVersion", inbox_driver_version
);
4703 test_sz("Monitor", info
.info8
.monitor_name
);
4704 test_sz("OEM URL", info
.info8
.manufacturer_url
);
4705 test_sz("Print Processor", info
.info8
.print_processor
);
4706 test_sz("Provider", info
.info8
.provider
);
4707 test_sz("VendorSetup", info
.info8
.vendor_setup
);
4708 test_multi_sz("ColorProfiles", info
.info8
.color_profiles
);
4709 test_multi_sz("Dependent Files", dependent_files
);
4710 test_multi_sz("CoreDependencies", info
.info8
.core_driver_dependencies
);
4711 test_multi_sz("Previous Names", info
.info8
.previous_names
);
4712 /* test_dword("Attributes", ?); */
4713 test_dword("PrinterDriverAttributes", info
.info8
.printer_driver_attributes
);
4714 test_dword("Version", info
.info8
.version
);
4715 /* test_dword("TempDir", ?); */
4720 torture_assert(tctx
,
4721 test_GetPrinterDriver2_level(tctx
, b
, handle
, driver_name
, environment
, 6, version
, 0, &info
, &result
),
4722 "failed to get driver info level 6");
4724 torture_assert(tctx
,
4725 test_EnumPrinterDrivers_findone(tctx
, b
, server_name_slash
, environment
, 6, driver_name
, &info
),
4726 "failed to get driver info level 6");
4729 driver_path
= strip_path(info
.info6
.driver_path
);
4730 data_file
= strip_path(info
.info6
.data_file
);
4731 config_file
= strip_path(info
.info6
.config_file
);
4732 help_file
= strip_path(info
.info6
.help_file
);
4733 dependent_files
= strip_paths(info
.info6
.dependent_files
);
4735 driver_date
= driver_winreg_date(tctx
, info
.info6
.driver_date
);
4737 driver_version
= driver_winreg_version(tctx
, info
.info6
.driver_version
);
4739 test_sz("Configuration File", config_file
);
4740 test_sz("Data File", data_file
);
4741 test_sz("Datatype", info
.info6
.default_datatype
);
4742 test_sz("Driver", driver_path
);
4743 if (torture_setting_bool(tctx
, "w2k3", false)) {
4744 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, 8);
4745 push_nttime(blob
.data
, 0, info
.info6
.driver_date
);
4746 test_binary("DriverDate", blob
);
4747 SBVAL(blob
.data
, 0, info
.info6
.driver_version
);
4748 test_binary("DriverVersion", blob
);
4750 test_sz("DriverDate", driver_date
);
4751 test_sz("DriverVersion", driver_version
);
4753 test_sz("HardwareID", info
.info6
.hardware_id
);
4754 test_sz("Help File", help_file
);
4755 test_sz("Manufacturer", info
.info6
.manufacturer_name
);
4756 test_sz("Monitor", info
.info6
.monitor_name
);
4757 test_sz("OEM URL", info
.info6
.manufacturer_url
);
4758 test_sz("Provider", info
.info6
.provider
);
4759 test_multi_sz("Dependent Files", dependent_files
);
4760 test_multi_sz("Previous Names", info
.info6
.previous_names
);
4761 /* test_dword("Attributes", ?); */
4762 test_dword("Version", info
.info6
.version
);
4763 /* test_dword("TempDir", ?); */
4768 torture_assert(tctx
,
4769 test_GetPrinterDriver2_level(tctx
, b
, handle
, driver_name
, environment
, 3, version
, 0, &info
, &result
),
4770 "failed to get driver info level 3");
4772 torture_assert(tctx
,
4773 test_EnumPrinterDrivers_findone(tctx
, b
, server_name_slash
, environment
, 3, driver_name
, &info
),
4774 "failed to get driver info level 3");
4777 driver_path
= strip_path(info
.info3
.driver_path
);
4778 data_file
= strip_path(info
.info3
.data_file
);
4779 config_file
= strip_path(info
.info3
.config_file
);
4780 help_file
= strip_path(info
.info3
.help_file
);
4781 dependent_files
= strip_paths(info
.info3
.dependent_files
);
4783 test_sz("Configuration File", config_file
);
4784 test_sz("Data File", data_file
);
4785 test_sz("Datatype", info
.info3
.default_datatype
);
4786 test_sz("Driver", driver_path
);
4787 test_sz("Help File", help_file
);
4788 test_sz("Monitor", info
.info3
.monitor_name
);
4789 test_multi_sz("Dependent Files", dependent_files
);
4790 /* test_dword("Attributes", ?); */
4791 test_dword("Version", info
.info3
.version
);
4792 /* test_dword("TempDir", ?); */
4795 torture_assert(tctx
,
4796 test_winreg_CloseKey(tctx
, winreg_handle
, &key_handle
), "");
4798 torture_comment(tctx
, "Driver Info and winreg consistency test succeeded\n\n");
4806 static bool test_SetPrinterData(struct torture_context
*tctx
,
4807 struct dcerpc_binding_handle
*b
,
4808 struct policy_handle
*handle
,
4809 const char *value_name
,
4810 enum winreg_Type type
,
4814 struct spoolss_SetPrinterData r
;
4816 r
.in
.handle
= handle
;
4817 r
.in
.value_name
= value_name
;
4820 r
.in
.offered
= offered
;
4822 torture_comment(tctx
, "Testing SetPrinterData(%s)\n",
4825 torture_assert_ntstatus_ok(tctx
,
4826 dcerpc_spoolss_SetPrinterData_r(b
, tctx
, &r
),
4827 "SetPrinterData failed");
4828 torture_assert_werr_ok(tctx
, r
.out
.result
,
4829 "SetPrinterData failed");
4834 static bool test_SetPrinterData_matrix(struct torture_context
*tctx
,
4835 struct dcerpc_binding_handle
*b
,
4836 struct policy_handle
*handle
,
4837 const char *printer_name
,
4838 struct dcerpc_binding_handle
*winreg_handle
,
4839 struct policy_handle
*hive_handle
)
4841 const char *values
[] = {
4845 /* FIXME: not working with s3 atm. */
4851 /* FIXME: not working with s3 atm. */
4858 for (i
=0; i
< ARRAY_SIZE(values
); i
++) {
4860 enum winreg_Type type
, expected_type
= REG_SZ
;
4865 torture_assert(tctx
, push_reg_sz(tctx
, &blob
, "dog"), "");
4868 torture_assert(tctx
,
4869 test_SetPrinterData(tctx
, b
, handle
, values
[i
], REG_SZ
, blob
.data
, blob
.length
),
4870 "SetPrinterData failed");
4872 torture_assert(tctx
,
4873 test_GetPrinterData_checktype(tctx
, b
, handle
, values
[i
], &expected_type
, &type
, &data
, &needed
),
4874 "GetPrinterData failed");
4876 torture_assert_int_equal(tctx
, type
, REG_SZ
, "type mismatch");
4877 torture_assert_int_equal(tctx
, needed
, blob
.length
, "size mismatch");
4878 torture_assert_mem_equal(tctx
, data
, blob
.data
, blob
.length
, "buffer mismatch");
4880 if (winreg_handle
&& hive_handle
) {
4882 enum winreg_Type w_type
;
4887 torture_assert(tctx
,
4888 test_winreg_query_printerdata(tctx
, winreg_handle
, hive_handle
,
4889 printer_name
, "PrinterDriverData", values
[i
],
4890 &w_type
, &w_size
, &w_length
, &w_data
), "");
4892 torture_assert_int_equal(tctx
, w_type
, REG_SZ
, "winreg type mismatch");
4893 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
4894 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
4895 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
4898 torture_assert(tctx
,
4899 test_DeletePrinterData(tctx
, b
, handle
, values
[i
]),
4900 "DeletePrinterData failed");
4907 static bool test_EnumPrinterKey(struct torture_context
*tctx
,
4908 struct dcerpc_binding_handle
*b
,
4909 struct policy_handle
*handle
,
4910 const char *key_name
,
4911 const char ***array
);
4913 static bool test_SetPrinterDataEx(struct torture_context
*tctx
,
4914 struct dcerpc_binding_handle
*b
,
4915 struct policy_handle
*handle
,
4916 const char *key_name
,
4917 const char *value_name
,
4918 enum winreg_Type type
,
4923 struct spoolss_SetPrinterDataEx r
;
4925 r
.in
.handle
= handle
;
4926 r
.in
.key_name
= key_name
;
4927 r
.in
.value_name
= value_name
;
4930 r
.in
.offered
= offered
;
4932 torture_comment(tctx
, "Testing SetPrinterDataEx(%s - %s) type: %s, offered: 0x%08x\n",
4933 r
.in
.key_name
, r
.in
.value_name
, str_regtype(r
.in
.type
), r
.in
.offered
);
4935 status
= dcerpc_spoolss_SetPrinterDataEx_r(b
, tctx
, &r
);
4937 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinterDataEx failed");
4938 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinterDataEx failed");
4943 static bool test_SetPrinterDataEx_keys(struct torture_context
*tctx
,
4944 struct dcerpc_pipe
*p
,
4945 struct policy_handle
*handle
)
4947 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4948 const char *value_name
= "dog";
4949 const char *keys
[] = {
4952 "torturedataex_with_subkey\\subkey",
4953 "torturedataex_with_subkey\\subkey:0",
4954 "torturedataex_with_subkey\\subkey:1",
4955 "torturedataex_with_subkey\\subkey\\subsubkey",
4956 "torturedataex_with_subkey\\subkey\\subsubkey:0",
4957 "torturedataex_with_subkey\\subkey\\subsubkey:1",
4964 "torture/data ex/sub",
4967 "torture//data ex/sub",
4968 "torture//data ex//sub",
4972 for (i
=0; i
< ARRAY_SIZE(keys
); i
++) {
4976 enum winreg_Type type
;
4977 DATA_BLOB blob_in
, blob_out
;
4978 const char **subkeys
;
4980 struct spoolss_PrinterEnumValues
*einfo
;
4983 blob_in
= data_blob_talloc(tctx
, NULL
, 42);
4985 generate_random_buffer(blob_in
.data
, blob_in
.length
);
4987 torture_assert(tctx
,
4988 test_SetPrinterDataEx(tctx
, b
, handle
, keys
[i
], value_name
, REG_BINARY
, blob_in
.data
, blob_in
.length
),
4989 "failed to call SetPrinterDataEx");
4991 torture_assert(tctx
,
4992 test_GetPrinterDataEx(tctx
, p
, handle
, keys
[i
], value_name
, &type
, &blob_out
.data
, &needed
),
4993 "failed to call GetPrinterDataEx");
4995 blob_out
.length
= needed
;
4996 torture_assert(tctx
,
4997 test_EnumPrinterDataEx(tctx
, b
, handle
, keys
[i
], &ecount
, &einfo
),
4998 "failed to call EnumPrinterDataEx");
5000 torture_assert_int_equal(tctx
, type
, REG_BINARY
, "type mismatch");
5001 torture_assert_int_equal(tctx
, blob_out
.length
, blob_in
.length
, "size mismatch");
5002 torture_assert_mem_equal(tctx
, blob_out
.data
, blob_in
.data
, blob_in
.length
, "buffer mismatch");
5004 torture_assert_int_equal(tctx
, ecount
, 1, "unexpected enum count");
5005 torture_assert_str_equal(tctx
, einfo
[0].value_name
, value_name
, "value_name mismatch");
5006 torture_assert_int_equal(tctx
, einfo
[0].value_name_len
, strlen_m_term(value_name
)*2, "unexpected value_name_len");
5007 torture_assert_int_equal(tctx
, einfo
[0].type
, REG_BINARY
, "type mismatch");
5008 torture_assert_int_equal(tctx
, einfo
[0].data_length
, blob_in
.length
, "size mismatch");
5009 if (einfo
[0].data_length
> 0) {
5010 torture_assert_mem_equal(tctx
, einfo
[0].data
->data
, blob_in
.data
, blob_in
.length
, "buffer mismatch");
5013 key
= talloc_strdup(tctx
, keys
[i
]);
5015 if (!test_DeletePrinterDataEx(tctx
, b
, handle
, keys
[i
], value_name
)) {
5019 c
= strchr(key
, '\\');
5023 /* we have subkeys */
5027 if (!test_EnumPrinterKey(tctx
, b
, handle
, key
, &subkeys
)) {
5031 for (k
=0; subkeys
&& subkeys
[k
]; k
++) {
5033 const char *current_key
= talloc_asprintf(tctx
, "%s\\%s", key
, subkeys
[k
]);
5035 if (!test_DeletePrinterKey(tctx
, b
, handle
, current_key
)) {
5040 if (!test_DeletePrinterKey(tctx
, b
, handle
, key
)) {
5045 if (!test_DeletePrinterKey(tctx
, b
, handle
, key
)) {
5054 static bool test_SetPrinterDataEx_values(struct torture_context
*tctx
,
5055 struct dcerpc_pipe
*p
,
5056 struct policy_handle
*handle
)
5058 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5059 const char *key
= "torturedataex";
5060 const char *values
[] = {
5070 for (i
=0; i
< ARRAY_SIZE(values
); i
++) {
5072 enum winreg_Type type
;
5073 DATA_BLOB blob_in
, blob_out
;
5075 struct spoolss_PrinterEnumValues
*einfo
;
5078 if (torture_setting_bool(tctx
, "samba3", false)) {
5080 q
= strrchr(values
[i
], ',');
5082 torture_comment(tctx
, "skipping valuename '%s' including ',' character against Samba3\n",
5088 blob_in
= data_blob_talloc(tctx
, NULL
, 42);
5090 generate_random_buffer(blob_in
.data
, blob_in
.length
);
5092 torture_assert(tctx
,
5093 test_SetPrinterDataEx(tctx
, b
, handle
, key
, values
[i
], REG_BINARY
, blob_in
.data
, blob_in
.length
),
5094 "failed to call SetPrinterDataEx");
5096 torture_assert(tctx
,
5097 test_GetPrinterDataEx(tctx
, p
, handle
, key
, values
[i
], &type
, &blob_out
.data
, &needed
),
5098 "failed to call GetPrinterDataEx");
5100 blob_out
.length
= needed
;
5101 torture_assert(tctx
,
5102 test_EnumPrinterDataEx(tctx
, b
, handle
, key
, &ecount
, &einfo
),
5103 "failed to call EnumPrinterDataEx");
5105 torture_assert_int_equal(tctx
, type
, REG_BINARY
, "type mismatch");
5106 torture_assert_int_equal(tctx
, blob_out
.length
, blob_in
.length
, "size mismatch");
5107 torture_assert_mem_equal(tctx
, blob_out
.data
, blob_in
.data
, blob_in
.length
, "buffer mismatch");
5109 torture_assert_int_equal(tctx
, ecount
, 1, "unexpected enum count");
5110 torture_assert_str_equal(tctx
, einfo
[0].value_name
, values
[i
], "value_name mismatch");
5111 torture_assert_int_equal(tctx
, einfo
[0].value_name_len
, strlen_m_term(values
[i
])*2, "unexpected value_name_len");
5112 torture_assert_int_equal(tctx
, einfo
[0].type
, REG_BINARY
, "type mismatch");
5113 torture_assert_int_equal(tctx
, einfo
[0].data_length
, blob_in
.length
, "size mismatch");
5114 if (einfo
[0].data_length
> 0) {
5115 torture_assert_mem_equal(tctx
, einfo
[0].data
->data
, blob_in
.data
, blob_in
.length
, "buffer mismatch");
5118 torture_assert(tctx
,
5119 test_DeletePrinterDataEx(tctx
, b
, handle
, key
, values
[i
]),
5120 "failed to call DeletePrinterDataEx");
5127 static bool test_SetPrinterDataEx_matrix(struct torture_context
*tctx
,
5128 struct dcerpc_pipe
*p
,
5129 struct policy_handle
*handle
,
5130 const char *printername
,
5131 struct dcerpc_binding_handle
*winreg_handle
,
5132 struct policy_handle
*hive_handle
)
5134 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5135 const char *value_name
= "dog";
5136 const char *key_name
= "torturedataex";
5137 enum winreg_Type types
[] = {
5143 const char *str
= "abcdefghi";
5146 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
5147 for (s
=0; s
< strlen(str
); s
++) {
5149 enum winreg_Type type
;
5150 const char *string
= talloc_strndup(tctx
, str
, s
);
5151 const char *array
[2];
5152 DATA_BLOB blob
= data_blob_string_const(string
);
5155 uint32_t needed
, offered
= 0;
5157 struct spoolss_PrinterEnumValues
*einfo
;
5159 array
[0] = talloc_strdup(tctx
, string
);
5162 if (types
[t
] == REG_DWORD
) {
5169 offered
= blob
.length
;
5172 data
= data_blob_talloc(tctx
, NULL
, 4);
5173 SIVAL(data
.data
, 0, 0x12345678);
5177 torture_assert(tctx
, push_reg_sz(tctx
, &data
, string
), "");
5179 offered
= data
.length
;
5180 /*strlen_m_term(data.string)*2;*/
5183 torture_assert(tctx
, push_reg_multi_sz(tctx
, &data
, array
), "");
5184 type
= REG_MULTI_SZ
;
5185 offered
= data
.length
;
5188 torture_fail(tctx
, talloc_asprintf(tctx
, "type %d untested\n", types
[t
]));
5191 torture_assert(tctx
,
5192 test_SetPrinterDataEx(tctx
, b
, handle
, key_name
, value_name
, types
[t
], data
.data
, offered
),
5193 "failed to call SetPrinterDataEx");
5195 torture_assert(tctx
,
5196 test_GetPrinterDataEx_checktype(tctx
, p
, handle
, key_name
, value_name
, &types
[t
], &type
, &data_out
, &needed
),
5197 "failed to call GetPrinterDataEx");
5199 torture_assert(tctx
,
5200 test_EnumPrinterDataEx(tctx
, b
, handle
, key_name
, &ecount
, &einfo
),
5201 "failed to call EnumPrinterDataEx");
5203 torture_assert_int_equal(tctx
, types
[t
], type
, "type mismatch");
5204 torture_assert_int_equal(tctx
, needed
, offered
, "size mismatch");
5205 torture_assert_mem_equal(tctx
, data_out
, data
.data
, offered
, "buffer mismatch");
5207 torture_assert_int_equal(tctx
, ecount
, 1, "unexpected enum count");
5208 torture_assert_str_equal(tctx
, einfo
[0].value_name
, value_name
, "value_name mismatch");
5209 torture_assert_int_equal(tctx
, einfo
[0].value_name_len
, strlen_m_term(value_name
)*2, "unexpected value_name_len");
5210 torture_assert_int_equal(tctx
, einfo
[0].type
, types
[t
], "type mismatch");
5211 torture_assert_int_equal(tctx
, einfo
[0].data_length
, offered
, "size mismatch");
5212 if (einfo
[0].data_length
> 0) {
5213 torture_assert_mem_equal(tctx
, einfo
[0].data
->data
, data
.data
, offered
, "buffer mismatch");
5216 if (winreg_handle
&& hive_handle
) {
5217 enum winreg_Type w_type
;
5222 torture_assert(tctx
,
5223 test_winreg_query_printerdata(tctx
, winreg_handle
, hive_handle
,
5224 printername
, key_name
, value_name
,
5225 &w_type
, &w_size
, &w_length
, &w_data
), "");
5227 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
5228 torture_assert_int_equal(tctx
, w_size
, offered
, "winreg size mismatch");
5229 torture_assert_int_equal(tctx
, w_length
, offered
, "winreg length mismatch");
5230 torture_assert_mem_equal(tctx
, w_data
, data
.data
, offered
, "winreg buffer mismatch");
5233 torture_assert(tctx
,
5234 test_DeletePrinterDataEx(tctx
, b
, handle
, key_name
, value_name
),
5235 "failed to call DeletePrinterDataEx");
5242 static bool test_PrinterData_winreg(struct torture_context
*tctx
,
5243 struct dcerpc_pipe
*p
,
5244 struct policy_handle
*handle
,
5245 const char *printer_name
)
5247 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5248 struct dcerpc_pipe
*p2
;
5250 struct policy_handle hive_handle
;
5251 struct dcerpc_binding_handle
*b2
;
5253 torture_assert_ntstatus_ok(tctx
,
5254 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
5255 "could not open winreg pipe");
5256 b2
= p2
->binding_handle
;
5258 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
5260 ret
&= test_SetPrinterData_matrix(tctx
, b
, handle
, printer_name
, b2
, &hive_handle
);
5261 ret
&= test_SetPrinterDataEx_matrix(tctx
, p
, handle
, printer_name
, b2
, &hive_handle
);
5263 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
5270 static bool test_Forms_winreg(struct torture_context
*tctx
,
5271 struct dcerpc_binding_handle
*b
,
5272 struct policy_handle
*handle
,
5274 const char *printer_name
)
5276 struct dcerpc_pipe
*p2
;
5278 struct policy_handle hive_handle
;
5279 struct dcerpc_binding_handle
*b2
;
5281 torture_assert_ntstatus_ok(tctx
,
5282 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
5283 "could not open winreg pipe");
5284 b2
= p2
->binding_handle
;
5286 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
5288 ret
= test_Forms(tctx
, b
, handle
, print_server
, printer_name
, b2
, &hive_handle
);
5290 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
5297 static bool test_PrinterInfo_winreg(struct torture_context
*tctx
,
5298 struct dcerpc_pipe
*p
,
5299 struct policy_handle
*handle
,
5300 const char *printer_name
)
5302 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5303 struct dcerpc_pipe
*p2
;
5305 struct policy_handle hive_handle
;
5306 struct dcerpc_binding_handle
*b2
;
5308 torture_assert_ntstatus_ok(tctx
,
5309 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
5310 "could not open winreg pipe");
5311 b2
= p2
->binding_handle
;
5313 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
5315 ret
= test_GetPrinterInfo_winreg(tctx
, b
, handle
, printer_name
, b2
, &hive_handle
);
5317 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
5324 static bool test_DriverInfo_winreg(struct torture_context
*tctx
,
5325 struct dcerpc_pipe
*p
,
5326 struct policy_handle
*handle
,
5327 const char *printer_name
,
5328 const char *driver_name
,
5329 const char *environment
,
5330 enum spoolss_DriverOSVersion version
)
5332 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5333 struct dcerpc_pipe
*p2
;
5335 struct policy_handle hive_handle
;
5336 struct dcerpc_binding_handle
*b2
;
5338 torture_assert_ntstatus_ok(tctx
,
5339 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
5340 "could not open winreg pipe");
5341 b2
= p2
->binding_handle
;
5343 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
5345 ret
= test_GetDriverInfo_winreg(tctx
, b
, handle
, printer_name
, driver_name
, environment
, version
, b2
, &hive_handle
, NULL
);
5347 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
5354 static bool test_PrintProcessors_winreg(struct torture_context
*tctx
,
5355 struct dcerpc_binding_handle
*b
,
5356 const char *environment
)
5358 struct dcerpc_pipe
*p2
;
5360 struct policy_handle hive_handle
;
5361 struct dcerpc_binding_handle
*b2
;
5363 torture_assert_ntstatus_ok(tctx
,
5364 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
5365 "could not open winreg pipe");
5366 b2
= p2
->binding_handle
;
5368 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
5370 ret
= test_PrintProcessors(tctx
, b
, environment
, b2
, &hive_handle
);
5372 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
5379 static bool test_PrinterData_DsSpooler(struct torture_context
*tctx
,
5380 struct dcerpc_pipe
*p
,
5381 struct policy_handle
*handle
,
5382 const char *printer_name
)
5384 struct spoolss_SetPrinterInfoCtr info_ctr
;
5385 struct spoolss_DevmodeContainer devmode_ctr
;
5386 struct sec_desc_buf secdesc_ctr
;
5387 union spoolss_SetPrinterInfo sinfo
;
5388 union spoolss_PrinterInfo info
;
5389 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5392 ZERO_STRUCT(info_ctr
);
5393 ZERO_STRUCT(devmode_ctr
);
5394 ZERO_STRUCT(secdesc_ctr
);
5396 torture_comment(tctx
, "Testing DsSpooler <-> SetPrinter relations\n");
5398 torture_assert(tctx
,
5399 test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
5400 "failed to query Printer level 2");
5402 torture_assert(tctx
,
5403 PrinterInfo_to_SetPrinterInfo(tctx
, &info
, 2, &sinfo
),
5404 "failed to convert");
5407 info_ctr
.info
= sinfo
;
5409 #define TEST_SZ(wname, iname) \
5411 enum winreg_Type type;\
5416 torture_assert(tctx,\
5417 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5418 "failed to query");\
5419 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5420 blob = data_blob_const(data, needed);\
5421 torture_assert(tctx,\
5422 pull_reg_sz(tctx, &blob, &str),\
5423 "failed to pull REG_SZ");\
5424 torture_assert_str_equal(tctx, str, iname, "unexpected result");\
5428 #define TEST_SET_SZ(wname, iname, val) \
5430 enum winreg_Type type;\
5435 sinfo.info2->iname = val;\
5436 torture_assert(tctx,\
5437 test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5438 "failed to call SetPrinter");\
5439 torture_assert(tctx,\
5440 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5441 "failed to query");\
5442 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5443 blob = data_blob_const(data, needed);\
5444 torture_assert(tctx,\
5445 pull_reg_sz(tctx, &blob, &str),\
5446 "failed to pull REG_SZ");\
5447 torture_assert_str_equal(tctx, str, val, "unexpected result");\
5450 #define TEST_SET_DWORD(wname, iname, val) \
5452 enum winreg_Type type;\
5456 sinfo.info2->iname = val;\
5457 torture_assert(tctx,\
5458 test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5459 "failed to call SetPrinter");\
5460 torture_assert(tctx,\
5461 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5462 "failed to query");\
5463 torture_assert_int_equal(tctx, type, REG_DWORD, "unexpected type");\
5464 torture_assert_int_equal(tctx, needed, 4, "unexpected length");\
5465 value = IVAL(data, 0); \
5466 torture_assert_int_equal(tctx, value, val, "unexpected result");\
5469 TEST_SET_SZ("description", comment
, "newval");
5470 TEST_SET_SZ("location", location
, "newval");
5471 /* TEST_SET_DWORD("priority", priority, 25); */
5473 torture_assert(tctx
,
5474 test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
5475 "failed to query Printer level 2");
5477 TEST_SZ("description", info
.info2
.comment
);
5478 TEST_SZ("driverName", info
.info2
.drivername
);
5479 TEST_SZ("location", info
.info2
.location
);
5481 pname
= strrchr(info
.info2
.printername
, '\\');
5482 if (pname
== NULL
) {
5483 pname
= info
.info2
.printername
;
5487 TEST_SZ("printerName", pname
);
5488 /* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
5489 /* TEST_SZ("printShareName", info.info2.sharename); */
5491 /* FIXME gd: complete the list */
5497 torture_comment(tctx
, "DsSpooler <-> SetPrinter relations test succeeded\n\n");
5502 static bool test_print_processors_winreg(struct torture_context
*tctx
,
5505 struct test_spoolss_context
*ctx
=
5506 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
5507 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
5508 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5510 return test_PrintProcessors_winreg(tctx
, b
, ctx
->environment
);
5513 static bool test_GetChangeID_PrinterData(struct torture_context
*tctx
,
5514 struct dcerpc_binding_handle
*b
,
5515 struct policy_handle
*handle
,
5516 uint32_t *change_id
)
5518 enum winreg_Type type
;
5522 torture_assert(tctx
,
5523 test_GetPrinterData(tctx
, b
, handle
, "ChangeID", &type
, &data
, &needed
),
5524 "failed to call GetPrinterData");
5526 torture_assert(tctx
, type
== REG_DWORD
, "unexpected type");
5527 torture_assert_int_equal(tctx
, needed
, 4, "unexpected size");
5529 *change_id
= IVAL(data
, 0);
5534 static bool test_GetChangeID_PrinterDataEx(struct torture_context
*tctx
,
5535 struct dcerpc_pipe
*p
,
5536 struct policy_handle
*handle
,
5537 uint32_t *change_id
)
5539 enum winreg_Type type
;
5543 torture_assert(tctx
,
5544 test_GetPrinterDataEx(tctx
, p
, handle
, "PrinterDriverData", "ChangeID", &type
, &data
, &needed
),
5545 "failed to call GetPrinterData");
5547 torture_assert(tctx
, type
== REG_DWORD
, "unexpected type");
5548 torture_assert_int_equal(tctx
, needed
, 4, "unexpected size");
5550 *change_id
= IVAL(data
, 0);
5555 static bool test_GetChangeID_PrinterInfo(struct torture_context
*tctx
,
5556 struct dcerpc_binding_handle
*b
,
5557 struct policy_handle
*handle
,
5558 uint32_t *change_id
)
5560 union spoolss_PrinterInfo info
;
5562 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 0, &info
),
5563 "failed to query Printer level 0");
5565 *change_id
= info
.info0
.change_id
;
5570 static bool test_ChangeID(struct torture_context
*tctx
,
5571 struct dcerpc_pipe
*p
,
5572 struct policy_handle
*handle
)
5574 uint32_t change_id
, change_id_ex
, change_id_info
;
5575 uint32_t change_id2
, change_id_ex2
, change_id_info2
;
5576 union spoolss_PrinterInfo info
;
5577 const char *comment
;
5578 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5580 torture_comment(tctx
, "Testing ChangeID: id change test #1\n");
5582 torture_assert(tctx
, test_GetChangeID_PrinterData(tctx
, b
, handle
, &change_id
),
5583 "failed to query for ChangeID");
5584 torture_assert(tctx
, test_GetChangeID_PrinterDataEx(tctx
, p
, handle
, &change_id_ex
),
5585 "failed to query for ChangeID");
5586 torture_assert(tctx
, test_GetChangeID_PrinterInfo(tctx
, b
, handle
, &change_id_info
),
5587 "failed to query for ChangeID");
5589 torture_assert_int_equal(tctx
, change_id
, change_id_ex
,
5590 "change_ids should all be equal");
5591 torture_assert_int_equal(tctx
, change_id_ex
, change_id_info
,
5592 "change_ids should all be equal");
5595 torture_comment(tctx
, "Testing ChangeID: id change test #2\n");
5597 torture_assert(tctx
, test_GetChangeID_PrinterData(tctx
, b
, handle
, &change_id
),
5598 "failed to query for ChangeID");
5599 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
5600 "failed to query Printer level 2");
5601 torture_assert(tctx
, test_GetChangeID_PrinterDataEx(tctx
, p
, handle
, &change_id_ex
),
5602 "failed to query for ChangeID");
5603 torture_assert(tctx
, test_GetChangeID_PrinterInfo(tctx
, b
, handle
, &change_id_info
),
5604 "failed to query for ChangeID");
5605 torture_assert_int_equal(tctx
, change_id
, change_id_ex
,
5606 "change_id should not have changed");
5607 torture_assert_int_equal(tctx
, change_id_ex
, change_id_info
,
5608 "change_id should not have changed");
5611 torture_comment(tctx
, "Testing ChangeID: id change test #3\n");
5613 torture_assert(tctx
, test_GetChangeID_PrinterData(tctx
, b
, handle
, &change_id
),
5614 "failed to query for ChangeID");
5615 torture_assert(tctx
, test_GetChangeID_PrinterDataEx(tctx
, p
, handle
, &change_id_ex
),
5616 "failed to query for ChangeID");
5617 torture_assert(tctx
, test_GetChangeID_PrinterInfo(tctx
, b
, handle
, &change_id_info
),
5618 "failed to query for ChangeID");
5619 torture_assert(tctx
, test_GetPrinter_level(tctx
, b
, handle
, 2, &info
),
5620 "failed to query Printer level 2");
5621 comment
= talloc_strdup(tctx
, info
.info2
.comment
);
5624 struct spoolss_SetPrinterInfoCtr info_ctr
;
5625 struct spoolss_DevmodeContainer devmode_ctr
;
5626 struct sec_desc_buf secdesc_ctr
;
5627 union spoolss_SetPrinterInfo sinfo
;
5629 ZERO_STRUCT(info_ctr
);
5630 ZERO_STRUCT(devmode_ctr
);
5631 ZERO_STRUCT(secdesc_ctr
);
5634 torture_assert(tctx
, PrinterInfo_to_SetPrinterInfo(tctx
, &info
, 2, &sinfo
), "");
5635 sinfo
.info2
->comment
= "torture_comment";
5638 info_ctr
.info
= sinfo
;
5640 torture_assert(tctx
, test_SetPrinter(tctx
, b
, handle
, &info_ctr
, &devmode_ctr
, &secdesc_ctr
, 0),
5641 "failed to call SetPrinter");
5643 sinfo
.info2
->comment
= comment
;
5645 torture_assert(tctx
, test_SetPrinter(tctx
, b
, handle
, &info_ctr
, &devmode_ctr
, &secdesc_ctr
, 0),
5646 "failed to call SetPrinter");
5650 torture_assert(tctx
, test_GetChangeID_PrinterData(tctx
, b
, handle
, &change_id2
),
5651 "failed to query for ChangeID");
5652 torture_assert(tctx
, test_GetChangeID_PrinterDataEx(tctx
, p
, handle
, &change_id_ex2
),
5653 "failed to query for ChangeID");
5654 torture_assert(tctx
, test_GetChangeID_PrinterInfo(tctx
, b
, handle
, &change_id_info2
),
5655 "failed to query for ChangeID");
5657 torture_assert_int_equal(tctx
, change_id2
, change_id_ex2
,
5658 "change_ids should all be equal");
5659 torture_assert_int_equal(tctx
, change_id_ex2
, change_id_info2
,
5660 "change_ids should all be equal");
5662 torture_assert(tctx
, (change_id
< change_id2
),
5663 talloc_asprintf(tctx
, "change_id %d needs to be larger than change_id %d",
5664 change_id2
, change_id
));
5665 torture_assert(tctx
, (change_id_ex
< change_id_ex2
),
5666 talloc_asprintf(tctx
, "change_id %d needs to be larger than change_id %d",
5667 change_id_ex2
, change_id_ex
));
5668 torture_assert(tctx
, (change_id_info
< change_id_info2
),
5669 talloc_asprintf(tctx
, "change_id %d needs to be larger than change_id %d",
5670 change_id_info2
, change_id_info
));
5672 torture_comment(tctx
, "ChangeID tests succeeded\n\n");
5677 static bool test_SecondaryClosePrinter(struct torture_context
*tctx
,
5678 struct dcerpc_pipe
*p
,
5679 struct policy_handle
*handle
)
5682 struct dcerpc_binding
*b
;
5683 struct dcerpc_pipe
*p2
;
5684 struct spoolss_ClosePrinter cp
;
5686 /* only makes sense on SMB */
5687 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
5691 torture_comment(tctx
, "Testing close on secondary pipe\n");
5693 status
= dcerpc_parse_binding(tctx
, p
->conn
->binding_string
, &b
);
5694 torture_assert_ntstatus_ok(tctx
, status
, "Failed to parse dcerpc binding");
5696 status
= dcerpc_secondary_connection(p
, &p2
, b
);
5697 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
5699 status
= dcerpc_bind_auth_none(p2
, &ndr_table_spoolss
);
5700 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create bind on secondary connection");
5702 cp
.in
.handle
= handle
;
5703 cp
.out
.handle
= handle
;
5705 status
= dcerpc_spoolss_ClosePrinter_r(p2
->binding_handle
, tctx
, &cp
);
5706 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_RPC_SS_CONTEXT_MISMATCH
,
5707 "ERROR: Allowed close on secondary connection");
5714 static bool test_OpenPrinter_badname(struct torture_context
*tctx
,
5715 struct dcerpc_binding_handle
*b
, const char *name
)
5718 struct spoolss_OpenPrinter op
;
5719 struct spoolss_OpenPrinterEx opEx
;
5720 struct policy_handle handle
;
5723 op
.in
.printername
= name
;
5724 op
.in
.datatype
= NULL
;
5725 op
.in
.devmode_ctr
.devmode
= NULL
;
5726 op
.in
.access_mask
= 0;
5727 op
.out
.handle
= &handle
;
5729 torture_comment(tctx
, "Testing OpenPrinter(%s) with bad name\n", op
.in
.printername
);
5731 status
= dcerpc_spoolss_OpenPrinter_r(b
, tctx
, &op
);
5732 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
5733 torture_assert_werr_equal(tctx
, op
.out
.result
, WERR_INVALID_PRINTER_NAME
,
5734 "unexpected result");
5736 if (W_ERROR_IS_OK(op
.out
.result
)) {
5737 ret
&=test_ClosePrinter(tctx
, b
, &handle
);
5740 opEx
.in
.printername
= name
;
5741 opEx
.in
.datatype
= NULL
;
5742 opEx
.in
.devmode_ctr
.devmode
= NULL
;
5743 opEx
.in
.access_mask
= 0;
5745 opEx
.in
.userlevel
.level1
= NULL
;
5746 opEx
.out
.handle
= &handle
;
5748 torture_comment(tctx
, "Testing OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
5750 status
= dcerpc_spoolss_OpenPrinterEx_r(b
, tctx
, &opEx
);
5751 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinterEx failed");
5752 torture_assert_werr_equal(tctx
, opEx
.out
.result
, WERR_INVALID_PARAM
,
5753 "unexpected result");
5755 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
5756 ret
&=test_ClosePrinter(tctx
, b
, &handle
);
5762 static bool test_OpenPrinter_badname_list(struct torture_context
*tctx
,
5765 struct test_spoolss_context
*ctx
=
5766 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
5768 const char *badnames
[] = {
5769 "__INVALID_PRINTER__",
5770 "\\\\__INVALID_HOST__",
5773 "\\\\\\__INVALID_PRINTER__"
5775 const char *badname
;
5776 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
5777 const char *server_name
= dcerpc_server_name(p
);
5778 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5781 for (i
=0; i
< ARRAY_SIZE(badnames
); i
++) {
5782 torture_assert(tctx
,
5783 test_OpenPrinter_badname(tctx
, b
, badnames
[i
]),
5787 badname
= talloc_asprintf(tctx
, "\\\\%s\\", server_name
);
5788 torture_assert(tctx
,
5789 test_OpenPrinter_badname(tctx
, b
, badname
),
5792 badname
= talloc_asprintf(tctx
, "\\\\%s\\__INVALID_PRINTER__", server_name
);
5793 torture_assert(tctx
,
5794 test_OpenPrinter_badname(tctx
, b
, badname
),
5800 static bool test_OpenPrinter(struct torture_context
*tctx
,
5801 struct dcerpc_pipe
*p
,
5803 const char *environment
,
5807 struct spoolss_OpenPrinter r
;
5808 struct policy_handle handle
;
5810 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5812 r
.in
.printername
= name
;
5813 r
.in
.datatype
= NULL
;
5814 r
.in
.devmode_ctr
.devmode
= NULL
;
5815 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5816 r
.out
.handle
= &handle
;
5818 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", r
.in
.printername
);
5820 status
= dcerpc_spoolss_OpenPrinter_r(b
, tctx
, &r
);
5822 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
5824 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenPrinter failed");
5830 if (!test_GetPrinter(tctx
, b
, &handle
, environment
)) {
5834 if (!torture_setting_bool(tctx
, "samba3", false)) {
5835 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
5841 if (!test_ClosePrinter(tctx
, b
, &handle
)) {
5848 static bool test_OpenPrinterEx(struct torture_context
*tctx
,
5849 struct dcerpc_binding_handle
*b
,
5850 const char *printername
,
5851 const char *datatype
,
5852 struct spoolss_DeviceMode
*devmode
,
5853 uint32_t access_mask
,
5855 union spoolss_UserLevel
*userlevel
,
5856 struct policy_handle
*handle
,
5857 WERROR expected_result
)
5859 struct spoolss_OpenPrinterEx r
;
5861 r
.in
.printername
= printername
;
5862 r
.in
.datatype
= datatype
;
5863 r
.in
.devmode_ctr
.devmode
= devmode
;
5864 r
.in
.access_mask
= access_mask
;
5866 r
.in
.userlevel
= *userlevel
;
5867 r
.out
.handle
= handle
;
5869 torture_comment(tctx
, "Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
5871 torture_assert_ntstatus_ok(tctx
,
5872 dcerpc_spoolss_OpenPrinterEx_r(b
, tctx
, &r
),
5873 "OpenPrinterEx failed");
5875 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
5876 "OpenPrinterEx failed");
5881 static bool call_OpenPrinterEx(struct torture_context
*tctx
,
5882 struct dcerpc_pipe
*p
,
5884 struct spoolss_DeviceMode
*devmode
,
5885 struct policy_handle
*handle
)
5887 union spoolss_UserLevel userlevel
;
5888 struct spoolss_UserLevel1 userlevel1
;
5889 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5891 userlevel1
.size
= 1234;
5892 userlevel1
.client
= "hello";
5893 userlevel1
.user
= "spottyfoot!";
5894 userlevel1
.build
= 1;
5895 userlevel1
.major
= 2;
5896 userlevel1
.minor
= 3;
5897 userlevel1
.processor
= 4;
5899 userlevel
.level1
= &userlevel1
;
5901 return test_OpenPrinterEx(tctx
, b
, name
, NULL
, devmode
,
5902 SEC_FLAG_MAXIMUM_ALLOWED
,
5909 static bool test_printer_rename(struct torture_context
*tctx
,
5912 struct torture_printer_context
*t
=
5913 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
5914 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
5917 union spoolss_PrinterInfo info
;
5918 union spoolss_SetPrinterInfo sinfo
;
5919 struct spoolss_SetPrinterInfoCtr info_ctr
;
5920 struct spoolss_DevmodeContainer devmode_ctr
;
5921 struct sec_desc_buf secdesc_ctr
;
5922 const char *printer_name
;
5923 const char *printer_name_orig
;
5924 const char *printer_name_new
= "SAMBA smbtorture Test Printer (Copy 2)";
5925 struct policy_handle new_handle
;
5927 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5929 ZERO_STRUCT(devmode_ctr
);
5930 ZERO_STRUCT(secdesc_ctr
);
5932 torture_comment(tctx
, "Testing Printer rename operations\n");
5934 torture_assert(tctx
,
5935 test_GetPrinter_level(tctx
, b
, &t
->handle
, 2, &info
),
5936 "failed to call GetPrinter level 2");
5938 printer_name_orig
= talloc_strdup(tctx
, info
.info2
.printername
);
5940 q
= strrchr(info
.info2
.printername
, '\\');
5942 torture_warning(tctx
,
5943 "server returns printername %s incl. servername although we did not set servername", info
.info2
.printername
);
5946 torture_assert(tctx
,
5947 PrinterInfo_to_SetPrinterInfo(tctx
, &info
, 2, &sinfo
), "");
5949 sinfo
.info2
->printername
= printer_name_new
;
5952 info_ctr
.info
= sinfo
;
5954 torture_assert(tctx
,
5955 test_SetPrinter(tctx
, b
, &t
->handle
, &info_ctr
, &devmode_ctr
, &secdesc_ctr
, 0),
5956 "failed to call SetPrinter level 2");
5958 torture_assert(tctx
,
5959 test_GetPrinter_level(tctx
, b
, &t
->handle
, 2, &info
),
5960 "failed to call GetPrinter level 2");
5962 printer_name
= talloc_strdup(tctx
, info
.info2
.printername
);
5964 q
= strrchr(info
.info2
.printername
, '\\');
5966 torture_warning(tctx
,
5967 "server returns printername %s incl. servername although we did not set servername", info
.info2
.printername
);
5972 torture_assert_str_equal(tctx
, printer_name
, printer_name_new
,
5973 "new printer name was not set");
5975 /* samba currently cannot fully rename printers */
5976 if (!torture_setting_bool(tctx
, "samba3", false)) {
5977 torture_assert(tctx
,
5978 test_OpenPrinter_badname(tctx
, b
, printer_name_orig
),
5979 "still can open printer with oldname after rename");
5981 torture_warning(tctx
, "*not* checking for open with oldname after rename for samba3");
5984 torture_assert(tctx
,
5985 call_OpenPrinterEx(tctx
, p
, printer_name_new
, NULL
, &new_handle
),
5986 "failed to open printer with new name");
5988 torture_assert(tctx
,
5989 test_GetPrinter_level(tctx
, b
, &new_handle
, 2, &info
),
5990 "failed to call GetPrinter level 2");
5992 torture_assert_str_equal(tctx
, info
.info2
.printername
, printer_name_new
,
5993 "new printer name was not set");
5995 torture_assert(tctx
,
5996 test_ClosePrinter(tctx
, b
, &new_handle
),
5997 "failed to close printer");
5999 torture_comment(tctx
, "Printer rename operations test succeeded\n\n");
6004 static bool test_openprinter(struct torture_context
*tctx
,
6005 struct dcerpc_binding_handle
*b
,
6006 const char *real_printername
)
6008 union spoolss_UserLevel userlevel
;
6009 struct policy_handle handle
;
6010 struct spoolss_UserLevel1 userlevel1
;
6011 const char *printername
= NULL
;
6016 WERROR expected_result
;
6019 .suffix
= "rubbish",
6020 .expected_result
= WERR_INVALID_PRINTER_NAME
6022 .suffix
= ", LocalOnl",
6023 .expected_result
= WERR_INVALID_PRINTER_NAME
6025 .suffix
= ", localOnly",
6026 .expected_result
= WERR_INVALID_PRINTER_NAME
6028 .suffix
= ", localonl",
6029 .expected_result
= WERR_INVALID_PRINTER_NAME
6031 .suffix
= ",LocalOnl",
6032 .expected_result
= WERR_INVALID_PRINTER_NAME
6034 .suffix
= ",localOnl2",
6035 .expected_result
= WERR_INVALID_PRINTER_NAME
6037 .suffix
= ", DrvConver2t",
6038 .expected_result
= WERR_INVALID_PRINTER_NAME
6040 .suffix
= ", drvconvert",
6041 .expected_result
= WERR_INVALID_PRINTER_NAME
6043 .suffix
= ",drvconvert",
6044 .expected_result
= WERR_INVALID_PRINTER_NAME
6046 .suffix
= ", DrvConvert",
6047 .expected_result
= WERR_OK
6049 .suffix
= " , DrvConvert",
6050 .expected_result
= WERR_INVALID_PRINTER_NAME
6052 .suffix
= ",DrvConvert",
6053 .expected_result
= WERR_OK
6055 .suffix
= ", DrvConvertsadfasdf",
6056 .expected_result
= WERR_OK
6058 .suffix
= ",DrvConvertasdfasd",
6059 .expected_result
= WERR_OK
6061 .suffix
= ", LocalOnly",
6062 .expected_result
= WERR_OK
6064 .suffix
= " , LocalOnly",
6065 .expected_result
= WERR_INVALID_PRINTER_NAME
6067 .suffix
= ",LocalOnly",
6068 .expected_result
= WERR_OK
6070 .suffix
= ", LocalOnlysagi4gjfkd",
6071 .expected_result
= WERR_OK
6073 .suffix
= ",LocalOnlysagi4gjfkd",
6074 .expected_result
= WERR_OK
6078 userlevel1
.size
= 1234;
6079 userlevel1
.client
= "hello";
6080 userlevel1
.user
= "spottyfoot!";
6081 userlevel1
.build
= 1;
6082 userlevel1
.major
= 2;
6083 userlevel1
.minor
= 3;
6084 userlevel1
.processor
= 4;
6086 userlevel
.level1
= &userlevel1
;
6088 torture_comment(tctx
, "Testing openprinterex printername pattern\n");
6090 torture_assert(tctx
,
6091 test_OpenPrinterEx(tctx
, b
, real_printername
, NULL
, NULL
, 0, 1,
6092 &userlevel
, &handle
,
6094 "OpenPrinterEx failed");
6095 test_ClosePrinter(tctx
, b
, &handle
);
6097 for (i
=0; i
< ARRAY_SIZE(tests
); i
++) {
6099 printername
= talloc_asprintf(tctx
, "%s%s",
6103 torture_assert(tctx
,
6104 test_OpenPrinterEx(tctx
, b
, printername
, NULL
, NULL
, 0, 1,
6105 &userlevel
, &handle
,
6106 tests
[i
].expected_result
),
6107 "OpenPrinterEx failed");
6108 if (W_ERROR_IS_OK(tests
[i
].expected_result
)) {
6109 test_ClosePrinter(tctx
, b
, &handle
);
6117 static bool test_existing_printer_openprinterex(struct torture_context
*tctx
,
6118 struct dcerpc_pipe
*p
,
6120 const char *environment
)
6122 struct policy_handle handle
;
6124 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6126 if (!test_openprinter(tctx
, b
, name
)) {
6130 if (!call_OpenPrinterEx(tctx
, p
, name
, NULL
, &handle
)) {
6134 if (!test_PrinterInfo_SD(tctx
, b
, &handle
)) {
6138 if (!test_GetPrinter(tctx
, b
, &handle
, environment
)) {
6142 if (!test_EnumForms_all(tctx
, b
, &handle
, false)) {
6146 if (!test_Forms(tctx
, b
, &handle
, false, name
, NULL
, NULL
)) {
6150 if (!test_Forms_winreg(tctx
, b
, &handle
, false, name
)) {
6154 if (!test_EnumPrinterData_all(tctx
, p
, &handle
)) {
6158 if (!test_EnumPrinterDataEx(tctx
, b
, &handle
, "PrinterDriverData", NULL
, NULL
)) {
6162 if (!test_EnumPrinterData_consistency(tctx
, p
, &handle
)) {
6166 if (!test_printer_all_keys(tctx
, b
, &handle
)) {
6170 if (!test_PausePrinter(tctx
, b
, &handle
)) {
6174 if (!test_DoPrintTest(tctx
, b
, &handle
)) {
6178 if (!test_ResumePrinter(tctx
, b
, &handle
)) {
6182 if (!test_SetPrinterData_matrix(tctx
, b
, &handle
, name
, NULL
, NULL
)) {
6186 if (!test_SetPrinterDataEx_matrix(tctx
, p
, &handle
, name
, NULL
, NULL
)) {
6190 if (!torture_setting_bool(tctx
, "samba3", false)) {
6191 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
6196 if (!test_ClosePrinter(tctx
, b
, &handle
)) {
6203 static bool test_EnumPrinters_old(struct torture_context
*tctx
,
6206 struct test_spoolss_context
*ctx
=
6207 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
6208 struct spoolss_EnumPrinters r
;
6210 uint16_t levels
[] = {1, 2, 4, 5};
6213 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
6214 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6216 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6217 union spoolss_PrinterInfo
*info
;
6222 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
6224 r
.in
.level
= levels
[i
];
6227 r
.out
.needed
= &needed
;
6228 r
.out
.count
= &count
;
6231 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
6233 status
= dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &r
);
6234 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
6236 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
6237 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
6238 r
.in
.buffer
= &blob
;
6239 r
.in
.offered
= needed
;
6240 status
= dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &r
);
6243 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
6245 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
6247 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters
, info
, r
.in
.level
, count
, needed
, 4);
6250 torture_comment(tctx
, "No printers returned\n");
6254 for (j
=0;j
<count
;j
++) {
6255 if (r
.in
.level
== 1) {
6256 char *unc
= talloc_strdup(tctx
, info
[j
].info1
.name
);
6257 char *slash
, *name
, *full_name
;
6259 if (unc
[0] == '\\' && unc
[1] == '\\') {
6262 slash
= strchr(unc
, '\\');
6267 full_name
= talloc_asprintf(tctx
, "\\\\%s\\%s",
6268 dcerpc_server_name(p
), name
);
6269 if (!test_OpenPrinter(tctx
, p
, name
, ctx
->environment
, true)) {
6272 if (!test_OpenPrinter(tctx
, p
, full_name
, ctx
->environment
, true)) {
6275 if (!test_OpenPrinter(tctx
, p
, name
, ctx
->environment
, false)) {
6278 if (!test_existing_printer_openprinterex(tctx
, p
, name
, ctx
->environment
)) {
6288 static bool test_EnumPrinters_level(struct torture_context
*tctx
,
6289 struct dcerpc_binding_handle
*b
,
6291 const char *servername
,
6294 union spoolss_PrinterInfo
**info_p
)
6296 struct spoolss_EnumPrinters r
;
6297 union spoolss_PrinterInfo
*info
;
6302 r
.in
.server
= servername
;
6306 r
.out
.needed
= &needed
;
6307 r
.out
.count
= &count
;
6310 torture_comment(tctx
, "Testing EnumPrinters(%s) level %u\n",
6311 r
.in
.server
, r
.in
.level
);
6313 torture_assert_ntstatus_ok(tctx
,
6314 dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &r
),
6315 "EnumPrinters failed");
6316 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
6317 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
6318 r
.in
.buffer
= &blob
;
6319 r
.in
.offered
= needed
;
6320 torture_assert_ntstatus_ok(tctx
,
6321 dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &r
),
6322 "EnumPrinters failed");
6325 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
6327 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters
, info
, r
.in
.level
, count
, needed
, 4);
6339 static const char *get_short_printername(struct torture_context
*tctx
,
6342 const char *short_name
;
6344 if (name
[0] == '\\' && name
[1] == '\\') {
6346 short_name
= strchr(name
, '\\');
6348 return talloc_strdup(tctx
, short_name
+1);
6355 static const char *get_full_printername(struct torture_context
*tctx
,
6358 const char *full_name
= talloc_strdup(tctx
, name
);
6361 if (name
&& name
[0] == '\\' && name
[1] == '\\') {
6363 p
= strchr(name
, '\\');
6372 static bool test_OnePrinter_servername(struct torture_context
*tctx
,
6373 struct dcerpc_pipe
*p
,
6374 struct dcerpc_binding_handle
*b
,
6375 const char *servername
,
6376 const char *printername
)
6378 union spoolss_PrinterInfo info
;
6379 const char *short_name
= get_short_printername(tctx
, printername
);
6380 const char *full_name
= get_full_printername(tctx
, printername
);
6383 struct policy_handle handle
;
6384 torture_assert(tctx
,
6385 call_OpenPrinterEx(tctx
, p
, short_name
, NULL
, &handle
),
6386 "failed to open printer");
6388 torture_assert(tctx
,
6389 test_GetPrinter_level(tctx
, b
, &handle
, 2, &info
),
6390 "failed to get printer info");
6392 torture_assert_casestr_equal(tctx
, info
.info2
.servername
, NULL
,
6393 "unexpected servername");
6394 torture_assert_casestr_equal(tctx
, info
.info2
.printername
, short_name
,
6395 "unexpected printername");
6397 if (info
.info2
.devmode
) {
6398 const char *expected_devicename
;
6399 expected_devicename
= talloc_strndup(tctx
, short_name
, MIN(strlen(short_name
), 31));
6400 torture_assert_casestr_equal(tctx
, info
.info2
.devmode
->devicename
, expected_devicename
,
6401 "unexpected devicemode devicename");
6404 torture_assert(tctx
,
6405 test_ClosePrinter(tctx
, b
, &handle
),
6406 "failed to close printer");
6410 struct policy_handle handle
;
6412 torture_assert(tctx
,
6413 call_OpenPrinterEx(tctx
, p
, full_name
, NULL
, &handle
),
6414 "failed to open printer");
6416 torture_assert(tctx
,
6417 test_GetPrinter_level(tctx
, b
, &handle
, 2, &info
),
6418 "failed to get printer info");
6420 torture_assert_casestr_equal(tctx
, info
.info2
.servername
, servername
,
6421 "unexpected servername");
6422 torture_assert_casestr_equal(tctx
, info
.info2
.printername
, full_name
,
6423 "unexpected printername");
6425 if (info
.info2
.devmode
) {
6426 const char *expected_devicename
;
6427 expected_devicename
= talloc_strndup(tctx
, full_name
, MIN(strlen(full_name
), 31));
6428 torture_assert_casestr_equal(tctx
, info
.info2
.devmode
->devicename
, expected_devicename
,
6429 "unexpected devicemode devicename");
6432 torture_assert(tctx
,
6433 test_ClosePrinter(tctx
, b
, &handle
),
6434 "failed to close printer");
6440 static bool test_EnumPrinters_servername(struct torture_context
*tctx
,
6443 struct test_spoolss_context
*ctx
=
6444 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
6446 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
6447 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6449 union spoolss_PrinterInfo
*info
;
6450 const char *servername
;
6451 uint32_t flags
= PRINTER_ENUM_NAME
|PRINTER_ENUM_LOCAL
;
6453 torture_comment(tctx
, "Testing servername behaviour in EnumPrinters and GetPrinters\n");
6455 servername
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
6457 torture_assert(tctx
,
6458 test_EnumPrinters_level(tctx
, b
, flags
, servername
, 2, &count
, &info
),
6459 "failed to enumerate printers");
6461 for (i
=0; i
< count
; i
++) {
6463 torture_assert_casestr_equal(tctx
, info
[i
].info2
.servername
, servername
,
6464 "unexpected servername");
6466 torture_assert(tctx
,
6467 test_OnePrinter_servername(tctx
, p
, b
, servername
, info
[i
].info2
.printername
),
6468 "failed to check printer");
6473 torture_assert(tctx
,
6474 test_EnumPrinters_level(tctx
, b
, flags
, servername
, 2, &count
, &info
),
6475 "failed to enumerate printers");
6477 for (i
=0; i
< count
; i
++) {
6479 torture_assert_casestr_equal(tctx
, info
[i
].info2
.servername
, NULL
,
6480 "unexpected servername");
6482 torture_assert(tctx
,
6483 test_OnePrinter_servername(tctx
, p
, b
, servername
, info
[i
].info2
.printername
),
6484 "failed to check printer");
6492 static bool test_GetPrinterDriver(struct torture_context
*tctx
,
6493 struct dcerpc_binding_handle
*b
,
6494 struct policy_handle
*handle
,
6495 const char *driver_name
)
6497 struct spoolss_GetPrinterDriver r
;
6500 r
.in
.handle
= handle
;
6501 r
.in
.architecture
= "W32X86";
6505 r
.out
.needed
= &needed
;
6507 torture_comment(tctx
, "Testing GetPrinterDriver level %d\n", r
.in
.level
);
6509 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_GetPrinterDriver_r(b
, tctx
, &r
),
6510 "failed to call GetPrinterDriver");
6511 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
6512 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
6513 r
.in
.buffer
= &blob
;
6514 r
.in
.offered
= needed
;
6515 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_GetPrinterDriver_r(b
, tctx
, &r
),
6516 "failed to call GetPrinterDriver");
6519 torture_assert_werr_ok(tctx
, r
.out
.result
,
6520 "failed to call GetPrinterDriver");
6522 CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo
, r
.out
.info
, r
.in
.level
, needed
, 4);
6527 static bool test_GetPrinterDriver2_level(struct torture_context
*tctx
,
6528 struct dcerpc_binding_handle
*b
,
6529 struct policy_handle
*handle
,
6530 const char *driver_name
,
6531 const char *architecture
,
6533 uint32_t client_major_version
,
6534 uint32_t client_minor_version
,
6535 union spoolss_DriverInfo
*info_p
,
6539 struct spoolss_GetPrinterDriver2 r
;
6541 uint32_t server_major_version
;
6542 uint32_t server_minor_version
;
6544 r
.in
.handle
= handle
;
6545 r
.in
.architecture
= architecture
;
6546 r
.in
.client_major_version
= client_major_version
;
6547 r
.in
.client_minor_version
= client_minor_version
;
6551 r
.out
.needed
= &needed
;
6552 r
.out
.server_major_version
= &server_major_version
;
6553 r
.out
.server_minor_version
= &server_minor_version
;
6555 torture_comment(tctx
, "Testing GetPrinterDriver2(%s) level %d\n",
6556 driver_name
, r
.in
.level
);
6558 torture_assert_ntstatus_ok(tctx
,
6559 dcerpc_spoolss_GetPrinterDriver2_r(b
, tctx
, &r
),
6560 "failed to call GetPrinterDriver2");
6561 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
6562 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
6563 r
.in
.buffer
= &blob
;
6564 r
.in
.offered
= needed
;
6565 torture_assert_ntstatus_ok(tctx
,
6566 dcerpc_spoolss_GetPrinterDriver2_r(b
, tctx
, &r
),
6567 "failed to call GetPrinterDriver2");
6571 *result_p
= r
.out
.result
;
6574 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_LEVEL
)) {
6575 switch (r
.in
.level
) {
6578 torture_comment(tctx
,
6579 "level %d not implemented, not considering as an error\n",
6587 torture_assert_werr_ok(tctx
, r
.out
.result
,
6588 "failed to call GetPrinterDriver2");
6590 CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo
, r
.out
.info
, r
.in
.level
, needed
, 4);
6593 *info_p
= *r
.out
.info
;
6599 static bool test_GetPrinterDriver2(struct torture_context
*tctx
,
6600 struct dcerpc_binding_handle
*b
,
6601 struct policy_handle
*handle
,
6602 const char *driver_name
,
6603 const char *architecture
)
6605 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 8, 101 };
6609 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6611 torture_assert(tctx
,
6612 test_GetPrinterDriver2_level(tctx
, b
, handle
, driver_name
, architecture
, levels
[i
], 3, 0, NULL
, NULL
),
6619 static bool test_EnumPrinterDrivers_old(struct torture_context
*tctx
,
6622 struct test_spoolss_context
*ctx
=
6623 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
6624 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
6626 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
6627 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6628 const char *server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
6630 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6633 union spoolss_DriverInfo
*info
;
6635 torture_assert(tctx
,
6636 test_EnumPrinterDrivers_args(tctx
, b
, server_name
, ctx
->environment
, levels
[i
], &count
, &info
),
6637 "failed to enumerate drivers");
6640 torture_comment(tctx
, "No printer drivers returned\n");
6648 static bool test_DeletePrinter(struct torture_context
*tctx
,
6649 struct dcerpc_binding_handle
*b
,
6650 struct policy_handle
*handle
)
6652 struct spoolss_DeletePrinter r
;
6654 torture_comment(tctx
, "Testing DeletePrinter\n");
6656 r
.in
.handle
= handle
;
6658 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_DeletePrinter_r(b
, tctx
, &r
),
6659 "failed to delete printer");
6660 torture_assert_werr_ok(tctx
, r
.out
.result
,
6661 "failed to delete printer");
6666 static bool test_EnumPrinters_findname(struct torture_context
*tctx
,
6667 struct dcerpc_binding_handle
*b
,
6673 struct spoolss_EnumPrinters e
;
6675 union spoolss_PrinterInfo
*info
;
6686 e
.out
.count
= &count
;
6688 e
.out
.needed
= &needed
;
6690 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &e
),
6691 "failed to enum printers");
6693 if (W_ERROR_EQUAL(e
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
6694 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
6695 e
.in
.buffer
= &blob
;
6696 e
.in
.offered
= needed
;
6698 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &e
),
6699 "failed to enum printers");
6702 torture_assert_werr_ok(tctx
, e
.out
.result
,
6703 "failed to enum printers");
6705 for (i
=0; i
< count
; i
++) {
6707 const char *current
= NULL
;
6712 current
= info
[i
].info1
.name
;
6716 if (strequal(current
, name
)) {
6721 q
= strrchr(current
, '\\');
6724 torture_warning(tctx
,
6725 "server returns printername %s incl. servername although we did not set servername", current
);
6728 if (strequal(q
, name
)) {
6738 static bool test_AddPrinter_wellknown(struct torture_context
*tctx
,
6739 struct dcerpc_pipe
*p
,
6740 const char *printername
,
6744 struct spoolss_AddPrinter r
;
6745 struct spoolss_AddPrinterEx rex
;
6746 struct spoolss_SetPrinterInfoCtr info_ctr
;
6747 struct spoolss_SetPrinterInfo1 info1
;
6748 struct spoolss_DevmodeContainer devmode_ctr
;
6749 struct sec_desc_buf secdesc_ctr
;
6750 struct spoolss_UserLevelCtr userlevel_ctr
;
6751 struct policy_handle handle
;
6753 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6755 ZERO_STRUCT(devmode_ctr
);
6756 ZERO_STRUCT(secdesc_ctr
);
6757 ZERO_STRUCT(userlevel_ctr
);
6760 torture_comment(tctx
, "Testing AddPrinter%s(%s) level 1\n",
6761 ex
? "Ex":"", printername
);
6763 /* try to add printer to wellknown printer list (level 1) */
6765 userlevel_ctr
.level
= 1;
6767 info_ctr
.info
.info1
= &info1
;
6770 rex
.in
.server
= NULL
;
6771 rex
.in
.info_ctr
= &info_ctr
;
6772 rex
.in
.devmode_ctr
= &devmode_ctr
;
6773 rex
.in
.secdesc_ctr
= &secdesc_ctr
;
6774 rex
.in
.userlevel_ctr
= &userlevel_ctr
;
6775 rex
.out
.handle
= &handle
;
6778 r
.in
.info_ctr
= &info_ctr
;
6779 r
.in
.devmode_ctr
= &devmode_ctr
;
6780 r
.in
.secdesc_ctr
= &secdesc_ctr
;
6781 r
.out
.handle
= &handle
;
6783 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6784 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6785 "failed to add printer");
6786 result
= ex
? rex
.out
.result
: r
.out
.result
;
6787 torture_assert_werr_equal(tctx
, result
, WERR_INVALID_PRINTER_NAME
,
6788 "unexpected result code");
6790 info1
.name
= printername
;
6791 info1
.flags
= PRINTER_ATTRIBUTE_SHARED
;
6793 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6794 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6795 "failed to add printer");
6796 result
= ex
? rex
.out
.result
: r
.out
.result
;
6797 torture_assert_werr_equal(tctx
, result
, WERR_PRINTER_ALREADY_EXISTS
,
6798 "unexpected result code");
6800 /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
6801 better do a real check to see the printer is really there */
6803 torture_assert(tctx
, test_EnumPrinters_findname(tctx
, b
,
6804 PRINTER_ENUM_NETWORK
, 1,
6807 "failed to enum printers");
6809 torture_assert(tctx
, found
, "failed to find newly added printer");
6813 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6814 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6815 "failed to add printer");
6816 result
= ex
? rex
.out
.result
: r
.out
.result
;
6817 torture_assert_werr_equal(tctx
, result
, WERR_PRINTER_ALREADY_EXISTS
,
6818 "unexpected result code");
6820 /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
6821 better do a real check to see the printer has really been removed
6822 from the well known printer list */
6826 torture_assert(tctx
, test_EnumPrinters_findname(tctx
, b
,
6827 PRINTER_ENUM_NETWORK
, 1,
6830 "failed to enum printers");
6832 torture_assert(tctx
, !found
, "printer still in well known printer list");
6837 static bool test_AddPrinter_normal(struct torture_context
*tctx
,
6838 struct dcerpc_pipe
*p
,
6839 struct policy_handle
*handle_p
,
6840 const char *printername
,
6841 const char *drivername
,
6842 const char *portname
,
6843 struct spoolss_DeviceMode
*devmode
,
6847 struct spoolss_AddPrinter r
;
6848 struct spoolss_AddPrinterEx rex
;
6849 struct spoolss_SetPrinterInfoCtr info_ctr
;
6850 struct spoolss_SetPrinterInfo2 info2
;
6851 struct spoolss_DevmodeContainer devmode_ctr
;
6852 struct sec_desc_buf secdesc_ctr
;
6853 struct spoolss_UserLevelCtr userlevel_ctr
;
6854 struct policy_handle handle
;
6856 bool existing_printer_deleted
= false;
6857 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6859 ZERO_STRUCT(devmode_ctr
);
6860 ZERO_STRUCT(secdesc_ctr
);
6861 ZERO_STRUCT(userlevel_ctr
);
6863 torture_comment(tctx
, "Testing AddPrinter%s(%s) level 2\n",
6864 ex
? "Ex":"", printername
);
6866 devmode_ctr
.devmode
= devmode
;
6868 userlevel_ctr
.level
= 1;
6870 rex
.in
.server
= NULL
;
6871 rex
.in
.info_ctr
= &info_ctr
;
6872 rex
.in
.devmode_ctr
= &devmode_ctr
;
6873 rex
.in
.secdesc_ctr
= &secdesc_ctr
;
6874 rex
.in
.userlevel_ctr
= &userlevel_ctr
;
6875 rex
.out
.handle
= &handle
;
6878 r
.in
.info_ctr
= &info_ctr
;
6879 r
.in
.devmode_ctr
= &devmode_ctr
;
6880 r
.in
.secdesc_ctr
= &secdesc_ctr
;
6881 r
.out
.handle
= &handle
;
6885 /* try to add printer to printer list (level 2) */
6889 info_ctr
.info
.info2
= &info2
;
6892 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6893 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6894 "failed to add printer");
6895 result
= ex
? rex
.out
.result
: r
.out
.result
;
6896 torture_assert_werr_equal(tctx
, result
, WERR_INVALID_PRINTER_NAME
,
6897 "unexpected result code");
6899 info2
.printername
= printername
;
6901 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6902 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6903 "failed to add printer");
6904 result
= ex
? rex
.out
.result
: r
.out
.result
;
6906 if (W_ERROR_EQUAL(result
, WERR_PRINTER_ALREADY_EXISTS
)) {
6907 struct policy_handle printer_handle
;
6909 if (existing_printer_deleted
) {
6910 torture_fail(tctx
, "already deleted printer still existing?");
6913 torture_assert(tctx
, call_OpenPrinterEx(tctx
, p
, printername
, NULL
, &printer_handle
),
6914 "failed to open printer handle");
6916 torture_assert(tctx
, test_DeletePrinter(tctx
, b
, &printer_handle
),
6917 "failed to delete printer");
6919 torture_assert(tctx
, test_ClosePrinter(tctx
, b
, &printer_handle
),
6920 "failed to close server handle");
6922 existing_printer_deleted
= true;
6927 torture_assert_werr_equal(tctx
, result
, WERR_UNKNOWN_PORT
,
6928 "unexpected result code");
6930 info2
.portname
= portname
;
6932 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6933 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6934 "failed to add printer");
6935 result
= ex
? rex
.out
.result
: r
.out
.result
;
6936 torture_assert_werr_equal(tctx
, result
, WERR_UNKNOWN_PRINTER_DRIVER
,
6937 "unexpected result code");
6939 info2
.drivername
= drivername
;
6941 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6942 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6943 "failed to add printer");
6944 result
= ex
? rex
.out
.result
: r
.out
.result
;
6946 /* w2k8r2 allows to add printer w/o defining printprocessor */
6948 if (!W_ERROR_IS_OK(result
)) {
6949 torture_assert_werr_equal(tctx
, result
, WERR_UNKNOWN_PRINTPROCESSOR
,
6950 "unexpected result code");
6952 info2
.printprocessor
= "winprint";
6954 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6955 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6956 "failed to add printer");
6957 result
= ex
? rex
.out
.result
: r
.out
.result
;
6958 torture_assert_werr_ok(tctx
, result
,
6959 "failed to add printer");
6964 /* we are paranoid, really check if the printer is there now */
6966 torture_assert(tctx
, test_EnumPrinters_findname(tctx
, b
,
6967 PRINTER_ENUM_LOCAL
, 1,
6970 "failed to enum printers");
6971 torture_assert(tctx
, found
, "failed to find newly added printer");
6973 torture_assert_ntstatus_ok(tctx
, ex
? dcerpc_spoolss_AddPrinterEx_r(b
, tctx
, &rex
) :
6974 dcerpc_spoolss_AddPrinter_r(b
, tctx
, &r
),
6975 "failed to add printer");
6976 result
= ex
? rex
.out
.result
: r
.out
.result
;
6977 torture_assert_werr_equal(tctx
, result
, WERR_PRINTER_ALREADY_EXISTS
,
6978 "unexpected result code");
6983 static bool test_printer_info(struct torture_context
*tctx
,
6986 struct torture_printer_context
*t
=
6987 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
6988 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
6989 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6993 if (torture_setting_bool(tctx
, "samba3", false)) {
6994 torture_skip(tctx
, "skipping printer info cross tests against samba 3");
6997 if (!test_PrinterInfo(tctx
, b
, &t
->handle
)) {
7001 if (!test_SetPrinter_errors(tctx
, b
, &t
->handle
)) {
7008 static bool test_EnumPrinterKey(struct torture_context
*tctx
,
7009 struct dcerpc_binding_handle
*b
,
7010 struct policy_handle
*handle
,
7011 const char *key_name
,
7012 const char ***array
)
7014 struct spoolss_EnumPrinterKey r
;
7015 uint32_t needed
= 0;
7016 union spoolss_KeyNames key_buffer
;
7017 int32_t offered
[] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, 256, 512, 1024, 2048 };
7021 r
.in
.handle
= handle
;
7022 r
.in
.key_name
= key_name
;
7023 r
.out
.key_buffer
= &key_buffer
;
7024 r
.out
.needed
= &needed
;
7025 r
.out
._ndr_size
= &_ndr_size
;
7027 for (i
=0; i
< ARRAY_SIZE(offered
); i
++) {
7029 if (offered
[i
] < 0 && needed
) {
7033 r
.in
.offered
= needed
+ offered
[i
];
7035 r
.in
.offered
= offered
[i
];
7038 ZERO_STRUCT(key_buffer
);
7040 torture_comment(tctx
, "Testing EnumPrinterKey(%s) with %d offered\n", r
.in
.key_name
, r
.in
.offered
);
7042 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinterKey_r(b
, tctx
, &r
),
7043 "failed to call EnumPrinterKey");
7044 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
7046 torture_assert(tctx
, (_ndr_size
== r
.in
.offered
/2),
7047 talloc_asprintf(tctx
, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7048 _ndr_size
, r
.in
.offered
/2));
7050 r
.in
.offered
= needed
;
7051 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinterKey_r(b
, tctx
, &r
),
7052 "failed to call EnumPrinterKey");
7055 if (offered
[i
] > 0) {
7056 torture_assert_werr_ok(tctx
, r
.out
.result
,
7057 "failed to call EnumPrinterKey");
7060 torture_assert(tctx
, (_ndr_size
== r
.in
.offered
/2),
7061 talloc_asprintf(tctx
, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7062 _ndr_size
, r
.in
.offered
/2));
7064 torture_assert(tctx
, (*r
.out
.needed
<= r
.in
.offered
),
7065 talloc_asprintf(tctx
, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r
.out
.needed
, r
.in
.offered
));
7067 torture_assert(tctx
, (*r
.out
.needed
<= _ndr_size
* 2),
7068 talloc_asprintf(tctx
, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r
.out
.needed
, _ndr_size
));
7070 if (key_buffer
.string_array
) {
7071 uint32_t calc_needed
= 0;
7073 for (s
=0; key_buffer
.string_array
[s
]; s
++) {
7074 calc_needed
+= strlen_m_term(key_buffer
.string_array
[s
])*2;
7076 if (!key_buffer
.string_array
[0]) {
7081 torture_assert_int_equal(tctx
, *r
.out
.needed
, calc_needed
,
7082 "EnumPrinterKey unexpected size");
7087 *array
= key_buffer
.string_array
;
7093 bool test_printer_all_keys(struct torture_context
*tctx
,
7094 struct dcerpc_binding_handle
*b
,
7095 struct policy_handle
*handle
)
7097 const char **key_array
= NULL
;
7100 torture_comment(tctx
, "Testing Printer Keys\n");
7102 torture_assert(tctx
, test_EnumPrinterKey(tctx
, b
, handle
, "", &key_array
),
7103 "failed to call test_EnumPrinterKey");
7105 for (i
=0; key_array
&& key_array
[i
]; i
++) {
7106 torture_assert(tctx
, test_EnumPrinterKey(tctx
, b
, handle
, key_array
[i
], NULL
),
7107 "failed to call test_EnumPrinterKey");
7109 for (i
=0; key_array
&& key_array
[i
]; i
++) {
7110 torture_assert(tctx
, test_EnumPrinterDataEx(tctx
, b
, handle
, key_array
[i
], NULL
, NULL
),
7111 "failed to call test_EnumPrinterDataEx");
7114 torture_comment(tctx
, "Printer Keys test succeeded\n\n");
7119 static bool test_openprinter_wrap(struct torture_context
*tctx
,
7122 struct torture_printer_context
*t
=
7123 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7124 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7125 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7126 const char *printername
= t
->info2
.printername
;
7128 return test_openprinter(tctx
, b
, printername
);
7131 static bool test_csetprinter(struct torture_context
*tctx
,
7134 struct torture_printer_context
*t
=
7135 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7136 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7138 const char *printername
= talloc_asprintf(tctx
, "%s2", t
->info2
.printername
);
7139 const char *drivername
= t
->added_driver
? t
->driver
.info8
.driver_name
: t
->info2
.drivername
;
7140 const char *portname
= t
->info2
.portname
;
7142 union spoolss_PrinterInfo info
;
7143 struct policy_handle new_handle
, new_handle2
;
7144 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7146 torture_comment(tctx
, "Testing c_setprinter\n");
7148 torture_assert(tctx
,
7149 test_GetPrinter_level(tctx
, b
, &t
->handle
, 0, &info
),
7150 "failed to get level 0 printer info");
7151 torture_comment(tctx
, "csetprinter on initial printer handle: %d\n",
7152 info
.info0
.c_setprinter
);
7154 /* check if c_setprinter on 1st handle increases after a printer has
7157 torture_assert(tctx
,
7158 test_AddPrinter_normal(tctx
, p
, &new_handle
, printername
, drivername
, portname
, NULL
, false),
7159 "failed to add new printer");
7160 torture_assert(tctx
,
7161 test_GetPrinter_level(tctx
, b
, &t
->handle
, 0, &info
),
7162 "failed to get level 0 printer info");
7163 torture_comment(tctx
, "csetprinter on initial printer handle (after add): %d\n",
7164 info
.info0
.c_setprinter
);
7166 /* check if c_setprinter on new handle increases after a printer has
7169 torture_assert(tctx
,
7170 test_GetPrinter_level(tctx
, b
, &new_handle
, 0, &info
),
7171 "failed to get level 0 printer info");
7172 torture_comment(tctx
, "csetprinter on created handle: %d\n",
7173 info
.info0
.c_setprinter
);
7175 /* open the new printer and check if c_setprinter increases */
7177 torture_assert(tctx
,
7178 call_OpenPrinterEx(tctx
, p
, printername
, NULL
, &new_handle2
),
7179 "failed to open created printer");
7180 torture_assert(tctx
,
7181 test_GetPrinter_level(tctx
, b
, &new_handle2
, 0, &info
),
7182 "failed to get level 0 printer info");
7183 torture_comment(tctx
, "csetprinter on new handle (after openprinter): %d\n",
7184 info
.info0
.c_setprinter
);
7188 torture_assert(tctx
,
7189 test_ClosePrinter(tctx
, b
, &new_handle2
),
7190 "failed to close printer");
7191 torture_assert(tctx
,
7192 test_DeletePrinter(tctx
, b
, &new_handle
),
7193 "failed to delete new printer");
7198 static bool compose_local_driver_directory(struct torture_context
*tctx
,
7199 const char *environment
,
7200 const char *local_dir
,
7205 p
= strrchr(local_dir
, '/');
7211 if (strequal(environment
, "Windows x64")) {
7212 if (!strequal(p
, "x64")) {
7213 *path
= talloc_asprintf(tctx
, "%s/x64", local_dir
);
7215 } else if (strequal(environment
, "Windows NT x86")) {
7216 if (!strequal(p
, "i386")) {
7217 *path
= talloc_asprintf(tctx
, "%s/i386", local_dir
);
7220 torture_assert(tctx
, "unknown environment: '%s'\n", environment
);
7226 static struct spoolss_DeviceMode
*torture_devicemode(TALLOC_CTX
*mem_ctx
,
7227 const char *devicename
)
7229 struct spoolss_DeviceMode
*r
;
7231 r
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
7236 r
->devicename
= talloc_strdup(r
, devicename
);
7237 r
->specversion
= DMSPEC_NT4_AND_ABOVE
;
7238 r
->driverversion
= 0x0600;
7240 r
->__driverextra_length
= 0;
7241 r
->fields
= DEVMODE_FORMNAME
|
7243 DEVMODE_PRINTQUALITY
|
7244 DEVMODE_DEFAULTSOURCE
|
7248 DEVMODE_ORIENTATION
;
7249 r
->orientation
= DMORIENT_PORTRAIT
;
7250 r
->papersize
= DMPAPER_LETTER
;
7255 r
->defaultsource
= DMBIN_FORMSOURCE
;
7256 r
->printquality
= DMRES_HIGH
;
7257 r
->color
= DMRES_MONOCHROME
;
7258 r
->duplex
= DMDUP_SIMPLEX
;
7260 r
->ttoption
= DMTT_SUBDEV
;
7261 r
->collate
= DMCOLLATE_FALSE
;
7262 r
->formname
= talloc_strdup(r
, "Letter");
7267 static bool test_architecture_buffer(struct torture_context
*tctx
,
7270 struct test_spoolss_context
*ctx
=
7271 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
7273 struct spoolss_OpenPrinterEx r
;
7274 struct spoolss_UserLevel1 u1
;
7275 struct policy_handle handle
;
7276 uint32_t architectures
[] = {
7277 PROCESSOR_ARCHITECTURE_INTEL
,
7278 PROCESSOR_ARCHITECTURE_IA64
,
7279 PROCESSOR_ARCHITECTURE_AMD64
7283 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
7284 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7286 for (i
=0; i
< ARRAY_SIZE(architectures
); i
++) {
7288 torture_comment(tctx
, "Testing OpenPrinterEx with architecture %d\n", architectures
[i
]);
7296 u1
.processor
= architectures
[i
];
7298 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
7299 r
.in
.datatype
= NULL
;
7300 r
.in
.devmode_ctr
.devmode
= NULL
;
7301 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7303 r
.in
.userlevel
.level1
= &u1
;
7304 r
.out
.handle
= &handle
;
7306 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_OpenPrinterEx_r(b
, tctx
, &r
), "");
7307 torture_assert_werr_ok(tctx
, r
.out
.result
, "");
7310 struct spoolss_EnumPrinters e
;
7312 union spoolss_PrinterInfo
*info
;
7314 e
.in
.flags
= PRINTER_ENUM_LOCAL
;
7319 e
.out
.count
= &count
;
7321 e
.out
.needed
= &needed
[i
];
7323 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_EnumPrinters_r(b
, tctx
, &e
), "");
7325 torture_comment(tctx
, "needed was %d\n", needed
[i
]);
7329 torture_assert(tctx
, test_ClosePrinter(tctx
, b
, &handle
), "");
7332 for (i
=1; i
< ARRAY_SIZE(architectures
); i
++) {
7333 if (needed
[i
-1] != needed
[i
]) {
7335 talloc_asprintf(tctx
, "needed size %d for architecture %d != needed size %d for architecture %d\n",
7336 needed
[i
-1], architectures
[i
-1], needed
[i
], architectures
[i
]));
7343 static bool test_PrintServer_Forms_Winreg(struct torture_context
*tctx
,
7346 struct test_spoolss_context
*ctx
=
7347 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
7348 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
7349 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7351 return test_Forms_winreg(tctx
, b
, &ctx
->server_handle
, true, NULL
);
7354 static bool test_PrintServer_Forms(struct torture_context
*tctx
,
7357 struct test_spoolss_context
*ctx
=
7358 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
7359 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
7360 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7362 return test_Forms(tctx
, b
, &ctx
->server_handle
, true, NULL
, NULL
, NULL
);
7365 static bool test_PrintServer_EnumForms(struct torture_context
*tctx
,
7368 struct test_spoolss_context
*ctx
=
7369 talloc_get_type_abort(private_data
, struct test_spoolss_context
);
7370 struct dcerpc_pipe
*p
= ctx
->spoolss_pipe
;
7371 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7373 return test_EnumForms_all(tctx
, b
, &ctx
->server_handle
, true);
7376 static bool torture_rpc_spoolss_setup_common(struct torture_context
*tctx
, struct test_spoolss_context
*t
)
7380 status
= torture_rpc_connection(tctx
, &t
->spoolss_pipe
, &ndr_table_spoolss
);
7382 torture_assert_ntstatus_ok(tctx
, status
, "Error connecting to server");
7384 torture_assert(tctx
,
7385 test_OpenPrinter_server(tctx
, t
->spoolss_pipe
, &t
->server_handle
),
7386 "failed to open printserver");
7387 torture_assert(tctx
,
7388 test_get_environment(tctx
, t
->spoolss_pipe
->binding_handle
, &t
->server_handle
, &t
->environment
),
7389 "failed to get environment");
7394 static bool torture_rpc_spoolss_setup(struct torture_context
*tctx
, void **data
)
7396 struct test_spoolss_context
*t
;
7398 *data
= t
= talloc_zero(tctx
, struct test_spoolss_context
);
7400 return torture_rpc_spoolss_setup_common(tctx
, t
);
7403 static bool torture_rpc_spoolss_teardown_common(struct torture_context
*tctx
, struct test_spoolss_context
*t
)
7405 test_ClosePrinter(tctx
, t
->spoolss_pipe
->binding_handle
, &t
->server_handle
);
7410 static bool torture_rpc_spoolss_teardown(struct torture_context
*tctx
, void *data
)
7412 struct test_spoolss_context
*t
= talloc_get_type(data
, struct test_spoolss_context
);
7415 ret
= torture_rpc_spoolss_teardown_common(tctx
, t
);
7421 static bool torture_rpc_spoolss_printer_setup_common(struct torture_context
*tctx
, struct torture_printer_context
*t
)
7423 struct dcerpc_pipe
*p
;
7424 struct dcerpc_binding_handle
*b
;
7425 const char *server_name_slash
;
7426 const char *driver_name
;
7427 const char *printer_name
;
7428 const char *port_name
;
7430 torture_assert_ntstatus_ok(tctx
,
7431 torture_rpc_connection(tctx
, &t
->spoolss_pipe
, &ndr_table_spoolss
),
7432 "Error connecting to server");
7434 p
= t
->spoolss_pipe
;
7435 b
= p
->binding_handle
;
7436 server_name_slash
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
7438 t
->driver
.info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
7439 t
->driver
.info8
.driver_name
= TORTURE_DRIVER
;
7440 t
->driver
.info8
.driver_path
= "pscript5.dll";
7441 t
->driver
.info8
.data_file
= "cups6.ppd";
7442 t
->driver
.info8
.config_file
= "ps5ui.dll";
7443 t
->driver
.info8
.help_file
= "pscript.hlp";
7444 t
->driver
.info8
.default_datatype
= "RAW";
7445 t
->driver
.info8
.dependent_files
= talloc_zero(t
, struct spoolss_StringArray
);
7446 t
->driver
.info8
.dependent_files
->string
= talloc_zero_array(t
, const char *, 8 + 1);
7447 t
->driver
.info8
.dependent_files
->string
[0] = "pscript5.dll";
7448 t
->driver
.info8
.dependent_files
->string
[1] = "cups6.ppd";
7449 t
->driver
.info8
.dependent_files
->string
[2] = "ps5ui.dll";
7450 t
->driver
.info8
.dependent_files
->string
[3] = "pscript.hlp";
7451 t
->driver
.info8
.dependent_files
->string
[4] = "pscript.ntf";
7452 t
->driver
.info8
.dependent_files
->string
[5] = "cups6.ini";
7453 t
->driver
.info8
.dependent_files
->string
[6] = "cupsps6.dll";
7454 t
->driver
.info8
.dependent_files
->string
[7] = "cupsui6.dll";
7456 t
->driver
.local
.driver_directory
= "/usr/share/cups/drivers";
7458 t
->info2
.drivername
= "Microsoft XPS Document Writer";
7459 t
->info2
.portname
= "LPT1:";
7461 printer_name
= t
->info2
.printername
;
7462 port_name
= t
->info2
.portname
;
7464 torture_assert(tctx
,
7465 fillup_printserver_info(tctx
, p
, &t
->driver
),
7466 "failed to fillup printserver info");
7468 t
->driver
.info8
.architecture
= talloc_strdup(t
, t
->driver
.remote
.environment
);
7470 torture_assert(tctx
,
7471 compose_local_driver_directory(tctx
, t
->driver
.remote
.environment
,
7472 t
->driver
.local
.driver_directory
,
7473 &t
->driver
.local
.driver_directory
),
7474 "failed to compose local driver directory");
7476 if (test_EnumPrinterDrivers_findone(tctx
, b
, server_name_slash
, t
->driver
.remote
.environment
, 3, t
->info2
.drivername
, NULL
)) {
7477 torture_comment(tctx
, "driver '%s' (architecture: %s, version: 3) is present on server\n",
7478 t
->info2
.drivername
, t
->driver
.remote
.environment
);
7479 t
->have_driver
= true;
7483 torture_comment(tctx
, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
7484 t
->info2
.drivername
, t
->driver
.remote
.environment
);
7485 torture_comment(tctx
, "trying to upload own driver\n");
7487 if (!directory_exist(t
->driver
.local
.driver_directory
)) {
7488 torture_warning(tctx
, "no local driver is available!");
7489 t
->have_driver
= false;
7493 torture_assert(tctx
,
7494 upload_printer_driver(tctx
, dcerpc_server_name(p
), &t
->driver
),
7495 "failed to upload printer driver");
7497 torture_assert(tctx
,
7498 test_AddPrinterDriver_args_level_3(tctx
, b
, server_name_slash
, &t
->driver
.info8
, 0, false, NULL
),
7499 "failed to add driver");
7501 t
->added_driver
= true;
7502 t
->have_driver
= true;
7505 driver_name
= t
->added_driver
? t
->driver
.info8
.driver_name
: t
->info2
.drivername
;
7508 torture_assert(tctx
,
7509 test_AddPrinter_wellknown(tctx
, p
, printer_name
, t
->ex
),
7510 "failed to add wellknown printer");
7512 torture_assert(tctx
,
7513 test_AddPrinter_normal(tctx
, p
, &t
->handle
, printer_name
, driver_name
, port_name
, t
->devmode
, t
->ex
),
7514 "failed to add printer");
7520 static bool torture_rpc_spoolss_printer_setup(struct torture_context
*tctx
, void **data
)
7522 struct torture_printer_context
*t
;
7524 *data
= t
= talloc_zero(tctx
, struct torture_printer_context
);
7527 t
->wellknown
= false;
7528 t
->info2
.printername
= TORTURE_PRINTER
;
7531 return torture_rpc_spoolss_printer_setup_common(tctx
, t
);
7534 static bool torture_rpc_spoolss_printerex_setup(struct torture_context
*tctx
, void **data
)
7536 struct torture_printer_context
*t
;
7538 *data
= t
= talloc_zero(tctx
, struct torture_printer_context
);
7541 t
->wellknown
= false;
7542 t
->info2
.printername
= TORTURE_PRINTER_EX
;
7545 return torture_rpc_spoolss_printer_setup_common(tctx
, t
);
7548 static bool torture_rpc_spoolss_printerwkn_setup(struct torture_context
*tctx
, void **data
)
7550 struct torture_printer_context
*t
;
7552 *data
= t
= talloc_zero(tctx
, struct torture_printer_context
);
7555 t
->wellknown
= true;
7556 t
->info2
.printername
= TORTURE_WELLKNOWN_PRINTER
;
7561 torture_skip(tctx
, "skipping AddPrinter level 1");
7564 return torture_rpc_spoolss_printer_setup_common(tctx
, t
);
7567 static bool torture_rpc_spoolss_printerexwkn_setup(struct torture_context
*tctx
, void **data
)
7569 struct torture_printer_context
*t
;
7571 *data
= t
= talloc_zero(tctx
, struct torture_printer_context
);
7574 t
->wellknown
= true;
7575 t
->info2
.printername
= TORTURE_WELLKNOWN_PRINTER_EX
;
7580 torture_skip(tctx
, "skipping AddPrinterEx level 1");
7583 return torture_rpc_spoolss_printer_setup_common(tctx
, t
);
7586 static bool torture_rpc_spoolss_printerdm_setup(struct torture_context
*tctx
, void **data
)
7588 struct torture_printer_context
*t
;
7590 *data
= t
= talloc_zero(tctx
, struct torture_printer_context
);
7593 t
->wellknown
= false;
7594 t
->info2
.printername
= TORTURE_PRINTER_EX
;
7595 t
->devmode
= torture_devicemode(t
, TORTURE_PRINTER_EX
);
7597 return torture_rpc_spoolss_printer_setup_common(tctx
, t
);
7600 static bool torture_rpc_spoolss_printer_teardown_common(struct torture_context
*tctx
, struct torture_printer_context
*t
)
7603 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7604 struct dcerpc_binding_handle
*b
;
7605 const char *printer_name
= t
->info2
.printername
;
7607 if (t
->added_driver
) {
7608 torture_assert(tctx
,
7609 remove_printer_driver(tctx
, dcerpc_server_name(t
->spoolss_pipe
), &t
->driver
),
7610 "failed to remove printer driver");
7614 b
= p
->binding_handle
;
7617 if (!t
->wellknown
) {
7618 torture_assert(tctx
,
7619 test_DeletePrinter(tctx
, b
, &t
->handle
),
7620 "failed to delete printer");
7622 torture_assert(tctx
,
7623 test_EnumPrinters_findname(tctx
, b
, PRINTER_ENUM_LOCAL
, 1,
7624 printer_name
, &found
),
7625 "failed to enumerate printers");
7627 torture_assert(tctx
, !found
, "deleted printer still there");
7633 static bool torture_rpc_spoolss_printer_teardown(struct torture_context
*tctx
, void *data
)
7635 struct torture_printer_context
*t
= talloc_get_type(data
, struct torture_printer_context
);
7638 ret
= torture_rpc_spoolss_printer_teardown_common(tctx
, t
);
7644 static bool test_print_test(struct torture_context
*tctx
,
7647 struct torture_printer_context
*t
=
7648 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7649 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7650 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7652 torture_assert(tctx
,
7653 test_PausePrinter(tctx
, b
, &t
->handle
),
7654 "failed to pause printer");
7656 torture_assert(tctx
,
7657 test_DoPrintTest(tctx
, b
, &t
->handle
),
7658 "failed to do print test");
7660 torture_assert(tctx
,
7661 test_ResumePrinter(tctx
, b
, &t
->handle
),
7662 "failed to resume printer");
7667 static bool test_print_test_extended(struct torture_context
*tctx
,
7670 struct torture_printer_context
*t
=
7671 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7672 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7673 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7676 torture_assert(tctx
,
7677 test_PausePrinter(tctx
, b
, &t
->handle
),
7678 "failed to pause printer");
7680 ret
= test_DoPrintTest_extended(tctx
, b
, &t
->handle
);
7682 torture_comment(tctx
, "WARNING! failed to do extended print test\n");
7683 if (torture_setting_bool(tctx
, "samba3", false)) {
7684 torture_comment(tctx
, "non-critical for samba3\n");
7686 tctx
->last_result
= TORTURE_SKIP
;
7690 torture_assert(tctx
,
7691 test_ResumePrinter(tctx
, b
, &t
->handle
),
7692 "failed to resume printer");
7697 static bool test_printer_sd(struct torture_context
*tctx
,
7700 struct torture_printer_context
*t
=
7701 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7702 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7703 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7705 torture_assert(tctx
,
7706 test_PrinterInfo_SD(tctx
, b
, &t
->handle
),
7707 "failed to test security descriptors");
7712 static bool test_printer_dm(struct torture_context
*tctx
,
7715 struct torture_printer_context
*t
=
7716 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7717 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7719 torture_assert(tctx
,
7720 test_PrinterInfo_DevMode(tctx
, p
, &t
->handle
, t
->info2
.printername
, t
->devmode
),
7721 "failed to test devicemodes");
7726 static bool test_printer_info_winreg(struct torture_context
*tctx
,
7729 struct torture_printer_context
*t
=
7730 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7731 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7733 torture_assert(tctx
,
7734 test_PrinterInfo_winreg(tctx
, p
, &t
->handle
, t
->info2
.printername
),
7735 "failed to test printer info winreg");
7740 static bool test_printer_change_id(struct torture_context
*tctx
,
7743 struct torture_printer_context
*t
=
7744 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7745 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7747 torture_assert(tctx
,
7748 test_ChangeID(tctx
, p
, &t
->handle
),
7749 "failed to test change id");
7754 static bool test_printer_keys(struct torture_context
*tctx
,
7757 struct torture_printer_context
*t
=
7758 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7759 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7760 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7762 torture_assert(tctx
,
7763 test_printer_all_keys(tctx
, b
, &t
->handle
),
7764 "failed to test printer keys");
7769 static bool test_printer_data_consistency(struct torture_context
*tctx
,
7772 struct torture_printer_context
*t
=
7773 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7774 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7776 torture_assert(tctx
,
7777 test_EnumPrinterData_consistency(tctx
, p
, &t
->handle
),
7778 "failed to test printer data consistency");
7783 static bool test_printer_data_keys(struct torture_context
*tctx
,
7786 struct torture_printer_context
*t
=
7787 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7788 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7790 torture_assert(tctx
,
7791 test_SetPrinterDataEx_keys(tctx
, p
, &t
->handle
),
7792 "failed to test printer data keys");
7797 static bool test_printer_data_values(struct torture_context
*tctx
,
7800 struct torture_printer_context
*t
=
7801 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7802 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7804 torture_assert(tctx
,
7805 test_SetPrinterDataEx_values(tctx
, p
, &t
->handle
),
7806 "failed to test printer data values");
7811 static bool test_printer_data_set(struct torture_context
*tctx
,
7814 struct torture_printer_context
*t
=
7815 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7816 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7818 torture_assert(tctx
,
7819 test_SetPrinterDataEx_matrix(tctx
, p
, &t
->handle
, t
->info2
.printername
, NULL
, NULL
),
7820 "failed to test printer data set");
7825 static bool test_printer_data_winreg(struct torture_context
*tctx
,
7828 struct torture_printer_context
*t
=
7829 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7830 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7832 torture_assert(tctx
,
7833 test_PrinterData_winreg(tctx
, p
, &t
->handle
, t
->info2
.printername
),
7834 "failed to test printer data winreg");
7839 static bool test_printer_data_dsspooler(struct torture_context
*tctx
,
7842 struct torture_printer_context
*t
=
7843 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7844 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7846 torture_assert(tctx
,
7847 test_PrinterData_DsSpooler(tctx
, p
, &t
->handle
, t
->info2
.printername
),
7848 "failed to test printer data winreg dsspooler");
7853 static bool test_driver_info_winreg(struct torture_context
*tctx
,
7856 struct torture_printer_context
*t
=
7857 (struct torture_printer_context
*)talloc_get_type_abort(private_data
, struct torture_printer_context
);
7858 struct dcerpc_pipe
*p
= t
->spoolss_pipe
;
7859 const char *driver_name
= t
->added_driver
? t
->driver
.info8
.driver_name
: t
->info2
.drivername
;
7861 if (!t
->have_driver
) {
7862 torture_skip(tctx
, "skipping driver info winreg test as we don't have a driver");
7865 torture_assert(tctx
,
7866 test_DriverInfo_winreg(tctx
, p
, &t
->handle
, t
->info2
.printername
, driver_name
, t
->driver
.remote
.environment
, 3),
7867 "failed to test driver info winreg");
7872 void torture_tcase_printer(struct torture_tcase
*tcase
)
7874 torture_tcase_add_simple_test(tcase
, "openprinter", test_openprinter_wrap
);
7875 torture_tcase_add_simple_test(tcase
, "csetprinter", test_csetprinter
);
7876 torture_tcase_add_simple_test(tcase
, "print_test", test_print_test
);
7877 torture_tcase_add_simple_test(tcase
, "print_test_extended", test_print_test_extended
);
7878 torture_tcase_add_simple_test(tcase
, "printer_info", test_printer_info
);
7879 torture_tcase_add_simple_test(tcase
, "sd", test_printer_sd
);
7880 torture_tcase_add_simple_test(tcase
, "dm", test_printer_dm
);
7881 torture_tcase_add_simple_test(tcase
, "printer_info_winreg", test_printer_info_winreg
);
7882 torture_tcase_add_simple_test(tcase
, "change_id", test_printer_change_id
);
7883 torture_tcase_add_simple_test(tcase
, "keys", test_printer_keys
);
7884 torture_tcase_add_simple_test(tcase
, "printerdata_consistency", test_printer_data_consistency
);
7885 torture_tcase_add_simple_test(tcase
, "printerdata_keys", test_printer_data_keys
);
7886 torture_tcase_add_simple_test(tcase
, "printerdata_values", test_printer_data_values
);
7887 torture_tcase_add_simple_test(tcase
, "printerdata_set", test_printer_data_set
);
7888 torture_tcase_add_simple_test(tcase
, "printerdata_winreg", test_printer_data_winreg
);
7889 torture_tcase_add_simple_test(tcase
, "printerdata_dsspooler", test_printer_data_dsspooler
);
7890 torture_tcase_add_simple_test(tcase
, "driver_info_winreg", test_driver_info_winreg
);
7891 torture_tcase_add_simple_test(tcase
, "printer_rename", test_printer_rename
);
7894 struct torture_suite
*torture_rpc_spoolss_printer(TALLOC_CTX
*mem_ctx
)
7896 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "printer");
7897 struct torture_tcase
*tcase
;
7899 tcase
= torture_suite_add_tcase(suite
, "addprinter");
7901 torture_tcase_set_fixture(tcase
,
7902 torture_rpc_spoolss_printer_setup
,
7903 torture_rpc_spoolss_printer_teardown
);
7905 torture_tcase_printer(tcase
);
7907 tcase
= torture_suite_add_tcase(suite
, "addprinterex");
7909 torture_tcase_set_fixture(tcase
,
7910 torture_rpc_spoolss_printerex_setup
,
7911 torture_rpc_spoolss_printer_teardown
);
7913 torture_tcase_printer(tcase
);
7915 tcase
= torture_suite_add_tcase(suite
, "addprinterwkn");
7917 torture_tcase_set_fixture(tcase
,
7918 torture_rpc_spoolss_printerwkn_setup
,
7919 torture_rpc_spoolss_printer_teardown
);
7921 tcase
= torture_suite_add_tcase(suite
, "addprinterexwkn");
7923 torture_tcase_set_fixture(tcase
,
7924 torture_rpc_spoolss_printerexwkn_setup
,
7925 torture_rpc_spoolss_printer_teardown
);
7928 /* test is not correct */
7929 tcase
= torture_suite_add_tcase(suite
, "addprinterdm");
7931 torture_tcase_set_fixture(tcase
,
7932 torture_rpc_spoolss_printerdm_setup
,
7933 torture_rpc_spoolss_printer_teardown
);
7935 torture_tcase_printer(tcase
);
7940 struct torture_suite
*torture_rpc_spoolss(TALLOC_CTX
*mem_ctx
)
7942 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "spoolss");
7943 struct torture_tcase
*tcase
= torture_suite_add_tcase(suite
, "printserver");
7945 torture_tcase_set_fixture(tcase
,
7946 torture_rpc_spoolss_setup
,
7947 torture_rpc_spoolss_teardown
);
7949 torture_tcase_add_simple_test(tcase
, "openprinter_badnamelist", test_OpenPrinter_badname_list
);
7950 torture_tcase_add_simple_test(tcase
, "printer_data_list", test_GetPrinterData_list
);
7951 torture_tcase_add_simple_test(tcase
, "enum_forms", test_PrintServer_EnumForms
);
7952 torture_tcase_add_simple_test(tcase
, "forms", test_PrintServer_Forms
);
7953 torture_tcase_add_simple_test(tcase
, "forms_winreg", test_PrintServer_Forms_Winreg
);
7954 torture_tcase_add_simple_test(tcase
, "enum_ports", test_EnumPorts
);
7955 torture_tcase_add_simple_test(tcase
, "add_port", test_AddPort
);
7956 torture_tcase_add_simple_test(tcase
, "get_printer_driver_directory", test_GetPrinterDriverDirectory
);
7957 torture_tcase_add_simple_test(tcase
, "get_print_processor_directory", test_GetPrintProcessorDirectory
);
7958 torture_tcase_add_simple_test(tcase
, "enum_printer_drivers", test_EnumPrinterDrivers
);
7959 torture_tcase_add_simple_test(tcase
, "enum_monitors", test_EnumMonitors
);
7960 torture_tcase_add_simple_test(tcase
, "enum_print_processors", test_EnumPrintProcessors
);
7961 torture_tcase_add_simple_test(tcase
, "print_processors_winreg", test_print_processors_winreg
);
7962 torture_tcase_add_simple_test(tcase
, "enum_printprocdata", test_EnumPrintProcDataTypes
);
7963 torture_tcase_add_simple_test(tcase
, "enum_printers", test_EnumPrinters
);
7964 torture_tcase_add_simple_test(tcase
, "enum_ports_old", test_EnumPorts_old
);
7965 torture_tcase_add_simple_test(tcase
, "enum_printers_old", test_EnumPrinters_old
);
7966 torture_tcase_add_simple_test(tcase
, "enum_printers_servername", test_EnumPrinters_servername
);
7967 torture_tcase_add_simple_test(tcase
, "enum_printer_drivers_old", test_EnumPrinterDrivers_old
);
7968 torture_tcase_add_simple_test(tcase
, "architecture_buffer", test_architecture_buffer
);
7970 torture_suite_add_suite(suite
, torture_rpc_spoolss_printer(suite
));
7975 static bool test_GetPrinterDriverDirectory_getdir(struct torture_context
*tctx
,
7976 struct dcerpc_binding_handle
*b
,
7978 const char *environment
,
7981 struct spoolss_GetPrinterDriverDirectory r
;
7984 r
.in
.server
= server
;
7985 r
.in
.environment
= environment
;
7989 r
.out
.needed
= &needed
;
7991 torture_assert_ntstatus_ok(tctx
,
7992 dcerpc_spoolss_GetPrinterDriverDirectory_r(b
, tctx
, &r
),
7993 "failed to query driver directory");
7995 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
7996 DATA_BLOB blob
= data_blob_talloc_zero(tctx
, needed
);
7997 r
.in
.buffer
= &blob
;
7998 r
.in
.offered
= needed
;
8000 torture_assert_ntstatus_ok(tctx
,
8001 dcerpc_spoolss_GetPrinterDriverDirectory_r(b
, tctx
, &r
),
8002 "failed to query driver directory");
8005 torture_assert_werr_ok(tctx
, r
.out
.result
,
8006 "failed to query driver directory");
8009 *dir_p
= r
.out
.info
->info1
.directory_name
;
8015 static const char *get_driver_from_info(struct spoolss_AddDriverInfoCtr
*info_ctr
)
8017 if (info_ctr
== NULL
) {
8021 switch (info_ctr
->level
) {
8023 return info_ctr
->info
.info1
->driver_name
;
8025 return info_ctr
->info
.info2
->driver_name
;
8027 return info_ctr
->info
.info3
->driver_name
;
8029 return info_ctr
->info
.info4
->driver_name
;
8031 return info_ctr
->info
.info6
->driver_name
;
8033 return info_ctr
->info
.info8
->driver_name
;
8039 static const char *get_environment_from_info(struct spoolss_AddDriverInfoCtr
*info_ctr
)
8041 if (info_ctr
== NULL
) {
8045 switch (info_ctr
->level
) {
8047 return info_ctr
->info
.info2
->architecture
;
8049 return info_ctr
->info
.info3
->architecture
;
8051 return info_ctr
->info
.info4
->architecture
;
8053 return info_ctr
->info
.info6
->architecture
;
8055 return info_ctr
->info
.info8
->architecture
;
8062 static bool test_AddPrinterDriver_exp(struct torture_context
*tctx
,
8063 struct dcerpc_binding_handle
*b
,
8064 const char *servername
,
8065 struct spoolss_AddDriverInfoCtr
*info_ctr
,
8066 WERROR expected_result
)
8068 struct spoolss_AddPrinterDriver r
;
8069 const char *drivername
= get_driver_from_info(info_ctr
);
8070 const char *environment
= get_environment_from_info(info_ctr
);
8072 r
.in
.servername
= servername
;
8073 r
.in
.info_ctr
= info_ctr
;
8075 torture_comment(tctx
, "Testing AddPrinterDriver(%s) level: %d, environment: '%s'\n",
8076 drivername
, info_ctr
->level
, environment
);
8078 torture_assert_ntstatus_ok(tctx
,
8079 dcerpc_spoolss_AddPrinterDriver_r(b
, tctx
, &r
),
8080 "spoolss_AddPrinterDriver failed");
8081 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
8082 "spoolss_AddPrinterDriver failed with unexpected result");
8088 static bool test_AddPrinterDriverEx_exp(struct torture_context
*tctx
,
8089 struct dcerpc_binding_handle
*b
,
8090 const char *servername
,
8091 struct spoolss_AddDriverInfoCtr
*info_ctr
,
8093 WERROR expected_result
)
8095 struct spoolss_AddPrinterDriverEx r
;
8096 const char *drivername
= get_driver_from_info(info_ctr
);
8097 const char *environment
= get_environment_from_info(info_ctr
);
8099 r
.in
.servername
= servername
;
8100 r
.in
.info_ctr
= info_ctr
;
8103 torture_comment(tctx
, "Testing AddPrinterDriverEx(%s) level: %d, environment: '%s'\n",
8104 drivername
, info_ctr
->level
, environment
);
8106 torture_assert_ntstatus_ok(tctx
,
8107 dcerpc_spoolss_AddPrinterDriverEx_r(b
, tctx
, &r
),
8108 "AddPrinterDriverEx failed");
8109 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
8110 "AddPrinterDriverEx failed with unexpected result");
8115 #define ASSERT_DRIVER_PATH(tctx, path, driver_dir, cmt) \
8116 if (path && strlen(path)) {\
8117 torture_assert_strn_equal(tctx, path, driver_dir, strlen(driver_dir), cmt); \
8120 static bool test_AddPrinterDriver_args_level_1(struct torture_context
*tctx
,
8121 struct dcerpc_binding_handle
*b
,
8122 const char *server_name
,
8123 struct spoolss_AddDriverInfo8
*r
,
8126 const char *remote_driver_dir
)
8128 struct spoolss_AddDriverInfoCtr info_ctr
;
8129 struct spoolss_AddDriverInfo1 info1
;
8134 info_ctr
.info
.info1
= &info1
;
8137 torture_assert(tctx
,
8138 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_UNKNOWN_LEVEL
),
8139 "failed to test AddPrinterDriverEx level 1");
8141 torture_assert(tctx
,
8142 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_UNKNOWN_LEVEL
),
8143 "failed to test AddPrinterDriver level 1");
8146 info1
.driver_name
= r
->driver_name
;
8149 torture_assert(tctx
,
8150 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_UNKNOWN_LEVEL
),
8151 "failed to test AddPrinterDriverEx level 1");
8153 torture_assert(tctx
,
8154 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_UNKNOWN_LEVEL
),
8155 "failed to test AddPrinterDriver level 1");
8161 static bool test_AddPrinterDriver_args_level_2(struct torture_context
*tctx
,
8162 struct dcerpc_binding_handle
*b
,
8163 const char *server_name
,
8164 struct spoolss_AddDriverInfo8
*r
,
8167 const char *remote_driver_dir
)
8169 struct spoolss_AddDriverInfoCtr info_ctr
;
8170 struct spoolss_AddDriverInfo2 info2
;
8171 union spoolss_DriverInfo info
;
8176 info_ctr
.info
.info2
= &info2
;
8179 torture_assert(tctx
,
8180 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8181 "failed to test AddPrinterDriverEx level 2");
8183 torture_assert(tctx
,
8184 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8185 "failed to test AddPrinterDriver level 2");
8188 info2
.driver_name
= r
->driver_name
;
8191 torture_assert(tctx
,
8192 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8193 "failed to test AddPrinterDriverEx level 2");
8195 torture_assert(tctx
,
8196 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8197 "failed to test AddPrinterDriver level 2");
8200 info2
.version
= r
->version
;
8203 torture_assert(tctx
,
8204 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8205 "failed to test AddPrinterDriverEx level 2");
8207 torture_assert(tctx
,
8208 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8209 "failed to test AddPrinterDriver level 2");
8212 info2
.architecture
= r
->architecture
;
8215 torture_assert(tctx
,
8216 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8217 "failed to test AddPrinterDriverEx level 2");
8219 torture_assert(tctx
,
8220 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8221 "failed to test AddPrinterDriver level 2");
8224 info2
.driver_path
= r
->driver_path
;
8227 torture_assert(tctx
,
8228 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8229 "failed to test AddPrinterDriverEx level 2");
8231 torture_assert(tctx
,
8232 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8233 "failed to test AddPrinterDriver level 2");
8236 info2
.data_file
= r
->data_file
;
8239 torture_assert(tctx
,
8240 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_INVALID_PARAM
),
8241 "failed to test AddPrinterDriverEx level 2");
8243 torture_assert(tctx
,
8244 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_INVALID_PARAM
),
8245 "failed to test AddPrinterDriver level 2");
8248 info2
.config_file
= r
->config_file
;
8251 torture_assert(tctx
,
8252 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, 0, WERR_INVALID_PARAM
),
8253 "failed to test AddPrinterDriverEx");
8257 torture_assert(tctx
,
8258 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_OK
),
8259 "failed to test AddPrinterDriverEx level 2");
8261 torture_assert(tctx
,
8262 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_OK
),
8263 "failed to test AddPrinterDriver level 2");
8266 torture_assert(tctx
,
8267 test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, r
->architecture
, 2, r
->driver_name
, &info
),
8268 "failed to find added printer driver");
8270 if (remote_driver_dir
) {
8271 ASSERT_DRIVER_PATH(tctx
, info
.info2
.driver_path
, remote_driver_dir
, "unexpected path");
8272 ASSERT_DRIVER_PATH(tctx
, info
.info2
.data_file
, remote_driver_dir
, "unexpected path");
8273 ASSERT_DRIVER_PATH(tctx
, info
.info2
.config_file
, remote_driver_dir
, "unexpected path");
8279 static bool test_AddPrinterDriver_args_level_3(struct torture_context
*tctx
,
8280 struct dcerpc_binding_handle
*b
,
8281 const char *server_name
,
8282 struct spoolss_AddDriverInfo8
*r
,
8285 const char *remote_driver_dir
)
8287 struct spoolss_AddDriverInfoCtr info_ctr
;
8288 struct spoolss_AddDriverInfo3 info3
;
8289 union spoolss_DriverInfo info
;
8291 info3
.driver_name
= r
->driver_name
;
8292 info3
.version
= r
->version
;
8293 info3
.architecture
= r
->architecture
;
8294 info3
.driver_path
= r
->driver_path
;
8295 info3
.data_file
= r
->data_file
;
8296 info3
.config_file
= r
->config_file
;
8297 info3
.help_file
= r
->help_file
;
8298 info3
.monitor_name
= r
->monitor_name
;
8299 info3
.default_datatype
= r
->default_datatype
;
8300 info3
._ndr_size_dependent_files
= r
->_ndr_size_dependent_files
;
8301 info3
.dependent_files
= r
->dependent_files
;
8304 info_ctr
.info
.info3
= &info3
;
8307 torture_assert(tctx
,
8308 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_OK
),
8309 "failed to test AddPrinterDriverEx level 3");
8311 torture_assert(tctx
,
8312 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_OK
),
8313 "failed to test AddPrinterDriver level 3");
8316 torture_assert(tctx
,
8317 test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, r
->architecture
, 3, r
->driver_name
, &info
),
8318 "failed to find added printer driver");
8320 if (remote_driver_dir
) {
8322 ASSERT_DRIVER_PATH(tctx
, info
.info3
.driver_path
, remote_driver_dir
, "unexpected path");
8323 ASSERT_DRIVER_PATH(tctx
, info
.info3
.data_file
, remote_driver_dir
, "unexpected path");
8324 ASSERT_DRIVER_PATH(tctx
, info
.info3
.config_file
, remote_driver_dir
, "unexpected path");
8325 ASSERT_DRIVER_PATH(tctx
, info
.info3
.help_file
, remote_driver_dir
, "unexpected path");
8326 for (i
=0; info
.info3
.dependent_files
&& info
.info3
.dependent_files
[i
] != NULL
; i
++) {
8327 ASSERT_DRIVER_PATH(tctx
, info
.info3
.dependent_files
[i
], remote_driver_dir
, "unexpected path");
8334 static bool test_AddPrinterDriver_args_level_4(struct torture_context
*tctx
,
8335 struct dcerpc_binding_handle
*b
,
8336 const char *server_name
,
8337 struct spoolss_AddDriverInfo8
*r
,
8340 const char *remote_driver_dir
)
8342 struct spoolss_AddDriverInfoCtr info_ctr
;
8343 struct spoolss_AddDriverInfo4 info4
;
8344 union spoolss_DriverInfo info
;
8346 info4
.version
= r
->version
;
8347 info4
.driver_name
= r
->driver_name
;
8348 info4
.architecture
= r
->architecture
;
8349 info4
.driver_path
= r
->driver_path
;
8350 info4
.data_file
= r
->data_file
;
8351 info4
.config_file
= r
->config_file
;
8352 info4
.help_file
= r
->help_file
;
8353 info4
.monitor_name
= r
->monitor_name
;
8354 info4
.default_datatype
= r
->default_datatype
;
8355 info4
._ndr_size_dependent_files
= r
->_ndr_size_dependent_files
;
8356 info4
.dependent_files
= r
->dependent_files
;
8357 info4
._ndr_size_previous_names
= r
->_ndr_size_previous_names
;
8358 info4
.previous_names
= r
->previous_names
;
8361 info_ctr
.info
.info4
= &info4
;
8364 torture_assert(tctx
,
8365 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_OK
),
8366 "failed to test AddPrinterDriverEx level 4");
8368 torture_assert(tctx
,
8369 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_OK
),
8370 "failed to test AddPrinterDriver level 4");
8373 torture_assert(tctx
,
8374 test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, r
->architecture
, 4, r
->driver_name
, &info
),
8375 "failed to find added printer driver");
8377 if (remote_driver_dir
) {
8379 ASSERT_DRIVER_PATH(tctx
, info
.info4
.driver_path
, remote_driver_dir
, "unexpected path");
8380 ASSERT_DRIVER_PATH(tctx
, info
.info4
.data_file
, remote_driver_dir
, "unexpected path");
8381 ASSERT_DRIVER_PATH(tctx
, info
.info4
.config_file
, remote_driver_dir
, "unexpected path");
8382 ASSERT_DRIVER_PATH(tctx
, info
.info4
.help_file
, remote_driver_dir
, "unexpected path");
8383 for (i
=0; info
.info4
.dependent_files
&& info
.info4
.dependent_files
[i
] != NULL
; i
++) {
8384 ASSERT_DRIVER_PATH(tctx
, info
.info4
.dependent_files
[i
], remote_driver_dir
, "unexpected path");
8391 static bool test_AddPrinterDriver_args_level_6(struct torture_context
*tctx
,
8392 struct dcerpc_binding_handle
*b
,
8393 const char *server_name
,
8394 struct spoolss_AddDriverInfo8
*r
,
8397 const char *remote_driver_dir
)
8399 struct spoolss_AddDriverInfoCtr info_ctr
;
8400 struct spoolss_AddDriverInfo6 info6
;
8401 union spoolss_DriverInfo info
;
8403 info6
.version
= r
->version
;
8404 info6
.driver_name
= r
->driver_name
;
8405 info6
.architecture
= r
->architecture
;
8406 info6
.driver_path
= r
->driver_path
;
8407 info6
.data_file
= r
->data_file
;
8408 info6
.config_file
= r
->config_file
;
8409 info6
.help_file
= r
->help_file
;
8410 info6
.monitor_name
= r
->monitor_name
;
8411 info6
.default_datatype
= r
->default_datatype
;
8412 info6
._ndr_size_dependent_files
= r
->_ndr_size_dependent_files
;
8413 info6
.dependent_files
= r
->dependent_files
;
8414 info6
._ndr_size_previous_names
= r
->_ndr_size_previous_names
;
8415 info6
.previous_names
= r
->previous_names
;
8416 info6
.driver_date
= r
->driver_date
;
8417 info6
.driver_version
= r
->driver_version
;
8418 info6
.manufacturer_name
= r
->manufacturer_name
;
8419 info6
.manufacturer_url
= r
->manufacturer_url
;
8420 info6
.hardware_id
= r
->hardware_id
;
8421 info6
.provider
= r
->provider
;
8424 info_ctr
.info
.info6
= &info6
;
8427 torture_assert(tctx
,
8428 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_OK
),
8429 "failed to test AddPrinterDriverEx level 6");
8431 torture_assert(tctx
,
8432 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_UNKNOWN_LEVEL
),
8433 "failed to test AddPrinterDriver level 6");
8436 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8442 torture_assert(tctx
,
8443 test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, r
->architecture
, 6, r
->driver_name
, &info
),
8444 "failed to find added printer driver");
8446 if (remote_driver_dir
) {
8448 ASSERT_DRIVER_PATH(tctx
, info
.info6
.driver_path
, remote_driver_dir
, "unexpected path");
8449 ASSERT_DRIVER_PATH(tctx
, info
.info6
.data_file
, remote_driver_dir
, "unexpected path");
8450 ASSERT_DRIVER_PATH(tctx
, info
.info6
.config_file
, remote_driver_dir
, "unexpected path");
8451 ASSERT_DRIVER_PATH(tctx
, info
.info6
.help_file
, remote_driver_dir
, "unexpected path");
8452 for (i
=0; info
.info6
.dependent_files
&& info
.info6
.dependent_files
[i
] != NULL
; i
++) {
8453 ASSERT_DRIVER_PATH(tctx
, info
.info6
.dependent_files
[i
], remote_driver_dir
, "unexpected path");
8457 torture_assert_nttime_equal(tctx
, info
.info6
.driver_date
, info6
.driver_date
, "driverdate mismatch");
8462 static bool test_AddPrinterDriver_args_level_8(struct torture_context
*tctx
,
8463 struct dcerpc_binding_handle
*b
,
8464 const char *server_name
,
8465 struct spoolss_AddDriverInfo8
*r
,
8468 const char *remote_driver_dir
)
8470 struct spoolss_AddDriverInfoCtr info_ctr
;
8471 union spoolss_DriverInfo info
;
8474 info_ctr
.info
.info8
= r
;
8477 torture_assert(tctx
,
8478 test_AddPrinterDriverEx_exp(tctx
, b
, server_name
, &info_ctr
, flags
, WERR_OK
),
8479 "failed to test AddPrinterDriverEx level 8");
8481 torture_assert(tctx
,
8482 test_AddPrinterDriver_exp(tctx
, b
, server_name
, &info_ctr
, WERR_UNKNOWN_LEVEL
),
8483 "failed to test AddPrinterDriver level 8");
8486 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8492 torture_assert(tctx
,
8493 test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, r
->architecture
, 8, r
->driver_name
, &info
),
8494 "failed to find added printer driver");
8496 if (remote_driver_dir
) {
8498 ASSERT_DRIVER_PATH(tctx
, info
.info8
.driver_path
, remote_driver_dir
, "unexpected path");
8499 ASSERT_DRIVER_PATH(tctx
, info
.info8
.data_file
, remote_driver_dir
, "unexpected path");
8500 ASSERT_DRIVER_PATH(tctx
, info
.info8
.config_file
, remote_driver_dir
, "unexpected path");
8501 ASSERT_DRIVER_PATH(tctx
, info
.info8
.help_file
, remote_driver_dir
, "unexpected path");
8502 for (i
=0; info
.info8
.dependent_files
&& info
.info8
.dependent_files
[i
] != NULL
; i
++) {
8503 ASSERT_DRIVER_PATH(tctx
, info
.info8
.dependent_files
[i
], remote_driver_dir
, "unexpected path");
8507 torture_assert_nttime_equal(tctx
, info
.info8
.driver_date
, r
->driver_date
, "driverdate mismatch");
8512 #undef ASSERT_DRIVER_PATH
8514 static bool test_DeletePrinterDriver_exp(struct torture_context
*tctx
,
8515 struct dcerpc_binding_handle
*b
,
8518 const char *environment
,
8519 WERROR expected_result
)
8521 struct spoolss_DeletePrinterDriver r
;
8523 r
.in
.server
= server
;
8524 r
.in
.architecture
= environment
;
8525 r
.in
.driver
= driver
;
8527 torture_comment(tctx
, "Testing DeletePrinterDriver(%s)\n", driver
);
8529 torture_assert_ntstatus_ok(tctx
,
8530 dcerpc_spoolss_DeletePrinterDriver_r(b
, tctx
, &r
),
8531 "DeletePrinterDriver failed");
8532 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
8533 "DeletePrinterDriver failed with unexpected result");
8538 static bool test_DeletePrinterDriverEx_exp(struct torture_context
*tctx
,
8539 struct dcerpc_binding_handle
*b
,
8542 const char *environment
,
8543 uint32_t delete_flags
,
8545 WERROR expected_result
)
8547 struct spoolss_DeletePrinterDriverEx r
;
8549 r
.in
.server
= server
;
8550 r
.in
.architecture
= environment
;
8551 r
.in
.driver
= driver
;
8552 r
.in
.delete_flags
= delete_flags
;
8553 r
.in
.version
= version
;
8555 torture_comment(tctx
, "Testing DeletePrinterDriverEx(%s)\n", driver
);
8557 torture_assert_ntstatus_ok(tctx
,
8558 dcerpc_spoolss_DeletePrinterDriverEx_r(b
, tctx
, &r
),
8559 "DeletePrinterDriverEx failed");
8560 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
8561 "DeletePrinterDriverEx failed with unexpected result");
8566 static bool test_DeletePrinterDriver(struct torture_context
*tctx
,
8567 struct dcerpc_binding_handle
*b
,
8568 const char *server_name
,
8570 const char *environment
)
8572 torture_assert(tctx
,
8573 test_DeletePrinterDriver_exp(tctx
, b
, server_name
, driver
, "FOOBAR", WERR_INVALID_ENVIRONMENT
),
8574 "failed to delete driver");
8576 torture_assert(tctx
,
8577 test_DeletePrinterDriver_exp(tctx
, b
, server_name
, driver
, environment
, WERR_OK
),
8578 "failed to delete driver");
8580 if (test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, environment
, 1, driver
, NULL
)) {
8581 torture_fail(tctx
, "deleted driver still enumerated");
8584 torture_assert(tctx
,
8585 test_DeletePrinterDriver_exp(tctx
, b
, server_name
, driver
, environment
, WERR_UNKNOWN_PRINTER_DRIVER
),
8586 "2nd delete failed");
8591 static bool test_DeletePrinterDriverEx(struct torture_context
*tctx
,
8592 struct dcerpc_binding_handle
*b
,
8593 const char *server_name
,
8595 const char *environment
,
8596 uint32_t delete_flags
,
8599 torture_assert(tctx
,
8600 test_DeletePrinterDriverEx_exp(tctx
, b
, server_name
, driver
, "FOOBAR", delete_flags
, version
, WERR_INVALID_ENVIRONMENT
),
8601 "failed to delete driver");
8603 torture_assert(tctx
,
8604 test_DeletePrinterDriverEx_exp(tctx
, b
, server_name
, driver
, environment
, delete_flags
, version
, WERR_OK
),
8605 "failed to delete driver");
8607 if (test_EnumPrinterDrivers_findone(tctx
, b
, server_name
, environment
, 1, driver
, NULL
)) {
8608 torture_fail(tctx
, "deleted driver still enumerated");
8611 torture_assert(tctx
,
8612 test_DeletePrinterDriverEx_exp(tctx
, b
, server_name
, driver
, environment
, delete_flags
, version
, WERR_UNKNOWN_PRINTER_DRIVER
),
8613 "2nd delete failed");
8618 static bool test_PrinterDriver_args(struct torture_context
*tctx
,
8619 struct dcerpc_binding_handle
*b
,
8620 const char *server_name
,
8622 struct spoolss_AddDriverInfo8
*r
,
8624 uint32_t delete_flags
,
8625 uint32_t delete_version
,
8627 const char *remote_driver_dir
)
8633 ret
= test_AddPrinterDriver_args_level_1(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8636 ret
= test_AddPrinterDriver_args_level_2(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8639 ret
= test_AddPrinterDriver_args_level_3(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8642 ret
= test_AddPrinterDriver_args_level_4(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8645 ret
= test_AddPrinterDriver_args_level_6(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8648 ret
= test_AddPrinterDriver_args_level_8(tctx
, b
, server_name
, r
, add_flags
, ex
, remote_driver_dir
);
8662 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8664 if (!ex
&& (level
== 6 || level
== 8)) {
8669 struct dcerpc_pipe
*p2
;
8670 struct policy_handle hive_handle
;
8671 struct dcerpc_binding_handle
*b2
;
8673 torture_assert_ntstatus_ok(tctx
,
8674 torture_rpc_connection(tctx
, &p2
, &ndr_table_winreg
),
8675 "could not open winreg pipe");
8676 b2
= p2
->binding_handle
;
8678 torture_assert(tctx
, test_winreg_OpenHKLM(tctx
, b2
, &hive_handle
), "");
8680 ret
= test_GetDriverInfo_winreg(tctx
, b
, NULL
, NULL
, r
->driver_name
, r
->architecture
, r
->version
, b2
, &hive_handle
, server_name
);
8682 test_winreg_CloseKey(tctx
, b2
, &hive_handle
);
8688 return test_DeletePrinterDriverEx(tctx
, b
, server_name
, r
->driver_name
, r
->architecture
, delete_flags
, r
->version
);
8690 return test_DeletePrinterDriver(tctx
, b
, server_name
, r
->driver_name
, r
->architecture
);
8694 static bool fillup_printserver_info(struct torture_context
*tctx
,
8695 struct dcerpc_pipe
*p
,
8696 struct torture_driver_context
*d
)
8698 struct policy_handle server_handle
;
8699 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8700 const char *server_name_slash
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
8702 torture_assert(tctx
,
8703 test_OpenPrinter_server(tctx
, p
, &server_handle
),
8704 "failed to open printserver");
8705 torture_assert(tctx
,
8706 test_get_environment(tctx
, b
, &server_handle
, &d
->remote
.environment
),
8707 "failed to get environment");
8708 torture_assert(tctx
,
8709 test_ClosePrinter(tctx
, b
, &server_handle
),
8710 "failed to close printserver");
8712 torture_assert(tctx
,
8713 test_GetPrinterDriverDirectory_getdir(tctx
, b
, server_name_slash
,
8714 d
->local
.environment
? d
->local
.environment
: d
->remote
.environment
,
8715 &d
->remote
.driver_directory
),
8716 "failed to get driver directory");
8721 static const char *driver_directory_dir(const char *driver_directory
)
8725 p
= strrchr(driver_directory
, '\\');
8733 static const char *driver_directory_share(struct torture_context
*tctx
,
8734 const char *driver_directory
)
8739 if (driver_directory
[0] == '\\' && driver_directory
[1] == '\\') {
8740 driver_directory
+= 2;
8743 p
= talloc_strdup(tctx
, driver_directory
);
8745 torture_assert(tctx
,
8746 next_token_talloc(tctx
, &p
, &tok
, "\\"),
8747 "cannot explode uri");
8748 torture_assert(tctx
,
8749 next_token_talloc(tctx
, &p
, &tok
, "\\"),
8750 "cannot explode uri");
8755 static bool upload_printer_driver_file(struct torture_context
*tctx
,
8756 struct smbcli_state
*cli
,
8757 struct torture_driver_context
*d
,
8758 const char *file_name
)
8763 int maxwrite
= 64512;
8766 const char *remote_dir
= driver_directory_dir(d
->remote
.driver_directory
);
8767 const char *local_name
= talloc_asprintf(tctx
, "%s/%s", d
->local
.driver_directory
, file_name
);
8768 const char *remote_name
= talloc_asprintf(tctx
, "%s\\%s", remote_dir
, file_name
);
8770 if (!file_name
|| strlen(file_name
) == 0) {
8774 torture_comment(tctx
, "Uploading %s to %s\n", local_name
, remote_name
);
8776 fnum
= smbcli_open(cli
->tree
, remote_name
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
);
8778 torture_fail(tctx
, talloc_asprintf(tctx
, "failed to open remote file: %s\n", remote_name
));
8781 f
= x_fopen(local_name
, O_RDONLY
, 0);
8783 torture_fail(tctx
, talloc_asprintf(tctx
, "failed to open local file: %s\n", local_name
));
8786 buf
= talloc_array(tctx
, uint8_t, maxwrite
);
8791 while (!x_feof(f
)) {
8795 if ((n
= x_fread(buf
, 1, n
, f
)) < 1) {
8796 if((n
== 0) && x_feof(f
))
8797 break; /* Empty local file. */
8799 torture_warning(tctx
,
8800 "failed to read file: %s\n", strerror(errno
));
8804 ret
= smbcli_write(cli
->tree
, fnum
, 0, buf
, nread
+ start
, n
);
8807 torture_warning(tctx
,
8808 "failed to write file: %s\n", smbcli_errstr(cli
->tree
));
8817 torture_assert_ntstatus_ok(tctx
,
8818 smbcli_close(cli
->tree
, fnum
),
8819 "failed to close file");
8824 static bool connect_printer_driver_share(struct torture_context
*tctx
,
8825 const char *server_name
,
8826 const char *share_name
,
8827 struct smbcli_state
**cli
)
8829 struct smbcli_options smb_options
;
8830 struct smbcli_session_options smb_session_options
;
8832 torture_comment(tctx
, "Connecting printer driver share '%s' on '%s'\n",
8833 share_name
, server_name
);
8835 lpcfg_smbcli_options(tctx
->lp_ctx
, &smb_options
);
8836 lpcfg_smbcli_session_options(tctx
->lp_ctx
, &smb_session_options
);
8838 torture_assert_ntstatus_ok(tctx
,
8839 smbcli_full_connection(tctx
, cli
, server_name
,
8840 lpcfg_smb_ports(tctx
->lp_ctx
),
8842 lpcfg_socket_options(tctx
->lp_ctx
),
8843 cmdline_credentials
,
8844 lpcfg_resolve_context(tctx
->lp_ctx
),
8847 &smb_session_options
,
8848 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)),
8849 "failed to open driver share");
8854 static bool upload_printer_driver(struct torture_context
*tctx
,
8855 const char *server_name
,
8856 struct torture_driver_context
*d
)
8858 struct smbcli_state
*cli
;
8859 const char *share_name
= driver_directory_share(tctx
, d
->remote
.driver_directory
);
8862 torture_assert(tctx
,
8863 connect_printer_driver_share(tctx
, server_name
, share_name
, &cli
),
8864 "failed to connect to driver share");
8866 torture_comment(tctx
, "Uploading printer driver files to \\\\%s\\%s\n",
8867 server_name
, share_name
);
8869 torture_assert(tctx
,
8870 upload_printer_driver_file(tctx
, cli
, d
, d
->info8
.driver_path
),
8871 "failed to upload driver_path");
8872 torture_assert(tctx
,
8873 upload_printer_driver_file(tctx
, cli
, d
, d
->info8
.data_file
),
8874 "failed to upload data_file");
8875 torture_assert(tctx
,
8876 upload_printer_driver_file(tctx
, cli
, d
, d
->info8
.config_file
),
8877 "failed to upload config_file");
8878 torture_assert(tctx
,
8879 upload_printer_driver_file(tctx
, cli
, d
, d
->info8
.help_file
),
8880 "failed to upload help_file");
8881 if (d
->info8
.dependent_files
) {
8882 for (i
=0; d
->info8
.dependent_files
->string
&& d
->info8
.dependent_files
->string
[i
] != NULL
; i
++) {
8883 torture_assert(tctx
,
8884 upload_printer_driver_file(tctx
, cli
, d
, d
->info8
.dependent_files
->string
[i
]),
8885 "failed to upload dependent_files");
8894 static bool remove_printer_driver_file(struct torture_context
*tctx
,
8895 struct smbcli_state
*cli
,
8896 struct torture_driver_context
*d
,
8897 const char *file_name
)
8899 const char *remote_name
;
8900 const char *remote_dir
= driver_directory_dir(d
->remote
.driver_directory
);
8902 if (!file_name
|| strlen(file_name
) == 0) {
8906 remote_name
= talloc_asprintf(tctx
, "%s\\%s", remote_dir
, file_name
);
8908 torture_comment(tctx
, "Removing %s\n", remote_name
);
8910 torture_assert_ntstatus_ok(tctx
,
8911 smbcli_unlink(cli
->tree
, remote_name
),
8912 "failed to unlink");
8917 static bool remove_printer_driver(struct torture_context
*tctx
,
8918 const char *server_name
,
8919 struct torture_driver_context
*d
)
8921 struct smbcli_state
*cli
;
8922 const char *share_name
= driver_directory_share(tctx
, d
->remote
.driver_directory
);
8925 torture_assert(tctx
,
8926 connect_printer_driver_share(tctx
, server_name
, share_name
, &cli
),
8927 "failed to connect to driver share");
8929 torture_comment(tctx
, "Removing printer driver files from \\\\%s\\%s\n",
8930 server_name
, share_name
);
8932 torture_assert(tctx
,
8933 remove_printer_driver_file(tctx
, cli
, d
, d
->info8
.driver_path
),
8934 "failed to remove driver_path");
8935 torture_assert(tctx
,
8936 remove_printer_driver_file(tctx
, cli
, d
, d
->info8
.data_file
),
8937 "failed to remove data_file");
8938 if (!strequal(d
->info8
.config_file
, d
->info8
.driver_path
)) {
8939 torture_assert(tctx
,
8940 remove_printer_driver_file(tctx
, cli
, d
, d
->info8
.config_file
),
8941 "failed to remove config_file");
8943 torture_assert(tctx
,
8944 remove_printer_driver_file(tctx
, cli
, d
, d
->info8
.help_file
),
8945 "failed to remove help_file");
8946 if (d
->info8
.dependent_files
) {
8947 for (i
=0; d
->info8
.dependent_files
->string
&& d
->info8
.dependent_files
->string
[i
] != NULL
; i
++) {
8948 if (strequal(d
->info8
.dependent_files
->string
[i
], d
->info8
.driver_path
) ||
8949 strequal(d
->info8
.dependent_files
->string
[i
], d
->info8
.data_file
) ||
8950 strequal(d
->info8
.dependent_files
->string
[i
], d
->info8
.config_file
) ||
8951 strequal(d
->info8
.dependent_files
->string
[i
], d
->info8
.help_file
)) {
8954 torture_assert(tctx
,
8955 remove_printer_driver_file(tctx
, cli
, d
, d
->info8
.dependent_files
->string
[i
]),
8956 "failed to remove dependent_files");
8966 static bool test_add_driver_arg(struct torture_context
*tctx
,
8967 struct dcerpc_pipe
*p
,
8968 struct torture_driver_context
*d
)
8971 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8972 const char *server_name_slash
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
8973 uint32_t levels
[] = { 1, 2, 3, 4, 6, 8 };
8975 struct spoolss_AddDriverInfo8 info8
;
8976 uint32_t add_flags
= APD_COPY_NEW_FILES
;
8977 uint32_t delete_flags
= 0;
8981 torture_comment(tctx
, "Testing PrinterDriver%s '%s' for environment '%s'\n",
8982 d
->ex
? "Ex" : "", d
->info8
.driver_name
, d
->local
.environment
);
8984 torture_assert(tctx
,
8985 fillup_printserver_info(tctx
, p
, d
),
8986 "failed to fillup printserver info");
8988 if (!directory_exist(d
->local
.driver_directory
)) {
8989 torture_skip(tctx
, "Skipping Printer Driver test as no local driver is available");
8992 torture_assert(tctx
,
8993 upload_printer_driver(tctx
, dcerpc_server_name(p
), d
),
8994 "failed to upload printer driver");
8996 info8
.version
= d
->info8
.version
;
8997 info8
.driver_name
= d
->info8
.driver_name
;
8998 info8
.architecture
= d
->local
.environment
;
8999 info8
.driver_path
= d
->info8
.driver_path
;
9000 info8
.data_file
= d
->info8
.data_file
;
9001 info8
.config_file
= d
->info8
.config_file
;
9003 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
9005 if (torture_setting_bool(tctx
, "samba3", false)) {
9006 switch (levels
[i
]) {
9010 torture_comment(tctx
, "skipping level %d against samba\n", levels
[i
]);
9016 if (torture_setting_bool(tctx
, "w2k3", false)) {
9017 switch (levels
[i
]) {
9019 torture_comment(tctx
, "skipping level %d against w2k3\n", levels
[i
]);
9026 torture_comment(tctx
,
9027 "Testing PrinterDriver%s '%s' add & delete level %d\n",
9028 d
->ex
? "Ex" : "", info8
.driver_name
, levels
[i
]);
9030 ret
&= test_PrinterDriver_args(tctx
, b
, server_name_slash
, levels
[i
], &info8
, add_flags
, delete_flags
, d
->info8
.version
, d
->ex
, d
->remote
.driver_directory
);
9033 info8
.driver_path
= talloc_asprintf(tctx
, "%s\\%s", d
->remote
.driver_directory
, d
->info8
.driver_path
);
9034 info8
.data_file
= talloc_asprintf(tctx
, "%s\\%s", d
->remote
.driver_directory
, d
->info8
.data_file
);
9035 if (d
->info8
.config_file
) {
9036 info8
.config_file
= talloc_asprintf(tctx
, "%s\\%s", d
->remote
.driver_directory
, d
->info8
.config_file
);
9039 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
9041 if (torture_setting_bool(tctx
, "samba3", false)) {
9042 switch (levels
[i
]) {
9046 torture_comment(tctx
, "skipping level %d against samba\n", levels
[i
]);
9052 if (torture_setting_bool(tctx
, "w2k3", false)) {
9053 switch (levels
[i
]) {
9055 torture_comment(tctx
, "skipping level %d against w2k3\n", levels
[i
]);
9062 torture_comment(tctx
,
9063 "Testing PrinterDriver%s '%s' add & delete level %d (full unc paths)\n",
9064 d
->ex
? "Ex" : "", info8
.driver_name
, levels
[i
]);
9066 ret
&= test_PrinterDriver_args(tctx
, b
, server_name_slash
, levels
[i
], &info8
, add_flags
, delete_flags
, d
->info8
.version
, d
->ex
, d
->remote
.driver_directory
);
9069 torture_assert(tctx
,
9070 remove_printer_driver(tctx
, dcerpc_server_name(p
), d
),
9071 "failed to remove printer driver");
9073 torture_comment(tctx
, "\n");
9078 static bool test_add_driver_ex_64(struct torture_context
*tctx
,
9079 struct dcerpc_pipe
*p
)
9081 struct torture_driver_context
*d
;
9083 d
= talloc_zero(tctx
, struct torture_driver_context
);
9085 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
9086 d
->info8
.driver_name
= TORTURE_DRIVER_EX
;
9087 d
->info8
.architecture
= NULL
;
9088 d
->info8
.driver_path
= talloc_strdup(d
, "pscript5.dll");
9089 d
->info8
.data_file
= talloc_strdup(d
, "cups6.ppd");
9090 d
->info8
.config_file
= talloc_strdup(d
, "cupsui6.dll");
9091 d
->local
.environment
= talloc_strdup(d
, "Windows x64");
9092 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/x64");
9095 return test_add_driver_arg(tctx
, p
, d
);
9098 static bool test_add_driver_ex_32(struct torture_context
*tctx
,
9099 struct dcerpc_pipe
*p
)
9101 struct torture_driver_context
*d
;
9103 d
= talloc_zero(tctx
, struct torture_driver_context
);
9105 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
9106 d
->info8
.driver_name
= TORTURE_DRIVER_EX
;
9107 d
->info8
.architecture
= NULL
;
9108 d
->info8
.driver_path
= talloc_strdup(d
, "pscript5.dll");
9109 d
->info8
.data_file
= talloc_strdup(d
, "cups6.ppd");
9110 d
->info8
.config_file
= talloc_strdup(d
, "cupsui6.dll");
9111 d
->local
.environment
= talloc_strdup(d
, "Windows NT x86");
9112 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/i386");
9115 return test_add_driver_arg(tctx
, p
, d
);
9118 static bool test_add_driver_64(struct torture_context
*tctx
,
9119 struct dcerpc_pipe
*p
)
9121 struct torture_driver_context
*d
;
9123 d
= talloc_zero(tctx
, struct torture_driver_context
);
9125 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
9126 d
->info8
.driver_name
= TORTURE_DRIVER
;
9127 d
->info8
.architecture
= NULL
;
9128 d
->info8
.driver_path
= talloc_strdup(d
, "pscript5.dll");
9129 d
->info8
.data_file
= talloc_strdup(d
, "cups6.ppd");
9130 d
->info8
.config_file
= talloc_strdup(d
, "cupsui6.dll");
9131 d
->local
.environment
= talloc_strdup(d
, "Windows x64");
9132 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/x64");
9135 return test_add_driver_arg(tctx
, p
, d
);
9138 static bool test_add_driver_32(struct torture_context
*tctx
,
9139 struct dcerpc_pipe
*p
)
9141 struct torture_driver_context
*d
;
9143 d
= talloc_zero(tctx
, struct torture_driver_context
);
9145 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
9146 d
->info8
.driver_name
= TORTURE_DRIVER
;
9147 d
->info8
.architecture
= NULL
;
9148 d
->info8
.driver_path
= talloc_strdup(d
, "pscript5.dll");
9149 d
->info8
.data_file
= talloc_strdup(d
, "cups6.ppd");
9150 d
->info8
.config_file
= talloc_strdup(d
, "cupsui6.dll");
9151 d
->local
.environment
= talloc_strdup(d
, "Windows NT x86");
9152 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/i386");
9155 return test_add_driver_arg(tctx
, p
, d
);
9158 static bool test_add_driver_adobe(struct torture_context
*tctx
,
9159 struct dcerpc_pipe
*p
)
9161 struct torture_driver_context
*d
;
9163 d
= talloc_zero(tctx
, struct torture_driver_context
);
9165 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_9X
;
9166 d
->info8
.driver_name
= TORTURE_DRIVER_ADOBE
;
9167 d
->info8
.architecture
= NULL
;
9168 d
->info8
.driver_path
= talloc_strdup(d
, "ADOBEPS4.DRV");
9169 d
->info8
.data_file
= talloc_strdup(d
, "DEFPRTR2.PPD");
9170 d
->info8
.config_file
= talloc_strdup(d
, "ADOBEPS4.DRV");
9172 d
->info8
.help_file
= talloc_strdup(d
, "ADOBEPS4.HLP");
9173 d
->info8
.monitor_name
= talloc_strdup(d
, "PSMON.DLL");
9175 d
->local
.environment
= talloc_strdup(d
, "Windows 4.0");
9176 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/adobe/");
9179 return test_add_driver_arg(tctx
, p
, d
);
9182 static bool test_add_driver_adobe_cupsaddsmb(struct torture_context
*tctx
,
9183 struct dcerpc_pipe
*p
)
9185 struct torture_driver_context
*d
;
9186 struct spoolss_StringArray
*a
;
9188 if (!torture_setting_bool(tctx
, "samba3", false)) {
9189 torture_skip(tctx
, "skipping cupsaddsmb test which only works against samba3");
9192 d
= talloc_zero(tctx
, struct torture_driver_context
);
9194 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_9X
;
9195 d
->info8
.driver_name
= TORTURE_DRIVER_ADOBE_CUPSADDSMB
;
9196 d
->info8
.architecture
= NULL
;
9197 d
->info8
.driver_path
= talloc_strdup(d
, "ADOBEPS4.DRV");
9198 d
->info8
.data_file
= talloc_strdup(d
, "DEFPRTR2.PPD");
9199 d
->info8
.config_file
= NULL
;
9200 d
->info8
.help_file
= talloc_strdup(d
, "ADOBEPS4.HLP");
9201 d
->info8
.monitor_name
= talloc_strdup(d
, "PSMON.DLL");
9202 d
->info8
.default_datatype
= talloc_strdup(d
, "RAW");
9204 a
= talloc_zero(d
, struct spoolss_StringArray
);
9205 a
->string
= talloc_zero_array(a
, const char *, 7);
9206 a
->string
[0] = talloc_strdup(a
->string
, "ADOBEPS4.DRV");
9207 a
->string
[1] = talloc_strdup(a
->string
, "DEFPRTR2.PPD");
9208 a
->string
[2] = talloc_strdup(a
->string
, "ADOBEPS4.HLP");
9209 a
->string
[3] = talloc_strdup(a
->string
, "PSMON.DLL");
9210 a
->string
[4] = talloc_strdup(a
->string
, "ADFONTS.MFM");
9211 a
->string
[5] = talloc_strdup(a
->string
, "ICONLIB.DLL");
9213 d
->info8
.dependent_files
= a
;
9214 d
->local
.environment
= talloc_strdup(d
, "Windows 4.0");
9215 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/adobe/");
9218 return test_add_driver_arg(tctx
, p
, d
);
9221 static bool test_add_driver_timestamps(struct torture_context
*tctx
,
9222 struct dcerpc_pipe
*p
)
9224 struct torture_driver_context
*d
;
9225 struct timeval t
= timeval_current();
9227 if (torture_setting_bool(tctx
, "samba3", false)) {
9228 torture_skip(tctx
, "skipping timestamps test against samba");
9231 d
= talloc_zero(tctx
, struct torture_driver_context
);
9233 d
->info8
.version
= SPOOLSS_DRIVER_VERSION_200X
;
9234 d
->info8
.driver_name
= TORTURE_DRIVER_TIMESTAMPS
;
9235 d
->info8
.architecture
= NULL
;
9236 d
->info8
.driver_path
= talloc_strdup(d
, "pscript5.dll");
9237 d
->info8
.data_file
= talloc_strdup(d
, "cups6.ppd");
9238 d
->info8
.config_file
= talloc_strdup(d
, "cupsui6.dll");
9239 d
->info8
.driver_date
= timeval_to_nttime(&t
);
9240 d
->local
.environment
= talloc_strdup(d
, "Windows NT x86");
9241 d
->local
.driver_directory
= talloc_strdup(d
, "/usr/share/cups/drivers/i386");
9244 torture_assert(tctx
,
9245 test_add_driver_arg(tctx
, p
, d
),
9248 unix_to_nt_time(&d
->info8
.driver_date
, 1);
9250 torture_assert(tctx
,
9251 test_add_driver_arg(tctx
, p
, d
),
9257 struct torture_suite
*torture_rpc_spoolss_driver(TALLOC_CTX
*mem_ctx
)
9259 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "spoolss.driver");
9261 struct torture_rpc_tcase
*tcase
= torture_suite_add_rpc_iface_tcase(suite
,
9262 "driver", &ndr_table_spoolss
);
9263 torture_rpc_tcase_add_test(tcase
, "add_driver_64", test_add_driver_64
);
9264 torture_rpc_tcase_add_test(tcase
, "add_driver_ex_64", test_add_driver_ex_64
);
9266 torture_rpc_tcase_add_test(tcase
, "add_driver_32", test_add_driver_32
);
9267 torture_rpc_tcase_add_test(tcase
, "add_driver_ex_32", test_add_driver_ex_32
);
9269 torture_rpc_tcase_add_test(tcase
, "add_driver_adobe", test_add_driver_adobe
);
9271 torture_rpc_tcase_add_test(tcase
, "add_driver_adobe_cupsaddsmb", test_add_driver_adobe_cupsaddsmb
);
9273 torture_rpc_tcase_add_test(tcase
, "add_driver_timestamps", test_add_driver_timestamps
);