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 test_binary("DriverDate", blob);
4746 test_binary("DriverVersion", blob);
4748 test_sz("DriverDate", driver_date);
4749 test_sz("DriverVersion", driver_version);
4751 test_sz("HardwareID", info.info6.hardware_id);
4752 test_sz("Help File", help_file);
4753 test_sz("Manufacturer", info.info6.manufacturer_name);
4754 test_sz("Monitor", info.info6.monitor_name);
4755 test_sz("OEM URL", info.info6.manufacturer_url);
4756 test_sz("Provider", info.info6.provider);
4757 test_multi_sz("Dependent Files", dependent_files);
4758 test_multi_sz("Previous Names", info.info6.previous_names);
4759 /* test_dword("Attributes", ?); */
4760 test_dword("Version", info.info6.version);
4761 /* test_dword("TempDir", ?); */
4766 torture_assert(tctx,
4767 test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 3, version, 0, &info, &result),
4768 "failed to get driver info level 3");
4770 torture_assert(tctx,
4771 test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 3, driver_name, &info),
4772 "failed to get driver info level 3");
4775 driver_path = strip_path(info.info3.driver_path);
4776 data_file = strip_path(info.info3.data_file);
4777 config_file = strip_path(info.info3.config_file);
4778 help_file = strip_path(info.info3.help_file);
4779 dependent_files = strip_paths(info.info3.dependent_files);
4781 test_sz("Configuration File", config_file);
4782 test_sz("Data File", data_file);
4783 test_sz("Datatype", info.info3.default_datatype);
4784 test_sz("Driver", driver_path);
4785 test_sz("Help File", help_file);
4786 test_sz("Monitor", info.info3.monitor_name);
4787 test_multi_sz("Dependent Files", dependent_files);
4788 /* test_dword("Attributes", ?); */
4789 test_dword("Version", info.info3.version);
4790 /* test_dword("TempDir", ?); */
4793 torture_assert(tctx,
4794 test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
4796 torture_comment(tctx, "Driver Info and winreg consistency test succeeded\n\n");
4804 static bool test_SetPrinterData(struct torture_context *tctx,
4805 struct dcerpc_binding_handle *b,
4806 struct policy_handle *handle,
4807 const char *value_name,
4808 enum winreg_Type type,
4812 struct spoolss_SetPrinterData r;
4814 r.in.handle = handle;
4815 r.in.value_name = value_name;
4818 r.in.offered = offered;
4820 torture_comment(tctx, "Testing SetPrinterData(%s)\n",
4823 torture_assert_ntstatus_ok(tctx,
4824 dcerpc_spoolss_SetPrinterData_r(b, tctx, &r),
4825 "SetPrinterData failed");
4826 torture_assert_werr_ok(tctx, r.out.result,
4827 "SetPrinterData failed");
4832 static bool test_SetPrinterData_matrix(struct torture_context *tctx,
4833 struct dcerpc_binding_handle *b,
4834 struct policy_handle *handle,
4835 const char *printer_name,
4836 struct dcerpc_binding_handle *winreg_handle,
4837 struct policy_handle *hive_handle)
4839 const char *values[] = {
4843 /* FIXME: not working with s3 atm. */
4849 /* FIXME: not working with s3 atm. */
4856 for (i=0; i < ARRAY_SIZE(values); i++) {
4858 enum winreg_Type type, expected_type = REG_SZ;
4863 torture_assert(tctx, push_reg_sz(tctx, &blob, "dog"), "");
4866 torture_assert(tctx,
4867 test_SetPrinterData(tctx, b, handle, values[i], REG_SZ, blob.data, blob.length),
4868 "SetPrinterData failed");
4870 torture_assert(tctx,
4871 test_GetPrinterData_checktype(tctx, b, handle, values[i], &expected_type, &type, &data, &needed),
4872 "GetPrinterData failed");
4874 torture_assert_int_equal(tctx, type, REG_SZ, "type mismatch");
4875 torture_assert_int_equal(tctx, needed, blob.length, "size mismatch");
4876 torture_assert_mem_equal(tctx, data, blob.data, blob.length, "buffer mismatch");
4878 if (winreg_handle && hive_handle) {
4880 enum winreg_Type w_type;
4885 torture_assert(tctx,
4886 test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
4887 printer_name, "PrinterDriverData", values[i],
4888 &w_type, &w_size, &w_length, &w_data), "");
4890 torture_assert_int_equal(tctx, w_type, REG_SZ, "winreg type mismatch");
4891 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
4892 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
4893 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
4896 torture_assert(tctx,
4897 test_DeletePrinterData(tctx, b, handle, values[i]),
4898 "DeletePrinterData failed");
4905 static bool test_EnumPrinterKey(struct torture_context *tctx,
4906 struct dcerpc_binding_handle *b,
4907 struct policy_handle *handle,
4908 const char *key_name,
4909 const char ***array);
4911 static bool test_SetPrinterDataEx(struct torture_context *tctx,
4912 struct dcerpc_binding_handle *b,
4913 struct policy_handle *handle,
4914 const char *key_name,
4915 const char *value_name,
4916 enum winreg_Type type,
4921 struct spoolss_SetPrinterDataEx r;
4923 r.in.handle = handle;
4924 r.in.key_name = key_name;
4925 r.in.value_name = value_name;
4928 r.in.offered = offered;
4930 torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s) type: %s, offered: 0x%08x\n",
4931 r.in.key_name, r.in.value_name, str_regtype(r.in.type), r.in.offered);
4933 status = dcerpc_spoolss_SetPrinterDataEx_r(b, tctx, &r);
4935 torture_assert_ntstatus_ok(tctx, status, "SetPrinterDataEx failed");
4936 torture_assert_werr_ok(tctx, r.out.result, "SetPrinterDataEx failed");
4941 static bool test_SetPrinterDataEx_keys(struct torture_context *tctx,
4942 struct dcerpc_pipe *p,
4943 struct policy_handle *handle)
4945 struct dcerpc_binding_handle *b = p->binding_handle;
4946 const char *value_name = "dog";
4947 const char *keys[] = {
4950 "torturedataex_with_subkey\\subkey",
4951 "torturedataex_with_subkey\\subkey:0",
4952 "torturedataex_with_subkey\\subkey:1",
4953 "torturedataex_with_subkey\\subkey\\subsubkey",
4954 "torturedataex_with_subkey\\subkey\\subsubkey:0",
4955 "torturedataex_with_subkey\\subkey\\subsubkey:1",
4962 "torture/data ex/sub",
4965 "torture//data ex/sub",
4966 "torture//data ex//sub",
4970 for (i=0; i < ARRAY_SIZE(keys); i++) {
4974 enum winreg_Type type;
4975 DATA_BLOB blob_in, blob_out;
4976 const char **subkeys;
4978 struct spoolss_PrinterEnumValues *einfo;
4981 blob_in = data_blob_talloc(tctx, NULL, 42);
4983 generate_random_buffer(blob_in.data, blob_in.length);
4985 torture_assert(tctx,
4986 test_SetPrinterDataEx(tctx, b, handle, keys[i], value_name, REG_BINARY, blob_in.data, blob_in.length),
4987 "failed to call SetPrinterDataEx");
4989 torture_assert(tctx,
4990 test_GetPrinterDataEx(tctx, p, handle, keys[i], value_name, &type, &blob_out.data, &needed),
4991 "failed to call GetPrinterDataEx");
4993 blob_out.length = needed;
4994 torture_assert(tctx,
4995 test_EnumPrinterDataEx(tctx, b, handle, keys[i], &ecount, &einfo),
4996 "failed to call EnumPrinterDataEx");
4998 torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
4999 torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5000 torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5002 torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5003 torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5004 torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5005 torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5006 torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5007 if (einfo[0].data_length > 0) {
5008 torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5011 key = talloc_strdup(tctx, keys[i]);
5013 if (!test_DeletePrinterDataEx(tctx, b, handle, keys[i], value_name)) {
5017 c = strchr(key, '\\');
5021 /* we have subkeys */
5025 if (!test_EnumPrinterKey(tctx, b, handle, key, &subkeys)) {
5029 for (k=0; subkeys && subkeys[k]; k++) {
5031 const char *current_key = talloc_asprintf(tctx, "%s\\%s", key, subkeys[k]);
5033 if (!test_DeletePrinterKey(tctx, b, handle, current_key)) {
5038 if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5043 if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5052 static bool test_SetPrinterDataEx_values(struct torture_context *tctx,
5053 struct dcerpc_pipe *p,
5054 struct policy_handle *handle)
5056 struct dcerpc_binding_handle *b = p->binding_handle;
5057 const char *key = "torturedataex";
5058 const char *values[] = {
5068 for (i=0; i < ARRAY_SIZE(values); i++) {
5070 enum winreg_Type type;
5071 DATA_BLOB blob_in, blob_out;
5073 struct spoolss_PrinterEnumValues *einfo;
5076 if (torture_setting_bool(tctx, "samba3", false)) {
5078 q = strrchr(values[i], ',');
5080 torture_comment(tctx, "skipping valuename '%s' including ',' character against Samba3\n",
5086 blob_in = data_blob_talloc(tctx, NULL, 42);
5088 generate_random_buffer(blob_in.data, blob_in.length);
5090 torture_assert(tctx,
5091 test_SetPrinterDataEx(tctx, b, handle, key, values[i], REG_BINARY, blob_in.data, blob_in.length),
5092 "failed to call SetPrinterDataEx");
5094 torture_assert(tctx,
5095 test_GetPrinterDataEx(tctx, p, handle, key, values[i], &type, &blob_out.data, &needed),
5096 "failed to call GetPrinterDataEx");
5098 blob_out.length = needed;
5099 torture_assert(tctx,
5100 test_EnumPrinterDataEx(tctx, b, handle, key, &ecount, &einfo),
5101 "failed to call EnumPrinterDataEx");
5103 torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
5104 torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5105 torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5107 torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5108 torture_assert_str_equal(tctx, einfo[0].value_name, values[i], "value_name mismatch");
5109 torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(values[i])*2, "unexpected value_name_len");
5110 torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5111 torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5112 if (einfo[0].data_length > 0) {
5113 torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5116 torture_assert(tctx,
5117 test_DeletePrinterDataEx(tctx, b, handle, key, values[i]),
5118 "failed to call DeletePrinterDataEx");
5125 static bool test_SetPrinterDataEx_matrix(struct torture_context *tctx,
5126 struct dcerpc_pipe *p,
5127 struct policy_handle *handle,
5128 const char *printername,
5129 struct dcerpc_binding_handle *winreg_handle,
5130 struct policy_handle *hive_handle)
5132 struct dcerpc_binding_handle *b = p->binding_handle;
5133 const char *value_name = "dog";
5134 const char *key_name = "torturedataex";
5135 enum winreg_Type types[] = {
5141 const char *str = "abcdefghi";
5144 for (t=0; t < ARRAY_SIZE(types); t++) {
5145 for (s=0; s < strlen(str); s++) {
5147 enum winreg_Type type;
5148 const char *string = talloc_strndup(tctx, str, s);
5149 const char *array[2];
5150 DATA_BLOB blob = data_blob_string_const(string);
5153 uint32_t needed, offered = 0;
5155 struct spoolss_PrinterEnumValues *einfo;
5157 array[0] = talloc_strdup(tctx, string);
5160 if (types[t] == REG_DWORD) {
5167 offered = blob.length;
5170 data = data_blob_talloc(tctx, NULL, 4);
5171 SIVAL(data.data, 0, 0x12345678);
5175 torture_assert(tctx, push_reg_sz(tctx, &data, string), "");
5177 offered = data.length;
5178 /*strlen_m_term(data.string)*2;*/
5181 torture_assert(tctx, push_reg_multi_sz(tctx, &data, array), "");
5182 type = REG_MULTI_SZ;
5183 offered = data.length;
5186 torture_fail(tctx, talloc_asprintf(tctx, "type %d untested\n", types[t]));
5189 torture_assert(tctx,
5190 test_SetPrinterDataEx(tctx, b, handle, key_name, value_name, types[t], data.data, offered),
5191 "failed to call SetPrinterDataEx");
5193 torture_assert(tctx,
5194 test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name, &types[t], &type, &data_out, &needed),
5195 "failed to call GetPrinterDataEx");
5197 torture_assert(tctx,
5198 test_EnumPrinterDataEx(tctx, b, handle, key_name, &ecount, &einfo),
5199 "failed to call EnumPrinterDataEx");
5201 torture_assert_int_equal(tctx, types[t], type, "type mismatch");
5202 torture_assert_int_equal(tctx, needed, offered, "size mismatch");
5203 torture_assert_mem_equal(tctx, data_out, data.data, offered, "buffer mismatch");
5205 torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5206 torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5207 torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5208 torture_assert_int_equal(tctx, einfo[0].type, types[t], "type mismatch");
5209 torture_assert_int_equal(tctx, einfo[0].data_length, offered, "size mismatch");
5210 if (einfo[0].data_length > 0) {
5211 torture_assert_mem_equal(tctx, einfo[0].data->data, data.data, offered, "buffer mismatch");
5214 if (winreg_handle && hive_handle) {
5215 enum winreg_Type w_type;
5220 torture_assert(tctx,
5221 test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
5222 printername, key_name, value_name,
5223 &w_type, &w_size, &w_length, &w_data), "");
5225 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
5226 torture_assert_int_equal(tctx, w_size, offered, "winreg size mismatch");
5227 torture_assert_int_equal(tctx, w_length, offered, "winreg length mismatch");
5228 torture_assert_mem_equal(tctx, w_data, data.data, offered, "winreg buffer mismatch");
5231 torture_assert(tctx,
5232 test_DeletePrinterDataEx(tctx, b, handle, key_name, value_name),
5233 "failed to call DeletePrinterDataEx");
5240 static bool test_PrinterData_winreg(struct torture_context *tctx,
5241 struct dcerpc_pipe *p,
5242 struct policy_handle *handle,
5243 const char *printer_name)
5245 struct dcerpc_binding_handle *b = p->binding_handle;
5246 struct dcerpc_pipe *p2;
5248 struct policy_handle hive_handle;
5249 struct dcerpc_binding_handle *b2;
5251 torture_assert_ntstatus_ok(tctx,
5252 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5253 "could not open winreg pipe");
5254 b2 = p2->binding_handle;
5256 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5258 ret &= test_SetPrinterData_matrix(tctx, b, handle, printer_name, b2, &hive_handle);
5259 ret &= test_SetPrinterDataEx_matrix(tctx, p, handle, printer_name, b2, &hive_handle);
5261 test_winreg_CloseKey(tctx, b2, &hive_handle);
5268 static bool test_Forms_winreg(struct torture_context *tctx,
5269 struct dcerpc_binding_handle *b,
5270 struct policy_handle *handle,
5272 const char *printer_name)
5274 struct dcerpc_pipe *p2;
5276 struct policy_handle hive_handle;
5277 struct dcerpc_binding_handle *b2;
5279 torture_assert_ntstatus_ok(tctx,
5280 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5281 "could not open winreg pipe");
5282 b2 = p2->binding_handle;
5284 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5286 ret = test_Forms(tctx, b, handle, print_server, printer_name, b2, &hive_handle);
5288 test_winreg_CloseKey(tctx, b2, &hive_handle);
5295 static bool test_PrinterInfo_winreg(struct torture_context *tctx,
5296 struct dcerpc_pipe *p,
5297 struct policy_handle *handle,
5298 const char *printer_name)
5300 struct dcerpc_binding_handle *b = p->binding_handle;
5301 struct dcerpc_pipe *p2;
5303 struct policy_handle hive_handle;
5304 struct dcerpc_binding_handle *b2;
5306 torture_assert_ntstatus_ok(tctx,
5307 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5308 "could not open winreg pipe");
5309 b2 = p2->binding_handle;
5311 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5313 ret = test_GetPrinterInfo_winreg(tctx, b, handle, printer_name, b2, &hive_handle);
5315 test_winreg_CloseKey(tctx, b2, &hive_handle);
5322 static bool test_DriverInfo_winreg(struct torture_context *tctx,
5323 struct dcerpc_pipe *p,
5324 struct policy_handle *handle,
5325 const char *printer_name,
5326 const char *driver_name,
5327 const char *environment,
5328 enum spoolss_DriverOSVersion version)
5330 struct dcerpc_binding_handle *b = p->binding_handle;
5331 struct dcerpc_pipe *p2;
5333 struct policy_handle hive_handle;
5334 struct dcerpc_binding_handle *b2;
5336 torture_assert_ntstatus_ok(tctx,
5337 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5338 "could not open winreg pipe");
5339 b2 = p2->binding_handle;
5341 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5343 ret = test_GetDriverInfo_winreg(tctx, b, handle, printer_name, driver_name, environment, version, b2, &hive_handle, NULL);
5345 test_winreg_CloseKey(tctx, b2, &hive_handle);
5352 static bool test_PrintProcessors_winreg(struct torture_context *tctx,
5353 struct dcerpc_binding_handle *b,
5354 const char *environment)
5356 struct dcerpc_pipe *p2;
5358 struct policy_handle hive_handle;
5359 struct dcerpc_binding_handle *b2;
5361 torture_assert_ntstatus_ok(tctx,
5362 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5363 "could not open winreg pipe");
5364 b2 = p2->binding_handle;
5366 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5368 ret = test_PrintProcessors(tctx, b, environment, b2, &hive_handle);
5370 test_winreg_CloseKey(tctx, b2, &hive_handle);
5377 static bool test_PrinterData_DsSpooler(struct torture_context *tctx,
5378 struct dcerpc_pipe *p,
5379 struct policy_handle *handle,
5380 const char *printer_name)
5382 struct spoolss_SetPrinterInfoCtr info_ctr;
5383 struct spoolss_DevmodeContainer devmode_ctr;
5384 struct sec_desc_buf secdesc_ctr;
5385 union spoolss_SetPrinterInfo sinfo;
5386 union spoolss_PrinterInfo info;
5387 struct dcerpc_binding_handle *b = p->binding_handle;
5390 ZERO_STRUCT(info_ctr);
5391 ZERO_STRUCT(devmode_ctr);
5392 ZERO_STRUCT(secdesc_ctr);
5394 torture_comment(tctx, "Testing DsSpooler <-> SetPrinter relations\n");
5396 torture_assert(tctx,
5397 test_GetPrinter_level(tctx, b, handle, 2, &info),
5398 "failed to query Printer level 2");
5400 torture_assert(tctx,
5401 PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo),
5402 "failed to convert");
5405 info_ctr.info = sinfo;
5407 #define TEST_SZ(wname, iname) \
5409 enum winreg_Type type;\
5414 torture_assert(tctx,\
5415 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5416 "failed to query");\
5417 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5418 blob = data_blob_const(data, needed);\
5419 torture_assert(tctx,\
5420 pull_reg_sz(tctx, &blob, &str),\
5421 "failed to pull REG_SZ");\
5422 torture_assert_str_equal(tctx, str, iname, "unexpected result");\
5426 #define TEST_SET_SZ(wname, iname, val) \
5428 enum winreg_Type type;\
5433 sinfo.info2->iname = val;\
5434 torture_assert(tctx,\
5435 test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5436 "failed to call SetPrinter");\
5437 torture_assert(tctx,\
5438 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5439 "failed to query");\
5440 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5441 blob = data_blob_const(data, needed);\
5442 torture_assert(tctx,\
5443 pull_reg_sz(tctx, &blob, &str),\
5444 "failed to pull REG_SZ");\
5445 torture_assert_str_equal(tctx, str, val, "unexpected result");\
5448 #define TEST_SET_DWORD(wname, iname, val) \
5450 enum winreg_Type type;\
5454 sinfo.info2->iname = val;\
5455 torture_assert(tctx,\
5456 test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5457 "failed to call SetPrinter");\
5458 torture_assert(tctx,\
5459 test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5460 "failed to query");\
5461 torture_assert_int_equal(tctx, type, REG_DWORD, "unexpected type");\
5462 torture_assert_int_equal(tctx, needed, 4, "unexpected length");\
5463 value = IVAL(data, 0); \
5464 torture_assert_int_equal(tctx, value, val, "unexpected result");\
5467 TEST_SET_SZ("description", comment, "newval");
5468 TEST_SET_SZ("location", location, "newval");
5469 /* TEST_SET_DWORD("priority", priority, 25); */
5471 torture_assert(tctx,
5472 test_GetPrinter_level(tctx, b, handle, 2, &info),
5473 "failed to query Printer level 2");
5475 TEST_SZ("description", info.info2.comment);
5476 TEST_SZ("driverName", info.info2.drivername);
5477 TEST_SZ("location", info.info2.location);
5479 pname = strrchr(info.info2.printername, '\\');
5480 if (pname == NULL) {
5481 pname = info.info2.printername;
5485 TEST_SZ("printerName", pname);
5486 /* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
5487 /* TEST_SZ("printShareName", info.info2.sharename); */
5489 /* FIXME gd: complete the list */
5495 torture_comment(tctx, "DsSpooler <-> SetPrinter relations test succeeded\n\n");
5500 static bool test_print_processors_winreg(struct torture_context *tctx,
5503 struct test_spoolss_context *ctx =
5504 talloc_get_type_abort(private_data, struct test_spoolss_context);
5505 struct dcerpc_pipe *p = ctx->spoolss_pipe;
5506 struct dcerpc_binding_handle *b = p->binding_handle;
5508 return test_PrintProcessors_winreg(tctx, b, ctx->environment);
5511 static bool test_GetChangeID_PrinterData(struct torture_context *tctx,
5512 struct dcerpc_binding_handle *b,
5513 struct policy_handle *handle,
5514 uint32_t *change_id)
5516 enum winreg_Type type;
5520 torture_assert(tctx,
5521 test_GetPrinterData(tctx, b, handle, "ChangeID", &type, &data, &needed),
5522 "failed to call GetPrinterData");
5524 torture_assert(tctx, type == REG_DWORD, "unexpected type");
5525 torture_assert_int_equal(tctx, needed, 4, "unexpected size");
5527 *change_id = IVAL(data, 0);
5532 static bool test_GetChangeID_PrinterDataEx(struct torture_context *tctx,
5533 struct dcerpc_pipe *p,
5534 struct policy_handle *handle,
5535 uint32_t *change_id)
5537 enum winreg_Type type;
5541 torture_assert(tctx,
5542 test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", "ChangeID", &type, &data, &needed),
5543 "failed to call GetPrinterData");
5545 torture_assert(tctx, type == REG_DWORD, "unexpected type");
5546 torture_assert_int_equal(tctx, needed, 4, "unexpected size");
5548 *change_id = IVAL(data, 0);
5553 static bool test_GetChangeID_PrinterInfo(struct torture_context *tctx,
5554 struct dcerpc_binding_handle *b,
5555 struct policy_handle *handle,
5556 uint32_t *change_id)
5558 union spoolss_PrinterInfo info;
5560 torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 0, &info),
5561 "failed to query Printer level 0");
5563 *change_id = info.info0.change_id;
5568 static bool test_ChangeID(struct torture_context *tctx,
5569 struct dcerpc_pipe *p,
5570 struct policy_handle *handle)
5572 uint32_t change_id, change_id_ex, change_id_info;
5573 uint32_t change_id2, change_id_ex2, change_id_info2;
5574 union spoolss_PrinterInfo info;
5575 const char *comment;
5576 struct dcerpc_binding_handle *b = p->binding_handle;
5578 torture_comment(tctx, "Testing ChangeID: id change test #1\n");
5580 torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
5581 "failed to query for ChangeID");
5582 torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
5583 "failed to query for ChangeID");
5584 torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
5585 "failed to query for ChangeID");
5587 torture_assert_int_equal(tctx, change_id, change_id_ex,
5588 "change_ids should all be equal");
5589 torture_assert_int_equal(tctx, change_id_ex, change_id_info,
5590 "change_ids should all be equal");
5593 torture_comment(tctx, "Testing ChangeID: id change test #2\n");
5595 torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
5596 "failed to query for ChangeID");
5597 torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
5598 "failed to query Printer level 2");
5599 torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
5600 "failed to query for ChangeID");
5601 torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
5602 "failed to query for ChangeID");
5603 torture_assert_int_equal(tctx, change_id, change_id_ex,
5604 "change_id should not have changed");
5605 torture_assert_int_equal(tctx, change_id_ex, change_id_info,
5606 "change_id should not have changed");
5609 torture_comment(tctx, "Testing ChangeID: id change test #3\n");
5611 torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
5612 "failed to query for ChangeID");
5613 torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
5614 "failed to query for ChangeID");
5615 torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
5616 "failed to query for ChangeID");
5617 torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
5618 "failed to query Printer level 2");
5619 comment = talloc_strdup(tctx, info.info2.comment);
5622 struct spoolss_SetPrinterInfoCtr info_ctr;
5623 struct spoolss_DevmodeContainer devmode_ctr;
5624 struct sec_desc_buf secdesc_ctr;
5625 union spoolss_SetPrinterInfo sinfo;
5627 ZERO_STRUCT(info_ctr);
5628 ZERO_STRUCT(devmode_ctr);
5629 ZERO_STRUCT(secdesc_ctr);
5632 torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
5633 sinfo.info2->comment = "torture_comment";
5636 info_ctr.info = sinfo;
5638 torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
5639 "failed to call SetPrinter");
5641 sinfo.info2->comment = comment;
5643 torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
5644 "failed to call SetPrinter");
5648 torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id2),
5649 "failed to query for ChangeID");
5650 torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex2),
5651 "failed to query for ChangeID");
5652 torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info2),
5653 "failed to query for ChangeID");
5655 torture_assert_int_equal(tctx, change_id2, change_id_ex2,
5656 "change_ids should all be equal");
5657 torture_assert_int_equal(tctx, change_id_ex2, change_id_info2,
5658 "change_ids should all be equal");
5660 torture_assert(tctx, (change_id < change_id2),
5661 talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
5662 change_id2, change_id));
5663 torture_assert(tctx, (change_id_ex < change_id_ex2),
5664 talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
5665 change_id_ex2, change_id_ex));
5666 torture_assert(tctx, (change_id_info < change_id_info2),
5667 talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
5668 change_id_info2, change_id_info));
5670 torture_comment(tctx, "ChangeID tests succeeded\n\n");
5675 static bool test_SecondaryClosePrinter(struct torture_context *tctx,
5676 struct dcerpc_pipe *p,
5677 struct policy_handle *handle)
5680 struct dcerpc_binding *b;
5681 struct dcerpc_pipe *p2;
5682 struct spoolss_ClosePrinter cp;
5684 /* only makes sense on SMB */
5685 if (p->conn->transport.transport != NCACN_NP) {
5689 torture_comment(tctx, "Testing close on secondary pipe\n");
5691 status = dcerpc_parse_binding(tctx, p->conn->binding_string, &b);
5692 torture_assert_ntstatus_ok(tctx, status, "Failed to parse dcerpc binding");
5694 status = dcerpc_secondary_connection(p, &p2, b);
5695 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5697 status = dcerpc_bind_auth_none(p2, &ndr_table_spoolss);
5698 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
5700 cp.in.handle = handle;
5701 cp.out.handle = handle;
5703 status = dcerpc_spoolss_ClosePrinter_r(p2->binding_handle, tctx, &cp);
5704 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
5705 "ERROR: Allowed close on secondary connection");
5712 static bool test_OpenPrinter_badname(struct torture_context *tctx,
5713 struct dcerpc_binding_handle *b, const char *name)
5716 struct spoolss_OpenPrinter op;
5717 struct spoolss_OpenPrinterEx opEx;
5718 struct policy_handle handle;
5721 op.in.printername = name;
5722 op.in.datatype = NULL;
5723 op.in.devmode_ctr.devmode= NULL;
5724 op.in.access_mask = 0;
5725 op.out.handle = &handle;
5727 torture_comment(tctx, "Testing OpenPrinter(%s) with bad name\n", op.in.printername);
5729 status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &op);
5730 torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
5731 torture_assert_werr_equal(tctx, op.out.result, WERR_INVALID_PRINTER_NAME,
5732 "unexpected result");
5734 if (W_ERROR_IS_OK(op.out.result)) {
5735 ret &=test_ClosePrinter(tctx, b, &handle);
5738 opEx.in.printername = name;
5739 opEx.in.datatype = NULL;
5740 opEx.in.devmode_ctr.devmode = NULL;
5741 opEx.in.access_mask = 0;
5743 opEx.in.userlevel.level1 = NULL;
5744 opEx.out.handle = &handle;
5746 torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
5748 status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &opEx);
5749 torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
5750 torture_assert_werr_equal(tctx, opEx.out.result, WERR_INVALID_PARAM,
5751 "unexpected result");
5753 if (W_ERROR_IS_OK(opEx.out.result)) {
5754 ret &=test_ClosePrinter(tctx, b, &handle);
5760 static bool test_OpenPrinter_badname_list(struct torture_context *tctx,
5763 struct test_spoolss_context *ctx =
5764 talloc_get_type_abort(private_data, struct test_spoolss_context);
5766 const char *badnames[] = {
5767 "__INVALID_PRINTER__",
5768 "\\\\__INVALID_HOST__",
5771 "\\\\\\__INVALID_PRINTER__"
5773 const char *badname;
5774 struct dcerpc_pipe *p = ctx->spoolss_pipe;
5775 const char *server_name = dcerpc_server_name(p);
5776 struct dcerpc_binding_handle *b = p->binding_handle;
5779 for (i=0; i < ARRAY_SIZE(badnames); i++) {
5780 torture_assert(tctx,
5781 test_OpenPrinter_badname(tctx, b, badnames[i]),
5785 badname = talloc_asprintf(tctx, "\\\\%s\\", server_name);
5786 torture_assert(tctx,
5787 test_OpenPrinter_badname(tctx, b, badname),
5790 badname = talloc_asprintf(tctx, "\\\\%s\\__INVALID_PRINTER__", server_name);
5791 torture_assert(tctx,
5792 test_OpenPrinter_badname(tctx, b, badname),
5798 static bool test_OpenPrinter(struct torture_context *tctx,
5799 struct dcerpc_pipe *p,
5801 const char *environment,
5805 struct spoolss_OpenPrinter r;
5806 struct policy_handle handle;
5808 struct dcerpc_binding_handle *b = p->binding_handle;
5810 r.in.printername = name;
5811 r.in.datatype = NULL;
5812 r.in.devmode_ctr.devmode= NULL;
5813 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5814 r.out.handle = &handle;
5816 torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
5818 status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &r);
5820 torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
5822 torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
5828 if (!test_GetPrinter(tctx, b, &handle, environment)) {
5832 if (!torture_setting_bool(tctx, "samba3", false)) {
5833 if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
5839 if (!test_ClosePrinter(tctx, b, &handle)) {
5846 static bool test_OpenPrinterEx(struct torture_context *tctx,
5847 struct dcerpc_binding_handle *b,
5848 const char *printername,
5849 const char *datatype,
5850 struct spoolss_DeviceMode *devmode,
5851 uint32_t access_mask,
5853 union spoolss_UserLevel *userlevel,
5854 struct policy_handle *handle,
5855 WERROR expected_result)
5857 struct spoolss_OpenPrinterEx r;
5859 r.in.printername = printername;
5860 r.in.datatype = datatype;
5861 r.in.devmode_ctr.devmode= devmode;
5862 r.in.access_mask = access_mask;
5864 r.in.userlevel = *userlevel;
5865 r.out.handle = handle;
5867 torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
5869 torture_assert_ntstatus_ok(tctx,
5870 dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
5871 "OpenPrinterEx failed");
5873 torture_assert_werr_equal(tctx, r.out.result, expected_result,
5874 "OpenPrinterEx failed");
5879 static bool call_OpenPrinterEx(struct torture_context *tctx,
5880 struct dcerpc_pipe *p,
5882 struct spoolss_DeviceMode *devmode,
5883 struct policy_handle *handle)
5885 union spoolss_UserLevel userlevel;
5886 struct spoolss_UserLevel1 userlevel1;
5887 struct dcerpc_binding_handle *b = p->binding_handle;
5889 userlevel1.size = 1234;
5890 userlevel1.client = "hello";
5891 userlevel1.user = "spottyfoot!";
5892 userlevel1.build = 1;
5893 userlevel1.major = 2;
5894 userlevel1.minor = 3;
5895 userlevel1.processor = 4;
5897 userlevel.level1 = &userlevel1;
5899 return test_OpenPrinterEx(tctx, b, name, NULL, devmode,
5900 SEC_FLAG_MAXIMUM_ALLOWED,
5907 static bool test_printer_rename(struct torture_context *tctx,
5910 struct torture_printer_context *t =
5911 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
5912 struct dcerpc_pipe *p = t->spoolss_pipe;
5915 union spoolss_PrinterInfo info;
5916 union spoolss_SetPrinterInfo sinfo;
5917 struct spoolss_SetPrinterInfoCtr info_ctr;
5918 struct spoolss_DevmodeContainer devmode_ctr;
5919 struct sec_desc_buf secdesc_ctr;
5920 const char *printer_name;
5921 const char *printer_name_orig;
5922 const char *printer_name_new = "SAMBA smbtorture Test Printer (Copy 2)";
5923 struct policy_handle new_handle;
5925 struct dcerpc_binding_handle *b = p->binding_handle;
5927 ZERO_STRUCT(devmode_ctr);
5928 ZERO_STRUCT(secdesc_ctr);
5930 torture_comment(tctx, "Testing Printer rename operations\n");
5932 torture_assert(tctx,
5933 test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
5934 "failed to call GetPrinter level 2");
5936 printer_name_orig = talloc_strdup(tctx, info.info2.printername);
5938 q = strrchr(info.info2.printername, '\\');
5940 torture_warning(tctx,
5941 "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
5944 torture_assert(tctx,
5945 PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
5947 sinfo.info2->printername = printer_name_new;
5950 info_ctr.info = sinfo;
5952 torture_assert(tctx,
5953 test_SetPrinter(tctx, b, &t->handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
5954 "failed to call SetPrinter level 2");
5956 torture_assert(tctx,
5957 test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
5958 "failed to call GetPrinter level 2");
5960 printer_name = talloc_strdup(tctx, info.info2.printername);
5962 q = strrchr(info.info2.printername, '\\');
5964 torture_warning(tctx,
5965 "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
5970 torture_assert_str_equal(tctx, printer_name, printer_name_new,
5971 "new printer name was not set");
5973 /* samba currently cannot fully rename printers */
5974 if (!torture_setting_bool(tctx, "samba3", false)) {
5975 torture_assert(tctx,
5976 test_OpenPrinter_badname(tctx, b, printer_name_orig),
5977 "still can open printer with oldname after rename");
5979 torture_warning(tctx, "*not* checking for open with oldname after rename for samba3");
5982 torture_assert(tctx,
5983 call_OpenPrinterEx(tctx, p, printer_name_new, NULL, &new_handle),
5984 "failed to open printer with new name");
5986 torture_assert(tctx,
5987 test_GetPrinter_level(tctx, b, &new_handle, 2, &info),
5988 "failed to call GetPrinter level 2");
5990 torture_assert_str_equal(tctx, info.info2.printername, printer_name_new,
5991 "new printer name was not set");
5993 torture_assert(tctx,
5994 test_ClosePrinter(tctx, b, &new_handle),
5995 "failed to close printer");
5997 torture_comment(tctx, "Printer rename operations test succeeded\n\n");
6002 static bool test_openprinter(struct torture_context *tctx,
6003 struct dcerpc_binding_handle *b,
6004 const char *real_printername)
6006 union spoolss_UserLevel userlevel;
6007 struct policy_handle handle;
6008 struct spoolss_UserLevel1 userlevel1;
6009 const char *printername = NULL;
6014 WERROR expected_result;
6017 .suffix = "rubbish",
6018 .expected_result = WERR_INVALID_PRINTER_NAME
6020 .suffix = ", LocalOnl",
6021 .expected_result = WERR_INVALID_PRINTER_NAME
6023 .suffix = ", localOnly",
6024 .expected_result = WERR_INVALID_PRINTER_NAME
6026 .suffix = ", localonl",
6027 .expected_result = WERR_INVALID_PRINTER_NAME
6029 .suffix = ",LocalOnl",
6030 .expected_result = WERR_INVALID_PRINTER_NAME
6032 .suffix = ",localOnl2",
6033 .expected_result = WERR_INVALID_PRINTER_NAME
6035 .suffix = ", DrvConver2t",
6036 .expected_result = WERR_INVALID_PRINTER_NAME
6038 .suffix = ", drvconvert",
6039 .expected_result = WERR_INVALID_PRINTER_NAME
6041 .suffix = ",drvconvert",
6042 .expected_result = WERR_INVALID_PRINTER_NAME
6044 .suffix = ", DrvConvert",
6045 .expected_result = WERR_OK
6047 .suffix = " , DrvConvert",
6048 .expected_result = WERR_INVALID_PRINTER_NAME
6050 .suffix = ",DrvConvert",
6051 .expected_result = WERR_OK
6053 .suffix = ", DrvConvertsadfasdf",
6054 .expected_result = WERR_OK
6056 .suffix = ",DrvConvertasdfasd",
6057 .expected_result = WERR_OK
6059 .suffix = ", LocalOnly",
6060 .expected_result = WERR_OK
6062 .suffix = " , LocalOnly",
6063 .expected_result = WERR_INVALID_PRINTER_NAME
6065 .suffix = ",LocalOnly",
6066 .expected_result = WERR_OK
6068 .suffix = ", LocalOnlysagi4gjfkd",
6069 .expected_result = WERR_OK
6071 .suffix = ",LocalOnlysagi4gjfkd",
6072 .expected_result = WERR_OK
6076 userlevel1.size = 1234;
6077 userlevel1.client = "hello";
6078 userlevel1.user = "spottyfoot!";
6079 userlevel1.build = 1;
6080 userlevel1.major = 2;
6081 userlevel1.minor = 3;
6082 userlevel1.processor = 4;
6084 userlevel.level1 = &userlevel1;
6086 torture_comment(tctx, "Testing openprinterex printername pattern\n");
6088 torture_assert(tctx,
6089 test_OpenPrinterEx(tctx, b, real_printername, NULL, NULL, 0, 1,
6090 &userlevel, &handle,
6092 "OpenPrinterEx failed");
6093 test_ClosePrinter(tctx, b, &handle);
6095 for (i=0; i < ARRAY_SIZE(tests); i++) {
6097 printername = talloc_asprintf(tctx, "%s%s",
6101 torture_assert(tctx,
6102 test_OpenPrinterEx(tctx, b, printername, NULL, NULL, 0, 1,
6103 &userlevel, &handle,
6104 tests[i].expected_result),
6105 "OpenPrinterEx failed");
6106 if (W_ERROR_IS_OK(tests[i].expected_result)) {
6107 test_ClosePrinter(tctx, b, &handle);
6115 static bool test_existing_printer_openprinterex(struct torture_context *tctx,
6116 struct dcerpc_pipe *p,
6118 const char *environment)
6120 struct policy_handle handle;
6122 struct dcerpc_binding_handle *b = p->binding_handle;
6124 if (!test_openprinter(tctx, b, name)) {
6128 if (!call_OpenPrinterEx(tctx, p, name, NULL, &handle)) {
6132 if (!test_PrinterInfo_SD(tctx, b, &handle)) {
6136 if (!test_GetPrinter(tctx, b, &handle, environment)) {
6140 if (!test_EnumForms_all(tctx, b, &handle, false)) {
6144 if (!test_Forms(tctx, b, &handle, false, name, NULL, NULL)) {
6148 if (!test_Forms_winreg(tctx, b, &handle, false, name)) {
6152 if (!test_EnumPrinterData_all(tctx, p, &handle)) {
6156 if (!test_EnumPrinterDataEx(tctx, b, &handle, "PrinterDriverData", NULL, NULL)) {
6160 if (!test_EnumPrinterData_consistency(tctx, p, &handle)) {
6164 if (!test_printer_all_keys(tctx, b, &handle)) {
6168 if (!test_PausePrinter(tctx, b, &handle)) {
6172 if (!test_DoPrintTest(tctx, b, &handle)) {
6176 if (!test_ResumePrinter(tctx, b, &handle)) {
6180 if (!test_SetPrinterData_matrix(tctx, b, &handle, name, NULL, NULL)) {
6184 if (!test_SetPrinterDataEx_matrix(tctx, p, &handle, name, NULL, NULL)) {
6188 if (!torture_setting_bool(tctx, "samba3", false)) {
6189 if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
6194 if (!test_ClosePrinter(tctx, b, &handle)) {
6201 static bool test_EnumPrinters_old(struct torture_context *tctx,
6204 struct test_spoolss_context *ctx =
6205 talloc_get_type_abort(private_data, struct test_spoolss_context);
6206 struct spoolss_EnumPrinters r;
6208 uint16_t levels[] = {1, 2, 4, 5};
6211 struct dcerpc_pipe *p = ctx->spoolss_pipe;
6212 struct dcerpc_binding_handle *b = p->binding_handle;
6214 for (i=0;i<ARRAY_SIZE(levels);i++) {
6215 union spoolss_PrinterInfo *info;
6220 r.in.flags = PRINTER_ENUM_LOCAL;
6222 r.in.level = levels[i];
6225 r.out.needed = &needed;
6226 r.out.count = &count;
6229 torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
6231 status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
6232 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
6234 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6235 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
6236 r.in.buffer = &blob;
6237 r.in.offered = needed;
6238 status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
6241 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
6243 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
6245 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
6248 torture_comment(tctx, "No printers returned\n");
6252 for (j=0;j<count;j++) {
6253 if (r.in.level == 1) {
6254 char *unc = talloc_strdup(tctx, info[j].info1.name);
6255 char *slash, *name, *full_name;
6257 if (unc[0] == '\\' && unc[1] == '\\') {
6260 slash = strchr(unc, '\\');
6265 full_name = talloc_asprintf(tctx, "\\\\%s\\%s",
6266 dcerpc_server_name(p), name);
6267 if (!test_OpenPrinter(tctx, p, name, ctx->environment, true)) {
6270 if (!test_OpenPrinter(tctx, p, full_name, ctx->environment, true)) {
6273 if (!test_OpenPrinter(tctx, p, name, ctx->environment, false)) {
6276 if (!test_existing_printer_openprinterex(tctx, p, name, ctx->environment)) {
6286 static bool test_EnumPrinters_level(struct torture_context *tctx,
6287 struct dcerpc_binding_handle *b,
6289 const char *servername,
6292 union spoolss_PrinterInfo **info_p)
6294 struct spoolss_EnumPrinters r;
6295 union spoolss_PrinterInfo *info;
6300 r.in.server = servername;
6304 r.out.needed = &needed;
6305 r.out.count = &count;
6308 torture_comment(tctx, "Testing EnumPrinters(%s) level %u\n",
6309 r.in.server, r.in.level);
6311 torture_assert_ntstatus_ok(tctx,
6312 dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
6313 "EnumPrinters failed");
6314 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6315 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
6316 r.in.buffer = &blob;
6317 r.in.offered = needed;
6318 torture_assert_ntstatus_ok(tctx,
6319 dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
6320 "EnumPrinters failed");
6323 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
6325 CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
6337 static const char *get_short_printername(struct torture_context *tctx,
6340 const char *short_name;
6342 if (name[0] == '\\' && name[1] == '\\') {
6344 short_name = strchr(name, '\\');
6346 return talloc_strdup(tctx, short_name+1);
6353 static const char *get_full_printername(struct torture_context *tctx,
6356 const char *full_name = talloc_strdup(tctx, name);
6359 if (name && name[0] == '\\' && name[1] == '\\') {
6361 p = strchr(name, '\\');
6370 static bool test_OnePrinter_servername(struct torture_context *tctx,
6371 struct dcerpc_pipe *p,
6372 struct dcerpc_binding_handle *b,
6373 const char *servername,
6374 const char *printername)
6376 union spoolss_PrinterInfo info;
6377 const char *short_name = get_short_printername(tctx, printername);
6378 const char *full_name = get_full_printername(tctx, printername);
6381 struct policy_handle handle;
6382 torture_assert(tctx,
6383 call_OpenPrinterEx(tctx, p, short_name, NULL, &handle),
6384 "failed to open printer");
6386 torture_assert(tctx,
6387 test_GetPrinter_level(tctx, b, &handle, 2, &info),
6388 "failed to get printer info");
6390 torture_assert_casestr_equal(tctx, info.info2.servername, NULL,
6391 "unexpected servername");
6392 torture_assert_casestr_equal(tctx, info.info2.printername, short_name,
6393 "unexpected printername");
6395 if (info.info2.devmode) {
6396 const char *expected_devicename;
6397 expected_devicename = talloc_strndup(tctx, short_name, MIN(strlen(short_name), 31));
6398 torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
6399 "unexpected devicemode devicename");
6402 torture_assert(tctx,
6403 test_ClosePrinter(tctx, b, &handle),
6404 "failed to close printer");
6408 struct policy_handle handle;
6410 torture_assert(tctx,
6411 call_OpenPrinterEx(tctx, p, full_name, NULL, &handle),
6412 "failed to open printer");
6414 torture_assert(tctx,
6415 test_GetPrinter_level(tctx, b, &handle, 2, &info),
6416 "failed to get printer info");
6418 torture_assert_casestr_equal(tctx, info.info2.servername, servername,
6419 "unexpected servername");
6420 torture_assert_casestr_equal(tctx, info.info2.printername, full_name,
6421 "unexpected printername");
6423 if (info.info2.devmode) {
6424 const char *expected_devicename;
6425 expected_devicename = talloc_strndup(tctx, full_name, MIN(strlen(full_name), 31));
6426 torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
6427 "unexpected devicemode devicename");
6430 torture_assert(tctx,
6431 test_ClosePrinter(tctx, b, &handle),
6432 "failed to close printer");
6438 static bool test_EnumPrinters_servername(struct torture_context *tctx,
6441 struct test_spoolss_context *ctx =
6442 talloc_get_type_abort(private_data, struct test_spoolss_context);
6444 struct dcerpc_pipe *p = ctx->spoolss_pipe;
6445 struct dcerpc_binding_handle *b = p->binding_handle;
6447 union spoolss_PrinterInfo *info;
6448 const char *servername;
6449 uint32_t flags = PRINTER_ENUM_NAME|PRINTER_ENUM_LOCAL;
6451 torture_comment(tctx, "Testing servername behaviour in EnumPrinters and GetPrinters\n");
6453 servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
6455 torture_assert(tctx,
6456 test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
6457 "failed to enumerate printers");
6459 for (i=0; i < count; i++) {
6461 torture_assert_casestr_equal(tctx, info[i].info2.servername, servername,
6462 "unexpected servername");
6464 torture_assert(tctx,
6465 test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
6466 "failed to check printer");
6471 torture_assert(tctx,
6472 test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
6473 "failed to enumerate printers");
6475 for (i=0; i < count; i++) {
6477 torture_assert_casestr_equal(tctx, info[i].info2.servername, NULL,
6478 "unexpected servername");
6480 torture_assert(tctx,
6481 test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
6482 "failed to check printer");
6490 static bool test_GetPrinterDriver(struct torture_context *tctx,
6491 struct dcerpc_binding_handle *b,
6492 struct policy_handle *handle,
6493 const char *driver_name)
6495 struct spoolss_GetPrinterDriver r;
6498 r.in.handle = handle;
6499 r.in.architecture = "W32X86";
6503 r.out.needed = &needed;
6505 torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
6507 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
6508 "failed to call GetPrinterDriver");
6509 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6510 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
6511 r.in.buffer = &blob;
6512 r.in.offered = needed;
6513 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
6514 "failed to call GetPrinterDriver");
6517 torture_assert_werr_ok(tctx, r.out.result,
6518 "failed to call GetPrinterDriver");
6520 CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
6525 static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
6526 struct dcerpc_binding_handle *b,
6527 struct policy_handle *handle,
6528 const char *driver_name,
6529 const char *architecture,
6531 uint32_t client_major_version,
6532 uint32_t client_minor_version,
6533 union spoolss_DriverInfo *info_p,
6537 struct spoolss_GetPrinterDriver2 r;
6539 uint32_t server_major_version;
6540 uint32_t server_minor_version;
6542 r.in.handle = handle;
6543 r.in.architecture = architecture;
6544 r.in.client_major_version = client_major_version;
6545 r.in.client_minor_version = client_minor_version;
6549 r.out.needed = &needed;
6550 r.out.server_major_version = &server_major_version;
6551 r.out.server_minor_version = &server_minor_version;
6553 torture_comment(tctx, "Testing GetPrinterDriver2(%s) level %d\n",
6554 driver_name, r.in.level);
6556 torture_assert_ntstatus_ok(tctx,
6557 dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
6558 "failed to call GetPrinterDriver2");
6559 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6560 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
6561 r.in.buffer = &blob;
6562 r.in.offered = needed;
6563 torture_assert_ntstatus_ok(tctx,
6564 dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
6565 "failed to call GetPrinterDriver2");
6569 *result_p = r.out.result;
6572 if (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL)) {
6573 switch (r.in.level) {
6576 torture_comment(tctx,
6577 "level %d not implemented, not considering as an error\n",
6585 torture_assert_werr_ok(tctx, r.out.result,
6586 "failed to call GetPrinterDriver2");
6588 CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
6591 *info_p = *r.out.info;
6597 static bool test_GetPrinterDriver2(struct torture_context *tctx,
6598 struct dcerpc_binding_handle *b,
6599 struct policy_handle *handle,
6600 const char *driver_name,
6601 const char *architecture)
6603 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 8, 101 };
6607 for (i=0;i<ARRAY_SIZE(levels);i++) {
6609 torture_assert(tctx,
6610 test_GetPrinterDriver2_level(tctx, b, handle, driver_name, architecture, levels[i], 3, 0, NULL, NULL),
6617 static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
6620 struct test_spoolss_context *ctx =
6621 talloc_get_type_abort(private_data, struct test_spoolss_context);
6622 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
6624 struct dcerpc_pipe *p = ctx->spoolss_pipe;
6625 struct dcerpc_binding_handle *b = p->binding_handle;
6626 const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
6628 for (i=0;i<ARRAY_SIZE(levels);i++) {
6631 union spoolss_DriverInfo *info;
6633 torture_assert(tctx,
6634 test_EnumPrinterDrivers_args(tctx, b, server_name, ctx->environment, levels[i], &count, &info),
6635 "failed to enumerate drivers");
6638 torture_comment(tctx, "No printer drivers returned\n");
6646 static bool test_DeletePrinter(struct torture_context *tctx,
6647 struct dcerpc_binding_handle *b,
6648 struct policy_handle *handle)
6650 struct spoolss_DeletePrinter r;
6652 torture_comment(tctx, "Testing DeletePrinter\n");
6654 r.in.handle = handle;
6656 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter_r(b, tctx, &r),
6657 "failed to delete printer");
6658 torture_assert_werr_ok(tctx, r.out.result,
6659 "failed to delete printer");
6664 static bool test_EnumPrinters_findname(struct torture_context *tctx,
6665 struct dcerpc_binding_handle *b,
6671 struct spoolss_EnumPrinters e;
6673 union spoolss_PrinterInfo *info;
6684 e.out.count = &count;
6686 e.out.needed = &needed;
6688 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
6689 "failed to enum printers");
6691 if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
6692 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
6693 e.in.buffer = &blob;
6694 e.in.offered = needed;
6696 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
6697 "failed to enum printers");
6700 torture_assert_werr_ok(tctx, e.out.result,
6701 "failed to enum printers");
6703 for (i=0; i < count; i++) {
6705 const char *current = NULL;
6710 current = info[i].info1.name;
6714 if (strequal(current, name)) {
6719 q = strrchr(current, '\\');
6722 torture_warning(tctx,
6723 "server returns printername %s incl. servername although we did not set servername", current);
6726 if (strequal(q, name)) {
6736 static bool test_AddPrinter_wellknown(struct torture_context *tctx,
6737 struct dcerpc_pipe *p,
6738 const char *printername,
6742 struct spoolss_AddPrinter r;
6743 struct spoolss_AddPrinterEx rex;
6744 struct spoolss_SetPrinterInfoCtr info_ctr;
6745 struct spoolss_SetPrinterInfo1 info1;
6746 struct spoolss_DevmodeContainer devmode_ctr;
6747 struct sec_desc_buf secdesc_ctr;
6748 struct spoolss_UserLevelCtr userlevel_ctr;
6749 struct policy_handle handle;
6751 struct dcerpc_binding_handle *b = p->binding_handle;
6753 ZERO_STRUCT(devmode_ctr);
6754 ZERO_STRUCT(secdesc_ctr);
6755 ZERO_STRUCT(userlevel_ctr);
6758 torture_comment(tctx, "Testing AddPrinter%s(%s) level 1\n",
6759 ex ? "Ex":"", printername);
6761 /* try to add printer to wellknown printer list (level 1) */
6763 userlevel_ctr.level = 1;
6765 info_ctr.info.info1 = &info1;
6768 rex.in.server = NULL;
6769 rex.in.info_ctr = &info_ctr;
6770 rex.in.devmode_ctr = &devmode_ctr;
6771 rex.in.secdesc_ctr = &secdesc_ctr;
6772 rex.in.userlevel_ctr = &userlevel_ctr;
6773 rex.out.handle = &handle;
6776 r.in.info_ctr = &info_ctr;
6777 r.in.devmode_ctr = &devmode_ctr;
6778 r.in.secdesc_ctr = &secdesc_ctr;
6779 r.out.handle = &handle;
6781 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6782 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6783 "failed to add printer");
6784 result = ex ? rex.out.result : r.out.result;
6785 torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
6786 "unexpected result code");
6788 info1.name = printername;
6789 info1.flags = PRINTER_ATTRIBUTE_SHARED;
6791 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6792 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6793 "failed to add printer");
6794 result = ex ? rex.out.result : r.out.result;
6795 torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
6796 "unexpected result code");
6798 /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
6799 better do a real check to see the printer is really there */
6801 torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
6802 PRINTER_ENUM_NETWORK, 1,
6805 "failed to enum printers");
6807 torture_assert(tctx, found, "failed to find newly added printer");
6811 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6812 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6813 "failed to add printer");
6814 result = ex ? rex.out.result : r.out.result;
6815 torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
6816 "unexpected result code");
6818 /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
6819 better do a real check to see the printer has really been removed
6820 from the well known printer list */
6824 torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
6825 PRINTER_ENUM_NETWORK, 1,
6828 "failed to enum printers");
6830 torture_assert(tctx, !found, "printer still in well known printer list");
6835 static bool test_AddPrinter_normal(struct torture_context *tctx,
6836 struct dcerpc_pipe *p,
6837 struct policy_handle *handle_p,
6838 const char *printername,
6839 const char *drivername,
6840 const char *portname,
6841 struct spoolss_DeviceMode *devmode,
6845 struct spoolss_AddPrinter r;
6846 struct spoolss_AddPrinterEx rex;
6847 struct spoolss_SetPrinterInfoCtr info_ctr;
6848 struct spoolss_SetPrinterInfo2 info2;
6849 struct spoolss_DevmodeContainer devmode_ctr;
6850 struct sec_desc_buf secdesc_ctr;
6851 struct spoolss_UserLevelCtr userlevel_ctr;
6852 struct policy_handle handle;
6854 bool existing_printer_deleted = false;
6855 struct dcerpc_binding_handle *b = p->binding_handle;
6857 ZERO_STRUCT(devmode_ctr);
6858 ZERO_STRUCT(secdesc_ctr);
6859 ZERO_STRUCT(userlevel_ctr);
6861 torture_comment(tctx, "Testing AddPrinter%s(%s) level 2\n",
6862 ex ? "Ex":"", printername);
6864 devmode_ctr.devmode = devmode;
6866 userlevel_ctr.level = 1;
6868 rex.in.server = NULL;
6869 rex.in.info_ctr = &info_ctr;
6870 rex.in.devmode_ctr = &devmode_ctr;
6871 rex.in.secdesc_ctr = &secdesc_ctr;
6872 rex.in.userlevel_ctr = &userlevel_ctr;
6873 rex.out.handle = &handle;
6876 r.in.info_ctr = &info_ctr;
6877 r.in.devmode_ctr = &devmode_ctr;
6878 r.in.secdesc_ctr = &secdesc_ctr;
6879 r.out.handle = &handle;
6883 /* try to add printer to printer list (level 2) */
6887 info_ctr.info.info2 = &info2;
6890 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6891 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6892 "failed to add printer");
6893 result = ex ? rex.out.result : r.out.result;
6894 torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
6895 "unexpected result code");
6897 info2.printername = printername;
6899 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6900 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6901 "failed to add printer");
6902 result = ex ? rex.out.result : r.out.result;
6904 if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
6905 struct policy_handle printer_handle;
6907 if (existing_printer_deleted) {
6908 torture_fail(tctx, "already deleted printer still existing?");
6911 torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, NULL, &printer_handle),
6912 "failed to open printer handle");
6914 torture_assert(tctx, test_DeletePrinter(tctx, b, &printer_handle),
6915 "failed to delete printer");
6917 torture_assert(tctx, test_ClosePrinter(tctx, b, &printer_handle),
6918 "failed to close server handle");
6920 existing_printer_deleted = true;
6925 torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
6926 "unexpected result code");
6928 info2.portname = portname;
6930 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6931 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6932 "failed to add printer");
6933 result = ex ? rex.out.result : r.out.result;
6934 torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
6935 "unexpected result code");
6937 info2.drivername = drivername;
6939 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6940 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6941 "failed to add printer");
6942 result = ex ? rex.out.result : r.out.result;
6944 /* w2k8r2 allows to add printer w/o defining printprocessor */
6946 if (!W_ERROR_IS_OK(result)) {
6947 torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
6948 "unexpected result code");
6950 info2.printprocessor = "winprint";
6952 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6953 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6954 "failed to add printer");
6955 result = ex ? rex.out.result : r.out.result;
6956 torture_assert_werr_ok(tctx, result,
6957 "failed to add printer");
6962 /* we are paranoid, really check if the printer is there now */
6964 torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
6965 PRINTER_ENUM_LOCAL, 1,
6968 "failed to enum printers");
6969 torture_assert(tctx, found, "failed to find newly added printer");
6971 torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
6972 dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
6973 "failed to add printer");
6974 result = ex ? rex.out.result : r.out.result;
6975 torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
6976 "unexpected result code");
6981 static bool test_printer_info(struct torture_context *tctx,
6984 struct torture_printer_context *t =
6985 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
6986 struct dcerpc_pipe *p = t->spoolss_pipe;
6987 struct dcerpc_binding_handle *b = p->binding_handle;
6991 if (torture_setting_bool(tctx, "samba3", false)) {
6992 torture_skip(tctx, "skipping printer info cross tests against samba 3");
6995 if (!test_PrinterInfo(tctx, b, &t->handle)) {
6999 if (!test_SetPrinter_errors(tctx, b, &t->handle)) {
7006 static bool test_EnumPrinterKey(struct torture_context *tctx,
7007 struct dcerpc_binding_handle *b,
7008 struct policy_handle *handle,
7009 const char *key_name,
7010 const char ***array)
7012 struct spoolss_EnumPrinterKey r;
7013 uint32_t needed = 0;
7014 union spoolss_KeyNames key_buffer;
7015 int32_t offered[] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, 256, 512, 1024, 2048 };
7019 r.in.handle = handle;
7020 r.in.key_name = key_name;
7021 r.out.key_buffer = &key_buffer;
7022 r.out.needed = &needed;
7023 r.out._ndr_size = &_ndr_size;
7025 for (i=0; i < ARRAY_SIZE(offered); i++) {
7027 if (offered[i] < 0 && needed) {
7031 r.in.offered = needed + offered[i];
7033 r.in.offered = offered[i];
7036 ZERO_STRUCT(key_buffer);
7038 torture_comment(tctx, "Testing EnumPrinterKey(%s) with %d offered\n", r.in.key_name, r.in.offered);
7040 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7041 "failed to call EnumPrinterKey");
7042 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
7044 torture_assert(tctx, (_ndr_size == r.in.offered/2),
7045 talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7046 _ndr_size, r.in.offered/2));
7048 r.in.offered = needed;
7049 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7050 "failed to call EnumPrinterKey");
7053 if (offered[i] > 0) {
7054 torture_assert_werr_ok(tctx, r.out.result,
7055 "failed to call EnumPrinterKey");
7058 torture_assert(tctx, (_ndr_size == r.in.offered/2),
7059 talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7060 _ndr_size, r.in.offered/2));
7062 torture_assert(tctx, (*r.out.needed <= r.in.offered),
7063 talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r.out.needed, r.in.offered));
7065 torture_assert(tctx, (*r.out.needed <= _ndr_size * 2),
7066 talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, _ndr_size));
7068 if (key_buffer.string_array) {
7069 uint32_t calc_needed = 0;
7071 for (s=0; key_buffer.string_array[s]; s++) {
7072 calc_needed += strlen_m_term(key_buffer.string_array[s])*2;
7074 if (!key_buffer.string_array[0]) {
7079 torture_assert_int_equal(tctx, *r.out.needed, calc_needed,
7080 "EnumPrinterKey unexpected size");
7085 *array = key_buffer.string_array;
7091 bool test_printer_all_keys(struct torture_context *tctx,
7092 struct dcerpc_binding_handle *b,
7093 struct policy_handle *handle)
7095 const char **key_array = NULL;
7098 torture_comment(tctx, "Testing Printer Keys\n");
7100 torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, "", &key_array),
7101 "failed to call test_EnumPrinterKey");
7103 for (i=0; key_array && key_array[i]; i++) {
7104 torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, key_array[i], NULL),
7105 "failed to call test_EnumPrinterKey");
7107 for (i=0; key_array && key_array[i]; i++) {
7108 torture_assert(tctx, test_EnumPrinterDataEx(tctx, b, handle, key_array[i], NULL, NULL),
7109 "failed to call test_EnumPrinterDataEx");
7112 torture_comment(tctx, "Printer Keys test succeeded\n\n");
7117 static bool test_openprinter_wrap(struct torture_context *tctx,
7120 struct torture_printer_context *t =
7121 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7122 struct dcerpc_pipe *p = t->spoolss_pipe;
7123 struct dcerpc_binding_handle *b = p->binding_handle;
7124 const char *printername = t->info2.printername;
7126 return test_openprinter(tctx, b, printername);
7129 static bool test_csetprinter(struct torture_context *tctx,
7132 struct torture_printer_context *t =
7133 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7134 struct dcerpc_pipe *p = t->spoolss_pipe;
7136 const char *printername = talloc_asprintf(tctx, "%s2", t->info2.printername);
7137 const char *drivername = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
7138 const char *portname = t->info2.portname;
7140 union spoolss_PrinterInfo info;
7141 struct policy_handle new_handle, new_handle2;
7142 struct dcerpc_binding_handle *b = p->binding_handle;
7144 torture_comment(tctx, "Testing c_setprinter\n");
7146 torture_assert(tctx,
7147 test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7148 "failed to get level 0 printer info");
7149 torture_comment(tctx, "csetprinter on initial printer handle: %d\n",
7150 info.info0.c_setprinter);
7152 /* check if c_setprinter on 1st handle increases after a printer has
7155 torture_assert(tctx,
7156 test_AddPrinter_normal(tctx, p, &new_handle, printername, drivername, portname, NULL, false),
7157 "failed to add new printer");
7158 torture_assert(tctx,
7159 test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7160 "failed to get level 0 printer info");
7161 torture_comment(tctx, "csetprinter on initial printer handle (after add): %d\n",
7162 info.info0.c_setprinter);
7164 /* check if c_setprinter on new handle increases after a printer has
7167 torture_assert(tctx,
7168 test_GetPrinter_level(tctx, b, &new_handle, 0, &info),
7169 "failed to get level 0 printer info");
7170 torture_comment(tctx, "csetprinter on created handle: %d\n",
7171 info.info0.c_setprinter);
7173 /* open the new printer and check if c_setprinter increases */
7175 torture_assert(tctx,
7176 call_OpenPrinterEx(tctx, p, printername, NULL, &new_handle2),
7177 "failed to open created printer");
7178 torture_assert(tctx,
7179 test_GetPrinter_level(tctx, b, &new_handle2, 0, &info),
7180 "failed to get level 0 printer info");
7181 torture_comment(tctx, "csetprinter on new handle (after openprinter): %d\n",
7182 info.info0.c_setprinter);
7186 torture_assert(tctx,
7187 test_ClosePrinter(tctx, b, &new_handle2),
7188 "failed to close printer");
7189 torture_assert(tctx,
7190 test_DeletePrinter(tctx, b, &new_handle),
7191 "failed to delete new printer");
7196 static bool compose_local_driver_directory(struct torture_context *tctx,
7197 const char *environment,
7198 const char *local_dir,
7203 p = strrchr(local_dir, '/');
7209 if (strequal(environment, "Windows x64")) {
7210 if (!strequal(p, "x64")) {
7211 *path = talloc_asprintf(tctx, "%s/x64", local_dir);
7213 } else if (strequal(environment, "Windows NT x86")) {
7214 if (!strequal(p, "i386")) {
7215 *path = talloc_asprintf(tctx, "%s/i386", local_dir);
7218 torture_assert(tctx, "unknown environment: '%s'\n", environment);
7224 static struct spoolss_DeviceMode *torture_devicemode(TALLOC_CTX *mem_ctx,
7225 const char *devicename)
7227 struct spoolss_DeviceMode *r;
7229 r = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
7234 r->devicename = talloc_strdup(r, devicename);
7235 r->specversion = DMSPEC_NT4_AND_ABOVE;
7236 r->driverversion = 0x0600;
7238 r->__driverextra_length = 0;
7239 r->fields = DEVMODE_FORMNAME |
7241 DEVMODE_PRINTQUALITY |
7242 DEVMODE_DEFAULTSOURCE |
7246 DEVMODE_ORIENTATION;
7247 r->orientation = DMORIENT_PORTRAIT;
7248 r->papersize = DMPAPER_LETTER;
7253 r->defaultsource = DMBIN_FORMSOURCE;
7254 r->printquality = DMRES_HIGH;
7255 r->color = DMRES_MONOCHROME;
7256 r->duplex = DMDUP_SIMPLEX;
7258 r->ttoption = DMTT_SUBDEV;
7259 r->collate = DMCOLLATE_FALSE;
7260 r->formname = talloc_strdup(r, "Letter");
7265 static bool test_architecture_buffer(struct torture_context *tctx,
7268 struct test_spoolss_context *ctx =
7269 talloc_get_type_abort(private_data, struct test_spoolss_context);
7271 struct spoolss_OpenPrinterEx r;
7272 struct spoolss_UserLevel1 u1;
7273 struct policy_handle handle;
7274 uint32_t architectures[] = {
7275 PROCESSOR_ARCHITECTURE_INTEL,
7276 PROCESSOR_ARCHITECTURE_IA64,
7277 PROCESSOR_ARCHITECTURE_AMD64
7281 struct dcerpc_pipe *p = ctx->spoolss_pipe;
7282 struct dcerpc_binding_handle *b = p->binding_handle;
7284 for (i=0; i < ARRAY_SIZE(architectures); i++) {
7286 torture_comment(tctx, "Testing OpenPrinterEx with architecture %d\n", architectures[i]);
7294 u1.processor = architectures[i];
7296 r.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7297 r.in.datatype = NULL;
7298 r.in.devmode_ctr.devmode= NULL;
7299 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7301 r.in.userlevel.level1 = &u1;
7302 r.out.handle = &handle;
7304 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r), "");
7305 torture_assert_werr_ok(tctx, r.out.result, "");
7308 struct spoolss_EnumPrinters e;
7310 union spoolss_PrinterInfo *info;
7312 e.in.flags = PRINTER_ENUM_LOCAL;
7317 e.out.count = &count;
7319 e.out.needed = &needed[i];
7321 torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e), "");
7323 torture_comment(tctx, "needed was %d\n", needed[i]);
7327 torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), "");
7330 for (i=1; i < ARRAY_SIZE(architectures); i++) {
7331 if (needed[i-1] != needed[i]) {
7333 talloc_asprintf(tctx, "needed size %d for architecture %d != needed size %d for architecture %d\n",
7334 needed[i-1], architectures[i-1], needed[i], architectures[i]));
7341 static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
7344 struct test_spoolss_context *ctx =
7345 talloc_get_type_abort(private_data, struct test_spoolss_context);
7346 struct dcerpc_pipe *p = ctx->spoolss_pipe;
7347 struct dcerpc_binding_handle *b = p->binding_handle;
7349 return test_Forms_winreg(tctx, b, &ctx->server_handle, true, NULL);
7352 static bool test_PrintServer_Forms(struct torture_context *tctx,
7355 struct test_spoolss_context *ctx =
7356 talloc_get_type_abort(private_data, struct test_spoolss_context);
7357 struct dcerpc_pipe *p = ctx->spoolss_pipe;
7358 struct dcerpc_binding_handle *b = p->binding_handle;
7360 return test_Forms(tctx, b, &ctx->server_handle, true, NULL, NULL, NULL);
7363 static bool test_PrintServer_EnumForms(struct torture_context *tctx,
7366 struct test_spoolss_context *ctx =
7367 talloc_get_type_abort(private_data, struct test_spoolss_context);
7368 struct dcerpc_pipe *p = ctx->spoolss_pipe;
7369 struct dcerpc_binding_handle *b = p->binding_handle;
7371 return test_EnumForms_all(tctx, b, &ctx->server_handle, true);
7374 static bool torture_rpc_spoolss_setup_common(struct torture_context *tctx, struct test_spoolss_context *t)
7378 status = torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss);
7380 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
7382 torture_assert(tctx,
7383 test_OpenPrinter_server(tctx, t->spoolss_pipe, &t->server_handle),
7384 "failed to open printserver");
7385 torture_assert(tctx,
7386 test_get_environment(tctx, t->spoolss_pipe->binding_handle, &t->server_handle, &t->environment),
7387 "failed to get environment");
7392 static bool torture_rpc_spoolss_setup(struct torture_context *tctx, void **data)
7394 struct test_spoolss_context *t;
7396 *data = t = talloc_zero(tctx, struct test_spoolss_context);
7398 return torture_rpc_spoolss_setup_common(tctx, t);
7401 static bool torture_rpc_spoolss_teardown_common(struct torture_context *tctx, struct test_spoolss_context *t)
7403 test_ClosePrinter(tctx, t->spoolss_pipe->binding_handle, &t->server_handle);
7408 static bool torture_rpc_spoolss_teardown(struct torture_context *tctx, void *data)
7410 struct test_spoolss_context *t = talloc_get_type(data, struct test_spoolss_context);
7413 ret = torture_rpc_spoolss_teardown_common(tctx, t);
7419 static bool torture_rpc_spoolss_printer_setup_common(struct torture_context *tctx, struct torture_printer_context *t)
7421 struct dcerpc_pipe *p;
7422 struct dcerpc_binding_handle *b;
7423 const char *server_name_slash;
7424 const char *driver_name;
7425 const char *printer_name;
7426 const char *port_name;
7428 torture_assert_ntstatus_ok(tctx,
7429 torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss),
7430 "Error connecting to server");
7432 p = t->spoolss_pipe;
7433 b = p->binding_handle;
7434 server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7436 t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
7437 t->driver.info8.driver_name = TORTURE_DRIVER;
7438 t->driver.info8.driver_path = "pscript5.dll";
7439 t->driver.info8.data_file = "cups6.ppd";
7440 t->driver.info8.config_file = "ps5ui.dll";
7441 t->driver.info8.help_file = "pscript.hlp";
7442 t->driver.info8.default_datatype = "RAW";
7443 t->driver.info8.dependent_files = talloc_zero(t, struct spoolss_StringArray);
7444 t->driver.info8.dependent_files->string = talloc_zero_array(t, const char *, 8 + 1);
7445 t->driver.info8.dependent_files->string[0] = "pscript5.dll";
7446 t->driver.info8.dependent_files->string[1] = "cups6.ppd";
7447 t->driver.info8.dependent_files->string[2] = "ps5ui.dll";
7448 t->driver.info8.dependent_files->string[3] = "pscript.hlp";
7449 t->driver.info8.dependent_files->string[4] = "pscript.ntf";
7450 t->driver.info8.dependent_files->string[5] = "cups6.ini";
7451 t->driver.info8.dependent_files->string[6] = "cupsps6.dll";
7452 t->driver.info8.dependent_files->string[7] = "cupsui6.dll";
7454 t->driver.local.driver_directory= "/usr/share/cups/drivers";
7456 t->info2.drivername = "Microsoft XPS Document Writer";
7457 t->info2.portname = "LPT1:";
7459 printer_name = t->info2.printername;
7460 port_name = t->info2.portname;
7462 torture_assert(tctx,
7463 fillup_printserver_info(tctx, p, &t->driver),
7464 "failed to fillup printserver info");
7466 t->driver.info8.architecture = talloc_strdup(t, t->driver.remote.environment);
7468 torture_assert(tctx,
7469 compose_local_driver_directory(tctx, t->driver.remote.environment,
7470 t->driver.local.driver_directory,
7471 &t->driver.local.driver_directory),
7472 "failed to compose local driver directory");
7474 if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername, NULL)) {
7475 torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) is present on server\n",
7476 t->info2.drivername, t->driver.remote.environment);
7477 t->have_driver = true;
7481 torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
7482 t->info2.drivername, t->driver.remote.environment);
7483 torture_comment(tctx, "trying to upload own driver\n");
7485 if (!directory_exist(t->driver.local.driver_directory)) {
7486 torture_warning(tctx, "no local driver is available!");
7487 t->have_driver = false;
7491 torture_assert(tctx,
7492 upload_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
7493 "failed to upload printer driver");
7495 torture_assert(tctx,
7496 test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &t->driver.info8, 0, false, NULL),
7497 "failed to add driver");
7499 t->added_driver = true;
7500 t->have_driver = true;
7503 driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
7506 torture_assert(tctx,
7507 test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
7508 "failed to add wellknown printer");
7510 torture_assert(tctx,
7511 test_AddPrinter_normal(tctx, p, &t->handle, printer_name, driver_name, port_name, t->devmode, t->ex),
7512 "failed to add printer");
7518 static bool torture_rpc_spoolss_printer_setup(struct torture_context *tctx, void **data)
7520 struct torture_printer_context *t;
7522 *data = t = talloc_zero(tctx, struct torture_printer_context);
7525 t->wellknown = false;
7526 t->info2.printername = TORTURE_PRINTER;
7529 return torture_rpc_spoolss_printer_setup_common(tctx, t);
7532 static bool torture_rpc_spoolss_printerex_setup(struct torture_context *tctx, void **data)
7534 struct torture_printer_context *t;
7536 *data = t = talloc_zero(tctx, struct torture_printer_context);
7539 t->wellknown = false;
7540 t->info2.printername = TORTURE_PRINTER_EX;
7543 return torture_rpc_spoolss_printer_setup_common(tctx, t);
7546 static bool torture_rpc_spoolss_printerwkn_setup(struct torture_context *tctx, void **data)
7548 struct torture_printer_context *t;
7550 *data = t = talloc_zero(tctx, struct torture_printer_context);
7553 t->wellknown = true;
7554 t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
7559 torture_skip(tctx, "skipping AddPrinter level 1");
7562 return torture_rpc_spoolss_printer_setup_common(tctx, t);
7565 static bool torture_rpc_spoolss_printerexwkn_setup(struct torture_context *tctx, void **data)
7567 struct torture_printer_context *t;
7569 *data = t = talloc_zero(tctx, struct torture_printer_context);
7572 t->wellknown = true;
7573 t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
7578 torture_skip(tctx, "skipping AddPrinterEx level 1");
7581 return torture_rpc_spoolss_printer_setup_common(tctx, t);
7584 static bool torture_rpc_spoolss_printerdm_setup(struct torture_context *tctx, void **data)
7586 struct torture_printer_context *t;
7588 *data = t = talloc_zero(tctx, struct torture_printer_context);
7591 t->wellknown = false;
7592 t->info2.printername = TORTURE_PRINTER_EX;
7593 t->devmode = torture_devicemode(t, TORTURE_PRINTER_EX);
7595 return torture_rpc_spoolss_printer_setup_common(tctx, t);
7598 static bool torture_rpc_spoolss_printer_teardown_common(struct torture_context *tctx, struct torture_printer_context *t)
7601 struct dcerpc_pipe *p = t->spoolss_pipe;
7602 struct dcerpc_binding_handle *b;
7603 const char *printer_name = t->info2.printername;
7605 if (t->added_driver) {
7606 torture_assert(tctx,
7607 remove_printer_driver(tctx, dcerpc_server_name(t->spoolss_pipe), &t->driver),
7608 "failed to remove printer driver");
7612 b = p->binding_handle;
7615 if (!t->wellknown) {
7616 torture_assert(tctx,
7617 test_DeletePrinter(tctx, b, &t->handle),
7618 "failed to delete printer");
7620 torture_assert(tctx,
7621 test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
7622 printer_name, &found),
7623 "failed to enumerate printers");
7625 torture_assert(tctx, !found, "deleted printer still there");
7631 static bool torture_rpc_spoolss_printer_teardown(struct torture_context *tctx, void *data)
7633 struct torture_printer_context *t = talloc_get_type(data, struct torture_printer_context);
7636 ret = torture_rpc_spoolss_printer_teardown_common(tctx, t);
7642 static bool test_print_test(struct torture_context *tctx,
7645 struct torture_printer_context *t =
7646 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7647 struct dcerpc_pipe *p = t->spoolss_pipe;
7648 struct dcerpc_binding_handle *b = p->binding_handle;
7650 torture_assert(tctx,
7651 test_PausePrinter(tctx, b, &t->handle),
7652 "failed to pause printer");
7654 torture_assert(tctx,
7655 test_DoPrintTest(tctx, b, &t->handle),
7656 "failed to do print test");
7658 torture_assert(tctx,
7659 test_ResumePrinter(tctx, b, &t->handle),
7660 "failed to resume printer");
7665 static bool test_print_test_extended(struct torture_context *tctx,
7668 struct torture_printer_context *t =
7669 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7670 struct dcerpc_pipe *p = t->spoolss_pipe;
7671 struct dcerpc_binding_handle *b = p->binding_handle;
7674 torture_assert(tctx,
7675 test_PausePrinter(tctx, b, &t->handle),
7676 "failed to pause printer");
7678 ret = test_DoPrintTest_extended(tctx, b, &t->handle);
7680 torture_comment(tctx, "WARNING! failed to do extended print test\n");
7681 if (torture_setting_bool(tctx, "samba3", false)) {
7682 torture_comment(tctx, "non-critical for samba3\n");
7684 tctx->last_result = TORTURE_SKIP;
7688 torture_assert(tctx,
7689 test_ResumePrinter(tctx, b, &t->handle),
7690 "failed to resume printer");
7695 static bool test_printer_sd(struct torture_context *tctx,
7698 struct torture_printer_context *t =
7699 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7700 struct dcerpc_pipe *p = t->spoolss_pipe;
7701 struct dcerpc_binding_handle *b = p->binding_handle;
7703 torture_assert(tctx,
7704 test_PrinterInfo_SD(tctx, b, &t->handle),
7705 "failed to test security descriptors");
7710 static bool test_printer_dm(struct torture_context *tctx,
7713 struct torture_printer_context *t =
7714 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7715 struct dcerpc_pipe *p = t->spoolss_pipe;
7717 torture_assert(tctx,
7718 test_PrinterInfo_DevMode(tctx, p, &t->handle, t->info2.printername, t->devmode),
7719 "failed to test devicemodes");
7724 static bool test_printer_info_winreg(struct torture_context *tctx,
7727 struct torture_printer_context *t =
7728 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7729 struct dcerpc_pipe *p = t->spoolss_pipe;
7731 torture_assert(tctx,
7732 test_PrinterInfo_winreg(tctx, p, &t->handle, t->info2.printername),
7733 "failed to test printer info winreg");
7738 static bool test_printer_change_id(struct torture_context *tctx,
7741 struct torture_printer_context *t =
7742 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7743 struct dcerpc_pipe *p = t->spoolss_pipe;
7745 torture_assert(tctx,
7746 test_ChangeID(tctx, p, &t->handle),
7747 "failed to test change id");
7752 static bool test_printer_keys(struct torture_context *tctx,
7755 struct torture_printer_context *t =
7756 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7757 struct dcerpc_pipe *p = t->spoolss_pipe;
7758 struct dcerpc_binding_handle *b = p->binding_handle;
7760 torture_assert(tctx,
7761 test_printer_all_keys(tctx, b, &t->handle),
7762 "failed to test printer keys");
7767 static bool test_printer_data_consistency(struct torture_context *tctx,
7770 struct torture_printer_context *t =
7771 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7772 struct dcerpc_pipe *p = t->spoolss_pipe;
7774 torture_assert(tctx,
7775 test_EnumPrinterData_consistency(tctx, p, &t->handle),
7776 "failed to test printer data consistency");
7781 static bool test_printer_data_keys(struct torture_context *tctx,
7784 struct torture_printer_context *t =
7785 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7786 struct dcerpc_pipe *p = t->spoolss_pipe;
7788 torture_assert(tctx,
7789 test_SetPrinterDataEx_keys(tctx, p, &t->handle),
7790 "failed to test printer data keys");
7795 static bool test_printer_data_values(struct torture_context *tctx,
7798 struct torture_printer_context *t =
7799 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7800 struct dcerpc_pipe *p = t->spoolss_pipe;
7802 torture_assert(tctx,
7803 test_SetPrinterDataEx_values(tctx, p, &t->handle),
7804 "failed to test printer data values");
7809 static bool test_printer_data_set(struct torture_context *tctx,
7812 struct torture_printer_context *t =
7813 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7814 struct dcerpc_pipe *p = t->spoolss_pipe;
7816 torture_assert(tctx,
7817 test_SetPrinterDataEx_matrix(tctx, p, &t->handle, t->info2.printername, NULL, NULL),
7818 "failed to test printer data set");
7823 static bool test_printer_data_winreg(struct torture_context *tctx,
7826 struct torture_printer_context *t =
7827 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7828 struct dcerpc_pipe *p = t->spoolss_pipe;
7830 torture_assert(tctx,
7831 test_PrinterData_winreg(tctx, p, &t->handle, t->info2.printername),
7832 "failed to test printer data winreg");
7837 static bool test_printer_data_dsspooler(struct torture_context *tctx,
7840 struct torture_printer_context *t =
7841 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7842 struct dcerpc_pipe *p = t->spoolss_pipe;
7844 torture_assert(tctx,
7845 test_PrinterData_DsSpooler(tctx, p, &t->handle, t->info2.printername),
7846 "failed to test printer data winreg dsspooler");
7851 static bool test_driver_info_winreg(struct torture_context *tctx,
7854 struct torture_printer_context *t =
7855 (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7856 struct dcerpc_pipe *p = t->spoolss_pipe;
7857 const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
7859 if (!t->have_driver) {
7860 torture_skip(tctx, "skipping driver info winreg test as we don't have a driver");
7863 torture_assert(tctx,
7864 test_DriverInfo_winreg(tctx, p, &t->handle, t->info2.printername, driver_name, t->driver.remote.environment, 3),
7865 "failed to test driver info winreg");
7870 void torture_tcase_printer(struct torture_tcase *tcase)
7872 torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter_wrap);
7873 torture_tcase_add_simple_test(tcase, "csetprinter", test_csetprinter);
7874 torture_tcase_add_simple_test(tcase, "print_test", test_print_test);
7875 torture_tcase_add_simple_test(tcase, "print_test_extended", test_print_test_extended);
7876 torture_tcase_add_simple_test(tcase, "printer_info", test_printer_info);
7877 torture_tcase_add_simple_test(tcase, "sd", test_printer_sd);
7878 torture_tcase_add_simple_test(tcase, "dm", test_printer_dm);
7879 torture_tcase_add_simple_test(tcase, "printer_info_winreg", test_printer_info_winreg);
7880 torture_tcase_add_simple_test(tcase, "change_id", test_printer_change_id);
7881 torture_tcase_add_simple_test(tcase, "keys", test_printer_keys);
7882 torture_tcase_add_simple_test(tcase, "printerdata_consistency", test_printer_data_consistency);
7883 torture_tcase_add_simple_test(tcase, "printerdata_keys", test_printer_data_keys);
7884 torture_tcase_add_simple_test(tcase, "printerdata_values", test_printer_data_values);
7885 torture_tcase_add_simple_test(tcase, "printerdata_set", test_printer_data_set);
7886 torture_tcase_add_simple_test(tcase, "printerdata_winreg", test_printer_data_winreg);
7887 torture_tcase_add_simple_test(tcase, "printerdata_dsspooler", test_printer_data_dsspooler);
7888 torture_tcase_add_simple_test(tcase, "driver_info_winreg", test_driver_info_winreg);
7889 torture_tcase_add_simple_test(tcase, "printer_rename", test_printer_rename);
7892 struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
7894 struct torture_suite *suite = torture_suite_create(mem_ctx, "printer");
7895 struct torture_tcase *tcase;
7897 tcase = torture_suite_add_tcase(suite, "addprinter");
7899 torture_tcase_set_fixture(tcase,
7900 torture_rpc_spoolss_printer_setup,
7901 torture_rpc_spoolss_printer_teardown);
7903 torture_tcase_printer(tcase);
7905 tcase = torture_suite_add_tcase(suite, "addprinterex");
7907 torture_tcase_set_fixture(tcase,
7908 torture_rpc_spoolss_printerex_setup,
7909 torture_rpc_spoolss_printer_teardown);
7911 torture_tcase_printer(tcase);
7913 tcase = torture_suite_add_tcase(suite, "addprinterwkn");
7915 torture_tcase_set_fixture(tcase,
7916 torture_rpc_spoolss_printerwkn_setup,
7917 torture_rpc_spoolss_printer_teardown);
7919 tcase = torture_suite_add_tcase(suite, "addprinterexwkn");
7921 torture_tcase_set_fixture(tcase,
7922 torture_rpc_spoolss_printerexwkn_setup,
7923 torture_rpc_spoolss_printer_teardown);
7926 /* test is not correct */
7927 tcase = torture_suite_add_tcase(suite, "addprinterdm");
7929 torture_tcase_set_fixture(tcase,
7930 torture_rpc_spoolss_printerdm_setup,
7931 torture_rpc_spoolss_printer_teardown);
7933 torture_tcase_printer(tcase);
7938 struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
7940 struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss");
7941 struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
7943 torture_tcase_set_fixture(tcase,
7944 torture_rpc_spoolss_setup,
7945 torture_rpc_spoolss_teardown);
7947 torture_tcase_add_simple_test(tcase, "openprinter_badnamelist", test_OpenPrinter_badname_list);
7948 torture_tcase_add_simple_test(tcase, "printer_data_list", test_GetPrinterData_list);
7949 torture_tcase_add_simple_test(tcase, "enum_forms", test_PrintServer_EnumForms);
7950 torture_tcase_add_simple_test(tcase, "forms", test_PrintServer_Forms);
7951 torture_tcase_add_simple_test(tcase, "forms_winreg", test_PrintServer_Forms_Winreg);
7952 torture_tcase_add_simple_test(tcase, "enum_ports", test_EnumPorts);
7953 torture_tcase_add_simple_test(tcase, "add_port", test_AddPort);
7954 torture_tcase_add_simple_test(tcase, "get_printer_driver_directory", test_GetPrinterDriverDirectory);
7955 torture_tcase_add_simple_test(tcase, "get_print_processor_directory", test_GetPrintProcessorDirectory);
7956 torture_tcase_add_simple_test(tcase, "enum_printer_drivers", test_EnumPrinterDrivers);
7957 torture_tcase_add_simple_test(tcase, "enum_monitors", test_EnumMonitors);
7958 torture_tcase_add_simple_test(tcase, "enum_print_processors", test_EnumPrintProcessors);
7959 torture_tcase_add_simple_test(tcase, "print_processors_winreg", test_print_processors_winreg);
7960 torture_tcase_add_simple_test(tcase, "enum_printprocdata", test_EnumPrintProcDataTypes);
7961 torture_tcase_add_simple_test(tcase, "enum_printers", test_EnumPrinters);
7962 torture_tcase_add_simple_test(tcase, "enum_ports_old", test_EnumPorts_old);
7963 torture_tcase_add_simple_test(tcase, "enum_printers_old", test_EnumPrinters_old);
7964 torture_tcase_add_simple_test(tcase, "enum_printers_servername", test_EnumPrinters_servername);
7965 torture_tcase_add_simple_test(tcase, "enum_printer_drivers_old", test_EnumPrinterDrivers_old);
7966 torture_tcase_add_simple_test(tcase, "architecture_buffer", test_architecture_buffer);
7968 torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
7973 static bool test_GetPrinterDriverDirectory_getdir(struct torture_context *tctx,
7974 struct dcerpc_binding_handle *b,
7976 const char *environment,
7979 struct spoolss_GetPrinterDriverDirectory r;
7982 r.in.server = server;
7983 r.in.environment = environment;
7987 r.out.needed = &needed;
7989 torture_assert_ntstatus_ok(tctx,
7990 dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
7991 "failed to query driver directory");
7993 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7994 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7995 r.in.buffer = &blob;
7996 r.in.offered = needed;
7998 torture_assert_ntstatus_ok(tctx,
7999 dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
8000 "failed to query driver directory");
8003 torture_assert_werr_ok(tctx, r.out.result,
8004 "failed to query driver directory");
8007 *dir_p = r.out.info->info1.directory_name;
8013 static const char *get_driver_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
8015 if (info_ctr == NULL) {
8019 switch (info_ctr->level) {
8021 return info_ctr->info.info1->driver_name;
8023 return info_ctr->info.info2->driver_name;
8025 return info_ctr->info.info3->driver_name;
8027 return info_ctr->info.info4->driver_name;
8029 return info_ctr->info.info6->driver_name;
8031 return info_ctr->info.info8->driver_name;
8037 static const char *get_environment_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
8039 if (info_ctr == NULL) {
8043 switch (info_ctr->level) {
8045 return info_ctr->info.info2->architecture;
8047 return info_ctr->info.info3->architecture;
8049 return info_ctr->info.info4->architecture;
8051 return info_ctr->info.info6->architecture;
8053 return info_ctr->info.info8->architecture;
8060 static bool test_AddPrinterDriver_exp(struct torture_context *tctx,
8061 struct dcerpc_binding_handle *b,
8062 const char *servername,
8063 struct spoolss_AddDriverInfoCtr *info_ctr,
8064 WERROR expected_result)
8066 struct spoolss_AddPrinterDriver r;
8067 const char *drivername = get_driver_from_info(info_ctr);
8068 const char *environment = get_environment_from_info(info_ctr);
8070 r.in.servername = servername;
8071 r.in.info_ctr = info_ctr;
8073 torture_comment(tctx, "Testing AddPrinterDriver(%s) level: %d, environment: '%s'\n",
8074 drivername, info_ctr->level, environment);
8076 torture_assert_ntstatus_ok(tctx,
8077 dcerpc_spoolss_AddPrinterDriver_r(b, tctx, &r),
8078 "spoolss_AddPrinterDriver failed");
8079 torture_assert_werr_equal(tctx, r.out.result, expected_result,
8080 "spoolss_AddPrinterDriver failed with unexpected result");
8086 static bool test_AddPrinterDriverEx_exp(struct torture_context *tctx,
8087 struct dcerpc_binding_handle *b,
8088 const char *servername,
8089 struct spoolss_AddDriverInfoCtr *info_ctr,
8091 WERROR expected_result)
8093 struct spoolss_AddPrinterDriverEx r;
8094 const char *drivername = get_driver_from_info(info_ctr);
8095 const char *environment = get_environment_from_info(info_ctr);
8097 r.in.servername = servername;
8098 r.in.info_ctr = info_ctr;
8101 torture_comment(tctx, "Testing AddPrinterDriverEx(%s) level: %d, environment: '%s'\n",
8102 drivername, info_ctr->level, environment);
8104 torture_assert_ntstatus_ok(tctx,
8105 dcerpc_spoolss_AddPrinterDriverEx_r(b, tctx, &r),
8106 "AddPrinterDriverEx failed");
8107 torture_assert_werr_equal(tctx, r.out.result, expected_result,
8108 "AddPrinterDriverEx failed with unexpected result");
8113 #define ASSERT_DRIVER_PATH(tctx, path, driver_dir, cmt) \
8114 if (path && strlen(path)) {\
8115 torture_assert_strn_equal(tctx, path, driver_dir, strlen(driver_dir), cmt); \
8118 static bool test_AddPrinterDriver_args_level_1(struct torture_context *tctx,
8119 struct dcerpc_binding_handle *b,
8120 const char *server_name,
8121 struct spoolss_AddDriverInfo8 *r,
8124 const char *remote_driver_dir)
8126 struct spoolss_AddDriverInfoCtr info_ctr;
8127 struct spoolss_AddDriverInfo1 info1;
8132 info_ctr.info.info1 = &info1;
8135 torture_assert(tctx,
8136 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_UNKNOWN_LEVEL),
8137 "failed to test AddPrinterDriverEx level 1");
8139 torture_assert(tctx,
8140 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_UNKNOWN_LEVEL),
8141 "failed to test AddPrinterDriver level 1");
8144 info1.driver_name = r->driver_name;
8147 torture_assert(tctx,
8148 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_UNKNOWN_LEVEL),
8149 "failed to test AddPrinterDriverEx level 1");
8151 torture_assert(tctx,
8152 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_UNKNOWN_LEVEL),
8153 "failed to test AddPrinterDriver level 1");
8159 static bool test_AddPrinterDriver_args_level_2(struct torture_context *tctx,
8160 struct dcerpc_binding_handle *b,
8161 const char *server_name,
8162 struct spoolss_AddDriverInfo8 *r,
8165 const char *remote_driver_dir)
8167 struct spoolss_AddDriverInfoCtr info_ctr;
8168 struct spoolss_AddDriverInfo2 info2;
8169 union spoolss_DriverInfo info;
8174 info_ctr.info.info2 = &info2;
8177 torture_assert(tctx,
8178 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8179 "failed to test AddPrinterDriverEx level 2");
8181 torture_assert(tctx,
8182 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8183 "failed to test AddPrinterDriver level 2");
8186 info2.driver_name = r->driver_name;
8189 torture_assert(tctx,
8190 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8191 "failed to test AddPrinterDriverEx level 2");
8193 torture_assert(tctx,
8194 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8195 "failed to test AddPrinterDriver level 2");
8198 info2.version = r->version;
8201 torture_assert(tctx,
8202 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8203 "failed to test AddPrinterDriverEx level 2");
8205 torture_assert(tctx,
8206 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8207 "failed to test AddPrinterDriver level 2");
8210 info2.architecture = r->architecture;
8213 torture_assert(tctx,
8214 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8215 "failed to test AddPrinterDriverEx level 2");
8217 torture_assert(tctx,
8218 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8219 "failed to test AddPrinterDriver level 2");
8222 info2.driver_path = r->driver_path;
8225 torture_assert(tctx,
8226 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8227 "failed to test AddPrinterDriverEx level 2");
8229 torture_assert(tctx,
8230 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8231 "failed to test AddPrinterDriver level 2");
8234 info2.data_file = r->data_file;
8237 torture_assert(tctx,
8238 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAM),
8239 "failed to test AddPrinterDriverEx level 2");
8241 torture_assert(tctx,
8242 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAM),
8243 "failed to test AddPrinterDriver level 2");
8246 info2.config_file = r->config_file;
8249 torture_assert(tctx,
8250 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, 0, WERR_INVALID_PARAM),
8251 "failed to test AddPrinterDriverEx");
8255 torture_assert(tctx,
8256 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
8257 "failed to test AddPrinterDriverEx level 2");
8259 torture_assert(tctx,
8260 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
8261 "failed to test AddPrinterDriver level 2");
8264 torture_assert(tctx,
8265 test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 2, r->driver_name, &info),
8266 "failed to find added printer driver");
8268 if (remote_driver_dir) {
8269 ASSERT_DRIVER_PATH(tctx, info.info2.driver_path, remote_driver_dir, "unexpected path");
8270 ASSERT_DRIVER_PATH(tctx, info.info2.data_file, remote_driver_dir, "unexpected path");
8271 ASSERT_DRIVER_PATH(tctx, info.info2.config_file, remote_driver_dir, "unexpected path");
8277 static bool test_AddPrinterDriver_args_level_3(struct torture_context *tctx,
8278 struct dcerpc_binding_handle *b,
8279 const char *server_name,
8280 struct spoolss_AddDriverInfo8 *r,
8283 const char *remote_driver_dir)
8285 struct spoolss_AddDriverInfoCtr info_ctr;
8286 struct spoolss_AddDriverInfo3 info3;
8287 union spoolss_DriverInfo info;
8289 info3.driver_name = r->driver_name;
8290 info3.version = r->version;
8291 info3.architecture = r->architecture;
8292 info3.driver_path = r->driver_path;
8293 info3.data_file = r->data_file;
8294 info3.config_file = r->config_file;
8295 info3.help_file = r->help_file;
8296 info3.monitor_name = r->monitor_name;
8297 info3.default_datatype = r->default_datatype;
8298 info3._ndr_size_dependent_files = r->_ndr_size_dependent_files;
8299 info3.dependent_files = r->dependent_files;
8302 info_ctr.info.info3 = &info3;
8305 torture_assert(tctx,
8306 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
8307 "failed to test AddPrinterDriverEx level 3");
8309 torture_assert(tctx,
8310 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
8311 "failed to test AddPrinterDriver level 3");
8314 torture_assert(tctx,
8315 test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 3, r->driver_name, &info),
8316 "failed to find added printer driver");
8318 if (remote_driver_dir) {
8320 ASSERT_DRIVER_PATH(tctx, info.info3.driver_path, remote_driver_dir, "unexpected path");
8321 ASSERT_DRIVER_PATH(tctx, info.info3.data_file, remote_driver_dir, "unexpected path");
8322 ASSERT_DRIVER_PATH(tctx, info.info3.config_file, remote_driver_dir, "unexpected path");
8323 ASSERT_DRIVER_PATH(tctx, info.info3.help_file, remote_driver_dir, "unexpected path");
8324 for (i=0; info.info3.dependent_files && info.info3.dependent_files[i] != NULL; i++) {
8325 ASSERT_DRIVER_PATH(tctx, info.info3.dependent_files[i], remote_driver_dir, "unexpected path");
8332 static bool test_AddPrinterDriver_args_level_4(struct torture_context *tctx,
8333 struct dcerpc_binding_handle *b,
8334 const char *server_name,
8335 struct spoolss_AddDriverInfo8 *r,
8338 const char *remote_driver_dir)
8340 struct spoolss_AddDriverInfoCtr info_ctr;
8341 struct spoolss_AddDriverInfo4 info4;
8342 union spoolss_DriverInfo info;
8344 info4.version = r->version;
8345 info4.driver_name = r->driver_name;
8346 info4.architecture = r->architecture;
8347 info4.driver_path = r->driver_path;
8348 info4.data_file = r->data_file;
8349 info4.config_file = r->config_file;
8350 info4.help_file = r->help_file;
8351 info4.monitor_name = r->monitor_name;
8352 info4.default_datatype = r->default_datatype;
8353 info4._ndr_size_dependent_files = r->_ndr_size_dependent_files;
8354 info4.dependent_files = r->dependent_files;
8355 info4._ndr_size_previous_names = r->_ndr_size_previous_names;
8356 info4.previous_names = r->previous_names;
8359 info_ctr.info.info4 = &info4;
8362 torture_assert(tctx,
8363 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
8364 "failed to test AddPrinterDriverEx level 4");
8366 torture_assert(tctx,
8367 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
8368 "failed to test AddPrinterDriver level 4");
8371 torture_assert(tctx,
8372 test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 4, r->driver_name, &info),
8373 "failed to find added printer driver");
8375 if (remote_driver_dir) {
8377 ASSERT_DRIVER_PATH(tctx, info.info4.driver_path, remote_driver_dir, "unexpected path");
8378 ASSERT_DRIVER_PATH(tctx, info.info4.data_file, remote_driver_dir, "unexpected path");
8379 ASSERT_DRIVER_PATH(tctx, info.info4.config_file, remote_driver_dir, "unexpected path");
8380 ASSERT_DRIVER_PATH(tctx, info.info4.help_file, remote_driver_dir, "unexpected path");
8381 for (i=0; info.info4.dependent_files && info.info4.dependent_files[i] != NULL; i++) {
8382 ASSERT_DRIVER_PATH(tctx, info.info4.dependent_files[i], remote_driver_dir, "unexpected path");
8389 static bool test_AddPrinterDriver_args_level_6(struct torture_context *tctx,
8390 struct dcerpc_binding_handle *b,
8391 const char *server_name,
8392 struct spoolss_AddDriverInfo8 *r,
8395 const char *remote_driver_dir)
8397 struct spoolss_AddDriverInfoCtr info_ctr;
8398 struct spoolss_AddDriverInfo6 info6;
8399 union spoolss_DriverInfo info;
8401 info6.version = r->version;
8402 info6.driver_name = r->driver_name;
8403 info6.architecture = r->architecture;
8404 info6.driver_path = r->driver_path;
8405 info6.data_file = r->data_file;
8406 info6.config_file = r->config_file;
8407 info6.help_file = r->help_file;
8408 info6.monitor_name = r->monitor_name;
8409 info6.default_datatype = r->default_datatype;
8410 info6._ndr_size_dependent_files = r->_ndr_size_dependent_files;
8411 info6.dependent_files = r->dependent_files;
8412 info6._ndr_size_previous_names = r->_ndr_size_previous_names;
8413 info6.previous_names = r->previous_names;
8414 info6.driver_date = r->driver_date;
8415 info6.driver_version = r->driver_version;
8416 info6.manufacturer_name = r->manufacturer_name;
8417 info6.manufacturer_url = r->manufacturer_url;
8418 info6.hardware_id = r->hardware_id;
8419 info6.provider = r->provider;
8422 info_ctr.info.info6 = &info6;
8425 torture_assert(tctx,
8426 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
8427 "failed to test AddPrinterDriverEx level 6");
8429 torture_assert(tctx,
8430 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_UNKNOWN_LEVEL),
8431 "failed to test AddPrinterDriver level 6");
8434 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8440 torture_assert(tctx,
8441 test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 6, r->driver_name, &info),
8442 "failed to find added printer driver");
8444 if (remote_driver_dir) {
8446 ASSERT_DRIVER_PATH(tctx, info.info6.driver_path, remote_driver_dir, "unexpected path");
8447 ASSERT_DRIVER_PATH(tctx, info.info6.data_file, remote_driver_dir, "unexpected path");
8448 ASSERT_DRIVER_PATH(tctx, info.info6.config_file, remote_driver_dir, "unexpected path");
8449 ASSERT_DRIVER_PATH(tctx, info.info6.help_file, remote_driver_dir, "unexpected path");
8450 for (i=0; info.info6.dependent_files && info.info6.dependent_files[i] != NULL; i++) {
8451 ASSERT_DRIVER_PATH(tctx, info.info6.dependent_files[i], remote_driver_dir, "unexpected path");
8455 torture_assert_nttime_equal(tctx, info.info6.driver_date, info6.driver_date, "driverdate mismatch");
8460 static bool test_AddPrinterDriver_args_level_8(struct torture_context *tctx,
8461 struct dcerpc_binding_handle *b,
8462 const char *server_name,
8463 struct spoolss_AddDriverInfo8 *r,
8466 const char *remote_driver_dir)
8468 struct spoolss_AddDriverInfoCtr info_ctr;
8469 union spoolss_DriverInfo info;
8472 info_ctr.info.info8 = r;
8475 torture_assert(tctx,
8476 test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
8477 "failed to test AddPrinterDriverEx level 8");
8479 torture_assert(tctx,
8480 test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_UNKNOWN_LEVEL),
8481 "failed to test AddPrinterDriver level 8");
8484 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8490 torture_assert(tctx,
8491 test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 8, r->driver_name, &info),
8492 "failed to find added printer driver");
8494 if (remote_driver_dir) {
8496 ASSERT_DRIVER_PATH(tctx, info.info8.driver_path, remote_driver_dir, "unexpected path");
8497 ASSERT_DRIVER_PATH(tctx, info.info8.data_file, remote_driver_dir, "unexpected path");
8498 ASSERT_DRIVER_PATH(tctx, info.info8.config_file, remote_driver_dir, "unexpected path");
8499 ASSERT_DRIVER_PATH(tctx, info.info8.help_file, remote_driver_dir, "unexpected path");
8500 for (i=0; info.info8.dependent_files && info.info8.dependent_files[i] != NULL; i++) {
8501 ASSERT_DRIVER_PATH(tctx, info.info8.dependent_files[i], remote_driver_dir, "unexpected path");
8505 torture_assert_nttime_equal(tctx, info.info8.driver_date, r->driver_date, "driverdate mismatch");
8510 #undef ASSERT_DRIVER_PATH
8512 static bool test_DeletePrinterDriver_exp(struct torture_context *tctx,
8513 struct dcerpc_binding_handle *b,
8516 const char *environment,
8517 WERROR expected_result)
8519 struct spoolss_DeletePrinterDriver r;
8521 r.in.server = server;
8522 r.in.architecture = environment;
8523 r.in.driver = driver;
8525 torture_comment(tctx, "Testing DeletePrinterDriver(%s)\n", driver);
8527 torture_assert_ntstatus_ok(tctx,
8528 dcerpc_spoolss_DeletePrinterDriver_r(b, tctx, &r),
8529 "DeletePrinterDriver failed");
8530 torture_assert_werr_equal(tctx, r.out.result, expected_result,
8531 "DeletePrinterDriver failed with unexpected result");
8536 static bool test_DeletePrinterDriverEx_exp(struct torture_context *tctx,
8537 struct dcerpc_binding_handle *b,
8540 const char *environment,
8541 uint32_t delete_flags,
8543 WERROR expected_result)
8545 struct spoolss_DeletePrinterDriverEx r;
8547 r.in.server = server;
8548 r.in.architecture = environment;
8549 r.in.driver = driver;
8550 r.in.delete_flags = delete_flags;
8551 r.in.version = version;
8553 torture_comment(tctx, "Testing DeletePrinterDriverEx(%s)\n", driver);
8555 torture_assert_ntstatus_ok(tctx,
8556 dcerpc_spoolss_DeletePrinterDriverEx_r(b, tctx, &r),
8557 "DeletePrinterDriverEx failed");
8558 torture_assert_werr_equal(tctx, r.out.result, expected_result,
8559 "DeletePrinterDriverEx failed with unexpected result");
8564 static bool test_DeletePrinterDriver(struct torture_context *tctx,
8565 struct dcerpc_binding_handle *b,
8566 const char *server_name,
8568 const char *environment)
8570 torture_assert(tctx,
8571 test_DeletePrinterDriver_exp(tctx, b, server_name, driver, "FOOBAR", WERR_INVALID_ENVIRONMENT),
8572 "failed to delete driver");
8574 torture_assert(tctx,
8575 test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_OK),
8576 "failed to delete driver");
8578 if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
8579 torture_fail(tctx, "deleted driver still enumerated");
8582 torture_assert(tctx,
8583 test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_UNKNOWN_PRINTER_DRIVER),
8584 "2nd delete failed");
8589 static bool test_DeletePrinterDriverEx(struct torture_context *tctx,
8590 struct dcerpc_binding_handle *b,
8591 const char *server_name,
8593 const char *environment,
8594 uint32_t delete_flags,
8597 torture_assert(tctx,
8598 test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, "FOOBAR", delete_flags, version, WERR_INVALID_ENVIRONMENT),
8599 "failed to delete driver");
8601 torture_assert(tctx,
8602 test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_OK),
8603 "failed to delete driver");
8605 if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
8606 torture_fail(tctx, "deleted driver still enumerated");
8609 torture_assert(tctx,
8610 test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_UNKNOWN_PRINTER_DRIVER),
8611 "2nd delete failed");
8616 static bool test_PrinterDriver_args(struct torture_context *tctx,
8617 struct dcerpc_binding_handle *b,
8618 const char *server_name,
8620 struct spoolss_AddDriverInfo8 *r,
8622 uint32_t delete_flags,
8623 uint32_t delete_version,
8625 const char *remote_driver_dir)
8631 ret = test_AddPrinterDriver_args_level_1(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8634 ret = test_AddPrinterDriver_args_level_2(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8637 ret = test_AddPrinterDriver_args_level_3(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8640 ret = test_AddPrinterDriver_args_level_4(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8643 ret = test_AddPrinterDriver_args_level_6(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8646 ret = test_AddPrinterDriver_args_level_8(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
8660 /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
8662 if (!ex && (level == 6 || level == 8)) {
8667 struct dcerpc_pipe *p2;
8668 struct policy_handle hive_handle;
8669 struct dcerpc_binding_handle *b2;
8671 torture_assert_ntstatus_ok(tctx,
8672 torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
8673 "could not open winreg pipe");
8674 b2 = p2->binding_handle;
8676 torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
8678 ret = test_GetDriverInfo_winreg(tctx, b, NULL, NULL, r->driver_name, r->architecture, r->version, b2, &hive_handle, server_name);
8680 test_winreg_CloseKey(tctx, b2, &hive_handle);
8686 return test_DeletePrinterDriverEx(tctx, b, server_name, r->driver_name, r->architecture, delete_flags, r->version);
8688 return test_DeletePrinterDriver(tctx, b, server_name, r->driver_name, r->architecture);
8692 static bool fillup_printserver_info(struct torture_context *tctx,
8693 struct dcerpc_pipe *p,
8694 struct torture_driver_context *d)
8696 struct policy_handle server_handle;
8697 struct dcerpc_binding_handle *b = p->binding_handle;
8698 const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8700 torture_assert(tctx,
8701 test_OpenPrinter_server(tctx, p, &server_handle),
8702 "failed to open printserver");
8703 torture_assert(tctx,
8704 test_get_environment(tctx, b, &server_handle, &d->remote.environment),
8705 "failed to get environment");
8706 torture_assert(tctx,
8707 test_ClosePrinter(tctx, b, &server_handle),
8708 "failed to close printserver");
8710 torture_assert(tctx,
8711 test_GetPrinterDriverDirectory_getdir(tctx, b, server_name_slash,
8712 d->local.environment ? d->local.environment : d->remote.environment,
8713 &d->remote.driver_directory),
8714 "failed to get driver directory");
8719 static const char *driver_directory_dir(const char *driver_directory)
8723 p = strrchr(driver_directory, '\\');
8731 static const char *driver_directory_share(struct torture_context *tctx,
8732 const char *driver_directory)
8737 if (driver_directory[0] == '\\' && driver_directory[1] == '\\') {
8738 driver_directory += 2;
8741 p = talloc_strdup(tctx, driver_directory);
8743 torture_assert(tctx,
8744 next_token_talloc(tctx, &p, &tok, "\\"),
8745 "cannot explode uri");
8746 torture_assert(tctx,
8747 next_token_talloc(tctx, &p, &tok, "\\"),
8748 "cannot explode uri");
8753 static bool upload_printer_driver_file(struct torture_context *tctx,
8754 struct smbcli_state *cli,
8755 struct torture_driver_context *d,
8756 const char *file_name)
8761 int maxwrite = 64512;
8764 const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
8765 const char *local_name = talloc_asprintf(tctx, "%s/%s", d->local.driver_directory, file_name);
8766 const char *remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, file_name);
8768 if (!file_name || strlen(file_name) == 0) {
8772 torture_comment(tctx, "Uploading %s to %s\n", local_name, remote_name);
8774 fnum = smbcli_open(cli->tree, remote_name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
8776 torture_fail(tctx, talloc_asprintf(tctx, "failed to open remote file: %s\n", remote_name));
8779 f = x_fopen(local_name, O_RDONLY, 0);
8781 torture_fail(tctx, talloc_asprintf(tctx, "failed to open local file: %s\n", local_name));
8784 buf = talloc_array(tctx, uint8_t, maxwrite);
8789 while (!x_feof(f)) {
8793 if ((n = x_fread(buf, 1, n, f)) < 1) {
8794 if((n == 0) && x_feof(f))
8795 break; /* Empty local file. */
8797 torture_warning(tctx,
8798 "failed to read file: %s\n", strerror(errno));
8802 ret = smbcli_write(cli->tree, fnum, 0, buf, nread + start, n);
8805 torture_warning(tctx,
8806 "failed to write file: %s\n", smbcli_errstr(cli->tree));
8815 torture_assert_ntstatus_ok(tctx,
8816 smbcli_close(cli->tree, fnum),
8817 "failed to close file");
8822 static bool connect_printer_driver_share(struct torture_context *tctx,
8823 const char *server_name,
8824 const char *share_name,
8825 struct smbcli_state **cli)
8827 struct smbcli_options smb_options;
8828 struct smbcli_session_options smb_session_options;
8830 torture_comment(tctx, "Connecting printer driver share '%s' on '%s'\n",
8831 share_name, server_name);
8833 lpcfg_smbcli_options(tctx->lp_ctx, &smb_options);
8834 lpcfg_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
8836 torture_assert_ntstatus_ok(tctx,
8837 smbcli_full_connection(tctx, cli, server_name,
8838 lpcfg_smb_ports(tctx->lp_ctx),
8840 lpcfg_socket_options(tctx->lp_ctx),
8841 cmdline_credentials,
8842 lpcfg_resolve_context(tctx->lp_ctx),
8845 &smb_session_options,
8846 lpcfg_gensec_settings(tctx, tctx->lp_ctx)),
8847 "failed to open driver share");
8852 static bool upload_printer_driver(struct torture_context *tctx,
8853 const char *server_name,
8854 struct torture_driver_context *d)
8856 struct smbcli_state *cli;
8857 const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
8860 torture_assert(tctx,
8861 connect_printer_driver_share(tctx, server_name, share_name, &cli),
8862 "failed to connect to driver share");
8864 torture_comment(tctx, "Uploading printer driver files to \\\\%s\\%s\n",
8865 server_name, share_name);
8867 torture_assert(tctx,
8868 upload_printer_driver_file(tctx, cli, d, d->info8.driver_path),
8869 "failed to upload driver_path");
8870 torture_assert(tctx,
8871 upload_printer_driver_file(tctx, cli, d, d->info8.data_file),
8872 "failed to upload data_file");
8873 torture_assert(tctx,
8874 upload_printer_driver_file(tctx, cli, d, d->info8.config_file),
8875 "failed to upload config_file");
8876 torture_assert(tctx,
8877 upload_printer_driver_file(tctx, cli, d, d->info8.help_file),
8878 "failed to upload help_file");
8879 if (d->info8.dependent_files) {
8880 for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
8881 torture_assert(tctx,
8882 upload_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
8883 "failed to upload dependent_files");
8892 static bool remove_printer_driver_file(struct torture_context *tctx,
8893 struct smbcli_state *cli,
8894 struct torture_driver_context *d,
8895 const char *file_name)
8897 const char *remote_name;
8898 const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
8900 if (!file_name || strlen(file_name) == 0) {
8904 remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, file_name);
8906 torture_comment(tctx, "Removing %s\n", remote_name);
8908 torture_assert_ntstatus_ok(tctx,
8909 smbcli_unlink(cli->tree, remote_name),
8910 "failed to unlink");
8915 static bool remove_printer_driver(struct torture_context *tctx,
8916 const char *server_name,
8917 struct torture_driver_context *d)
8919 struct smbcli_state *cli;
8920 const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
8923 torture_assert(tctx,
8924 connect_printer_driver_share(tctx, server_name, share_name, &cli),
8925 "failed to connect to driver share");
8927 torture_comment(tctx, "Removing printer driver files from \\\\%s\\%s\n",
8928 server_name, share_name);
8930 torture_assert(tctx,
8931 remove_printer_driver_file(tctx, cli, d, d->info8.driver_path),
8932 "failed to remove driver_path");
8933 torture_assert(tctx,
8934 remove_printer_driver_file(tctx, cli, d, d->info8.data_file),
8935 "failed to remove data_file");
8936 if (!strequal(d->info8.config_file, d->info8.driver_path)) {
8937 torture_assert(tctx,
8938 remove_printer_driver_file(tctx, cli, d, d->info8.config_file),
8939 "failed to remove config_file");
8941 torture_assert(tctx,
8942 remove_printer_driver_file(tctx, cli, d, d->info8.help_file),
8943 "failed to remove help_file");
8944 if (d->info8.dependent_files) {
8945 for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
8946 if (strequal(d->info8.dependent_files->string[i], d->info8.driver_path) ||
8947 strequal(d->info8.dependent_files->string[i], d->info8.data_file) ||
8948 strequal(d->info8.dependent_files->string[i], d->info8.config_file) ||
8949 strequal(d->info8.dependent_files->string[i], d->info8.help_file)) {
8952 torture_assert(tctx,
8953 remove_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
8954 "failed to remove dependent_files");
8964 static bool test_add_driver_arg(struct torture_context *tctx,
8965 struct dcerpc_pipe *p,
8966 struct torture_driver_context *d)
8969 struct dcerpc_binding_handle *b = p->binding_handle;
8970 const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8971 uint32_t levels[] = { 1, 2, 3, 4, 6, 8 };
8973 struct spoolss_AddDriverInfo8 info8;
8974 uint32_t add_flags = APD_COPY_NEW_FILES;
8975 uint32_t delete_flags = 0;
8979 torture_comment(tctx, "Testing PrinterDriver%s '%s' for environment '%s'\n",
8980 d->ex ? "Ex" : "", d->info8.driver_name, d->local.environment);
8982 torture_assert(tctx,
8983 fillup_printserver_info(tctx, p, d),
8984 "failed to fillup printserver info");
8986 if (!directory_exist(d->local.driver_directory)) {
8987 torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
8990 torture_assert(tctx,
8991 upload_printer_driver(tctx, dcerpc_server_name(p), d),
8992 "failed to upload printer driver");
8994 info8.version = d->info8.version;
8995 info8.driver_name = d->info8.driver_name;
8996 info8.architecture = d->local.environment;
8997 info8.driver_path = d->info8.driver_path;
8998 info8.data_file = d->info8.data_file;
8999 info8.config_file = d->info8.config_file;
9001 for (i=0; i < ARRAY_SIZE(levels); i++) {
9003 if (torture_setting_bool(tctx, "samba3", false)) {
9004 switch (levels[i]) {
9008 torture_comment(tctx, "skipping level %d against samba\n", levels[i]);
9014 if (torture_setting_bool(tctx, "w2k3", false)) {
9015 switch (levels[i]) {
9017 torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
9024 torture_comment(tctx,
9025 "Testing PrinterDriver%s '%s' add & delete level %d\n",
9026 d->ex ? "Ex" : "", info8.driver_name, levels[i]);
9028 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);
9031 info8.driver_path = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.driver_path);
9032 info8.data_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.data_file);
9033 if (d->info8.config_file) {
9034 info8.config_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.config_file);
9037 for (i=0; i < ARRAY_SIZE(levels); i++) {
9039 if (torture_setting_bool(tctx, "samba3", false)) {
9040 switch (levels[i]) {
9044 torture_comment(tctx, "skipping level %d against samba\n", levels[i]);
9050 if (torture_setting_bool(tctx, "w2k3", false)) {
9051 switch (levels[i]) {
9053 torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
9060 torture_comment(tctx,
9061 "Testing PrinterDriver%s '%s' add & delete level %d (full unc paths)\n",
9062 d->ex ? "Ex" : "", info8.driver_name, levels[i]);
9064 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);
9067 torture_assert(tctx,
9068 remove_printer_driver(tctx, dcerpc_server_name(p), d),
9069 "failed to remove printer driver");
9071 torture_comment(tctx, "\n");
9076 static bool test_add_driver_ex_64(struct torture_context *tctx,
9077 struct dcerpc_pipe *p)
9079 struct torture_driver_context *d;
9081 d = talloc_zero(tctx, struct torture_driver_context);
9083 d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
9084 d->info8.driver_name = TORTURE_DRIVER_EX;
9085 d->info8.architecture = NULL;
9086 d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
9087 d->info8.data_file = talloc_strdup(d, "cups6.ppd");
9088 d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
9089 d->local.environment = talloc_strdup(d, "Windows x64");
9090 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
9093 return test_add_driver_arg(tctx, p, d);
9096 static bool test_add_driver_ex_32(struct torture_context *tctx,
9097 struct dcerpc_pipe *p)
9099 struct torture_driver_context *d;
9101 d = talloc_zero(tctx, struct torture_driver_context);
9103 d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
9104 d->info8.driver_name = TORTURE_DRIVER_EX;
9105 d->info8.architecture = NULL;
9106 d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
9107 d->info8.data_file = talloc_strdup(d, "cups6.ppd");
9108 d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
9109 d->local.environment = talloc_strdup(d, "Windows NT x86");
9110 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
9113 return test_add_driver_arg(tctx, p, d);
9116 static bool test_add_driver_64(struct torture_context *tctx,
9117 struct dcerpc_pipe *p)
9119 struct torture_driver_context *d;
9121 d = talloc_zero(tctx, struct torture_driver_context);
9123 d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
9124 d->info8.driver_name = TORTURE_DRIVER;
9125 d->info8.architecture = NULL;
9126 d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
9127 d->info8.data_file = talloc_strdup(d, "cups6.ppd");
9128 d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
9129 d->local.environment = talloc_strdup(d, "Windows x64");
9130 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
9133 return test_add_driver_arg(tctx, p, d);
9136 static bool test_add_driver_32(struct torture_context *tctx,
9137 struct dcerpc_pipe *p)
9139 struct torture_driver_context *d;
9141 d = talloc_zero(tctx, struct torture_driver_context);
9143 d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
9144 d->info8.driver_name = TORTURE_DRIVER;
9145 d->info8.architecture = NULL;
9146 d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
9147 d->info8.data_file = talloc_strdup(d, "cups6.ppd");
9148 d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
9149 d->local.environment = talloc_strdup(d, "Windows NT x86");
9150 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
9153 return test_add_driver_arg(tctx, p, d);
9156 static bool test_add_driver_adobe(struct torture_context *tctx,
9157 struct dcerpc_pipe *p)
9159 struct torture_driver_context *d;
9161 d = talloc_zero(tctx, struct torture_driver_context);
9163 d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
9164 d->info8.driver_name = TORTURE_DRIVER_ADOBE;
9165 d->info8.architecture = NULL;
9166 d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
9167 d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
9168 d->info8.config_file = talloc_strdup(d, "ADOBEPS4.DRV");
9170 d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
9171 d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
9173 d->local.environment = talloc_strdup(d, "Windows 4.0");
9174 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
9177 return test_add_driver_arg(tctx, p, d);
9180 static bool test_add_driver_adobe_cupsaddsmb(struct torture_context *tctx,
9181 struct dcerpc_pipe *p)
9183 struct torture_driver_context *d;
9184 struct spoolss_StringArray *a;
9186 if (!torture_setting_bool(tctx, "samba3", false)) {
9187 torture_skip(tctx, "skipping cupsaddsmb test which only works against samba3");
9190 d = talloc_zero(tctx, struct torture_driver_context);
9192 d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
9193 d->info8.driver_name = TORTURE_DRIVER_ADOBE_CUPSADDSMB;
9194 d->info8.architecture = NULL;
9195 d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
9196 d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
9197 d->info8.config_file = NULL;
9198 d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
9199 d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
9200 d->info8.default_datatype = talloc_strdup(d, "RAW");
9202 a = talloc_zero(d, struct spoolss_StringArray);
9203 a->string = talloc_zero_array(a, const char *, 7);
9204 a->string[0] = talloc_strdup(a->string, "ADOBEPS4.DRV");
9205 a->string[1] = talloc_strdup(a->string, "DEFPRTR2.PPD");
9206 a->string[2] = talloc_strdup(a->string, "ADOBEPS4.HLP");
9207 a->string[3] = talloc_strdup(a->string, "PSMON.DLL");
9208 a->string[4] = talloc_strdup(a->string, "ADFONTS.MFM");
9209 a->string[5] = talloc_strdup(a->string, "ICONLIB.DLL");
9211 d->info8.dependent_files = a;
9212 d->local.environment = talloc_strdup(d, "Windows 4.0");
9213 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
9216 return test_add_driver_arg(tctx, p, d);
9219 static bool test_add_driver_timestamps(struct torture_context *tctx,
9220 struct dcerpc_pipe *p)
9222 struct torture_driver_context *d;
9223 struct timeval t = timeval_current();
9225 if (torture_setting_bool(tctx, "samba3", false)) {
9226 torture_skip(tctx, "skipping timestamps test against samba");
9229 d = talloc_zero(tctx, struct torture_driver_context);
9231 d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
9232 d->info8.driver_name = TORTURE_DRIVER_TIMESTAMPS;
9233 d->info8.architecture = NULL;
9234 d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
9235 d->info8.data_file = talloc_strdup(d, "cups6.ppd");
9236 d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
9237 d->info8.driver_date = timeval_to_nttime(&t);
9238 d->local.environment = talloc_strdup(d, "Windows NT x86");
9239 d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
9242 torture_assert(tctx,
9243 test_add_driver_arg(tctx, p, d),
9246 unix_to_nt_time(&d->info8.driver_date, 1);
9248 torture_assert(tctx,
9249 test_add_driver_arg(tctx, p, d),
9255 struct torture_suite *torture_rpc_spoolss_driver(TALLOC_CTX *mem_ctx)
9257 struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.driver");
9259 struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
9260 "driver", &ndr_table_spoolss);
9261 torture_rpc_tcase_add_test(tcase, "add_driver_64", test_add_driver_64);
9262 torture_rpc_tcase_add_test(tcase, "add_driver_ex_64", test_add_driver_ex_64);
9264 torture_rpc_tcase_add_test(tcase, "add_driver_32", test_add_driver_32);
9265 torture_rpc_tcase_add_test(tcase, "add_driver_ex_32", test_add_driver_ex_32);
9267 torture_rpc_tcase_add_test(tcase, "add_driver_adobe", test_add_driver_adobe);
9269 torture_rpc_tcase_add_test(tcase, "add_driver_adobe_cupsaddsmb", test_add_driver_adobe_cupsaddsmb);
9271 torture_rpc_tcase_add_test(tcase, "add_driver_timestamps", test_add_driver_timestamps);