s4-smbtorture: print SPOOLSS_JOB_CONTROL flags in RPC-SPOOLSS test.
[Samba/gbeck.git] / source4 / torture / rpc / spoolss.c
blobd17b3c7b609dd3cf7f9d848341c33b5c2b55c5ea
1 /*
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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "torture/rpc/rpc.h"
26 #include "librpc/gen_ndr/ndr_spoolss_c.h"
28 struct test_spoolss_context {
29 /* print server handle */
30 struct policy_handle server_handle;
32 /* for EnumPorts */
33 uint32_t port_count[3];
34 union spoolss_PortInfo *ports[3];
36 /* for EnumPrinterDrivers */
37 uint32_t driver_count[7];
38 union spoolss_DriverInfo *drivers[7];
40 /* for EnumMonitors */
41 uint32_t monitor_count[3];
42 union spoolss_MonitorInfo *monitors[3];
44 /* for EnumPrintProcessors */
45 uint32_t print_processor_count[2];
46 union spoolss_PrintProcessorInfo *print_processors[2];
48 /* for EnumPrinters */
49 uint32_t printer_count[6];
50 union spoolss_PrinterInfo *printers[6];
53 #define COMPARE_STRING(tctx, c,r,e) \
54 torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
56 /* not every compiler supports __typeof__() */
57 #if (__GNUC__ >= 3)
58 #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
59 if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
60 torture_fail(tctx, #c "." #e "field is not " #type "\n"); \
62 if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
63 torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
65 } while(0)
66 #else
67 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
68 #endif
70 #define COMPARE_UINT32(tctx, c, r, e) do {\
71 _CHECK_FIELD_SIZE(c, r, e, uint32_t); \
72 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
73 } while(0)
75 #define COMPARE_STRING_ARRAY(tctx, c,r,e)
77 static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx)
79 NTSTATUS status;
80 struct spoolss_OpenPrinter op;
82 op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
83 op.in.datatype = NULL;
84 op.in.devmode_ctr.devmode= NULL;
85 op.in.access_mask = 0;
86 op.out.handle = &ctx->server_handle;
88 torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
90 status = dcerpc_spoolss_OpenPrinter(p, ctx, &op);
91 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
92 torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
94 return true;
97 static bool test_EnumPorts(struct torture_context *tctx,
98 struct dcerpc_pipe *p,
99 struct test_spoolss_context *ctx)
101 NTSTATUS status;
102 struct spoolss_EnumPorts r;
103 uint16_t levels[] = { 1, 2 };
104 int i, j;
106 for (i=0;i<ARRAY_SIZE(levels);i++) {
107 int level = levels[i];
108 DATA_BLOB blob;
109 uint32_t needed;
110 uint32_t count;
111 union spoolss_PortInfo *info;
113 r.in.servername = "";
114 r.in.level = level;
115 r.in.buffer = NULL;
116 r.in.offered = 0;
117 r.out.needed = &needed;
118 r.out.count = &count;
119 r.out.info = &info;
121 torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
123 status = dcerpc_spoolss_EnumPorts(p, ctx, &r);
124 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
125 if (W_ERROR_IS_OK(r.out.result)) {
126 /* TODO: do some more checks here */
127 continue;
129 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
130 "EnumPorts unexpected return code");
132 blob = data_blob_talloc(ctx, NULL, needed);
133 data_blob_clear(&blob);
134 r.in.buffer = &blob;
135 r.in.offered = needed;
137 status = dcerpc_spoolss_EnumPorts(p, ctx, &r);
138 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
140 torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
142 torture_assert(tctx, info, "EnumPorts returned no info");
144 ctx->port_count[level] = count;
145 ctx->ports[level] = info;
148 for (i=1;i<ARRAY_SIZE(levels);i++) {
149 int level = levels[i];
150 int old_level = levels[i-1];
151 torture_assert_int_equal(tctx, ctx->port_count[level], ctx->port_count[old_level],
152 "EnumPorts invalid value");
154 /* if the array sizes are not the same we would maybe segfault in the following code */
156 for (i=0;i<ARRAY_SIZE(levels);i++) {
157 int level = levels[i];
158 for (j=0;j<ctx->port_count[level];j++) {
159 union spoolss_PortInfo *cur = &ctx->ports[level][j];
160 union spoolss_PortInfo *ref = &ctx->ports[2][j];
161 switch (level) {
162 case 1:
163 COMPARE_STRING(tctx, cur->info1, ref->info2, port_name);
164 break;
165 case 2:
166 /* level 2 is our reference, and it makes no sense to compare it to itself */
167 break;
172 return true;
175 static bool test_GetPrintProcessorDirectory(struct torture_context *tctx,
176 struct dcerpc_pipe *p,
177 struct test_spoolss_context *ctx)
179 NTSTATUS status;
180 struct spoolss_GetPrintProcessorDirectory r;
181 struct {
182 uint16_t level;
183 const char *server;
184 } levels[] = {{
185 .level = 1,
186 .server = NULL
188 .level = 1,
189 .server = ""
191 .level = 78,
192 .server = ""
194 .level = 1,
195 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
197 .level = 1024,
198 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
201 int i;
202 uint32_t needed;
204 for (i=0;i<ARRAY_SIZE(levels);i++) {
205 int level = levels[i].level;
206 DATA_BLOB blob;
208 r.in.server = levels[i].server;
209 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
210 r.in.level = level;
211 r.in.buffer = NULL;
212 r.in.offered = 0;
213 r.out.needed = &needed;
215 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %u\n", r.in.level);
217 status = dcerpc_spoolss_GetPrintProcessorDirectory(p, ctx, &r);
218 torture_assert_ntstatus_ok(tctx, status,
219 "dcerpc_spoolss_GetPrintProcessorDirectory failed");
220 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
221 "GetPrintProcessorDirectory unexpected return code");
223 blob = data_blob_talloc(ctx, NULL, needed);
224 data_blob_clear(&blob);
225 r.in.buffer = &blob;
226 r.in.offered = needed;
228 status = dcerpc_spoolss_GetPrintProcessorDirectory(p, ctx, &r);
229 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
231 torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
234 return true;
238 static bool test_GetPrinterDriverDirectory(struct torture_context *tctx,
239 struct dcerpc_pipe *p,
240 struct test_spoolss_context *ctx)
242 NTSTATUS status;
243 struct spoolss_GetPrinterDriverDirectory r;
244 struct {
245 uint16_t level;
246 const char *server;
247 } levels[] = {{
248 .level = 1,
249 .server = NULL
251 .level = 1,
252 .server = ""
254 .level = 78,
255 .server = ""
257 .level = 1,
258 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
260 .level = 1024,
261 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
264 int i;
265 uint32_t needed;
267 for (i=0;i<ARRAY_SIZE(levels);i++) {
268 int level = levels[i].level;
269 DATA_BLOB blob;
271 r.in.server = levels[i].server;
272 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
273 r.in.level = level;
274 r.in.buffer = NULL;
275 r.in.offered = 0;
276 r.out.needed = &needed;
278 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %u\n", r.in.level);
280 status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r);
281 torture_assert_ntstatus_ok(tctx, status,
282 "dcerpc_spoolss_GetPrinterDriverDirectory failed");
283 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
284 "GetPrinterDriverDirectory unexpected return code");
286 blob = data_blob_talloc(ctx, NULL, needed);
287 data_blob_clear(&blob);
288 r.in.buffer = &blob;
289 r.in.offered = needed;
291 status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r);
292 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
294 torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
297 return true;
300 static bool test_EnumPrinterDrivers(struct torture_context *tctx,
301 struct dcerpc_pipe *p,
302 struct test_spoolss_context *ctx)
304 NTSTATUS status;
305 struct spoolss_EnumPrinterDrivers r;
306 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
307 int i, j;
309 for (i=0;i<ARRAY_SIZE(levels);i++) {
310 int level = levels[i];
311 DATA_BLOB blob;
312 uint32_t needed;
313 uint32_t count;
314 union spoolss_DriverInfo *info;
316 r.in.server = "";
317 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
318 r.in.level = level;
319 r.in.buffer = NULL;
320 r.in.offered = 0;
321 r.out.needed = &needed;
322 r.out.count = &count;
323 r.out.info = &info;
325 torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
327 status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r);
328 torture_assert_ntstatus_ok(tctx, status,
329 "dcerpc_spoolss_EnumPrinterDrivers failed");
330 if (W_ERROR_IS_OK(r.out.result)) {
331 /* TODO: do some more checks here */
332 continue;
334 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
335 "EnumPrinterDrivers failed");
337 blob = data_blob_talloc(ctx, NULL, needed);
338 data_blob_clear(&blob);
339 r.in.buffer = &blob;
340 r.in.offered = needed;
342 status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r);
343 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinterDrivers failed");
345 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
347 ctx->driver_count[level] = count;
348 ctx->drivers[level] = info;
351 for (i=1;i<ARRAY_SIZE(levels);i++) {
352 int level = levels[i];
353 int old_level = levels[i-1];
354 torture_assert_int_equal(tctx, ctx->driver_count[level], ctx->driver_count[old_level],
355 "EnumPrinterDrivers invalid value");
358 for (i=0;i<ARRAY_SIZE(levels);i++) {
359 int level = levels[i];
360 for (j=0;j<ctx->driver_count[level];j++) {
361 union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
362 union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
363 switch (level) {
364 case 1:
365 COMPARE_STRING(tctx, cur->info1, ref->info6, driver_name);
366 break;
367 case 2:
368 COMPARE_UINT32(tctx, cur->info2, ref->info6, version);
369 COMPARE_STRING(tctx, cur->info2, ref->info6, driver_name);
370 COMPARE_STRING(tctx, cur->info2, ref->info6, architecture);
371 COMPARE_STRING(tctx, cur->info2, ref->info6, driver_path);
372 COMPARE_STRING(tctx, cur->info2, ref->info6, data_file);
373 COMPARE_STRING(tctx, cur->info2, ref->info6, config_file);
374 break;
375 case 3:
376 COMPARE_UINT32(tctx, cur->info3, ref->info6, version);
377 COMPARE_STRING(tctx, cur->info3, ref->info6, driver_name);
378 COMPARE_STRING(tctx, cur->info3, ref->info6, architecture);
379 COMPARE_STRING(tctx, cur->info3, ref->info6, driver_path);
380 COMPARE_STRING(tctx, cur->info3, ref->info6, data_file);
381 COMPARE_STRING(tctx, cur->info3, ref->info6, config_file);
382 COMPARE_STRING(tctx, cur->info3, ref->info6, help_file);
383 COMPARE_STRING_ARRAY(tctx, cur->info3, ref->info6, dependent_files);
384 COMPARE_STRING(tctx, cur->info3, ref->info6, monitor_name);
385 COMPARE_STRING(tctx, cur->info3, ref->info6, default_datatype);
386 break;
387 case 4:
388 COMPARE_UINT32(tctx, cur->info4, ref->info6, version);
389 COMPARE_STRING(tctx, cur->info4, ref->info6, driver_name);
390 COMPARE_STRING(tctx, cur->info4, ref->info6, architecture);
391 COMPARE_STRING(tctx, cur->info4, ref->info6, driver_path);
392 COMPARE_STRING(tctx, cur->info4, ref->info6, data_file);
393 COMPARE_STRING(tctx, cur->info4, ref->info6, config_file);
394 COMPARE_STRING(tctx, cur->info4, ref->info6, help_file);
395 COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, dependent_files);
396 COMPARE_STRING(tctx, cur->info4, ref->info6, monitor_name);
397 COMPARE_STRING(tctx, cur->info4, ref->info6, default_datatype);
398 COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, previous_names);
399 break;
400 case 5:
401 COMPARE_UINT32(tctx, cur->info5, ref->info6, version);
402 COMPARE_STRING(tctx, cur->info5, ref->info6, driver_name);
403 COMPARE_STRING(tctx, cur->info5, ref->info6, architecture);
404 COMPARE_STRING(tctx, cur->info5, ref->info6, driver_path);
405 COMPARE_STRING(tctx, cur->info5, ref->info6, data_file);
406 COMPARE_STRING(tctx, cur->info5, ref->info6, config_file);
407 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/
408 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/
409 /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_version); */
410 break;
411 case 6:
412 /* level 6 is our reference, and it makes no sense to compare it to itself */
413 break;
418 return true;
421 static bool test_EnumMonitors(struct torture_context *tctx,
422 struct dcerpc_pipe *p,
423 struct test_spoolss_context *ctx)
425 NTSTATUS status;
426 struct spoolss_EnumMonitors r;
427 uint16_t levels[] = { 1, 2 };
428 int i, j;
430 for (i=0;i<ARRAY_SIZE(levels);i++) {
431 int level = levels[i];
432 DATA_BLOB blob;
433 uint32_t needed;
434 uint32_t count;
435 union spoolss_MonitorInfo *info;
437 r.in.servername = "";
438 r.in.level = level;
439 r.in.buffer = NULL;
440 r.in.offered = 0;
441 r.out.needed = &needed;
442 r.out.count = &count;
443 r.out.info = &info;
445 torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
447 status = dcerpc_spoolss_EnumMonitors(p, ctx, &r);
448 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
449 if (W_ERROR_IS_OK(r.out.result)) {
450 /* TODO: do some more checks here */
451 continue;
453 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
454 "EnumMonitors failed");
456 blob = data_blob_talloc(ctx, NULL, needed);
457 data_blob_clear(&blob);
458 r.in.buffer = &blob;
459 r.in.offered = needed;
461 status = dcerpc_spoolss_EnumMonitors(p, ctx, &r);
462 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
464 torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
466 ctx->monitor_count[level] = count;
467 ctx->monitors[level] = info;
470 for (i=1;i<ARRAY_SIZE(levels);i++) {
471 int level = levels[i];
472 int old_level = levels[i-1];
473 torture_assert_int_equal(tctx, ctx->monitor_count[level], ctx->monitor_count[old_level],
474 "EnumMonitors invalid value");
477 for (i=0;i<ARRAY_SIZE(levels);i++) {
478 int level = levels[i];
479 for (j=0;j<ctx->monitor_count[level];j++) {
480 union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
481 union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
482 switch (level) {
483 case 1:
484 COMPARE_STRING(tctx, cur->info1, ref->info2, monitor_name);
485 break;
486 case 2:
487 /* level 2 is our reference, and it makes no sense to compare it to itself */
488 break;
493 return true;
496 static bool test_EnumPrintProcessors(struct torture_context *tctx,
497 struct dcerpc_pipe *p,
498 struct test_spoolss_context *ctx)
500 NTSTATUS status;
501 struct spoolss_EnumPrintProcessors r;
502 uint16_t levels[] = { 1 };
503 int i, j;
505 for (i=0;i<ARRAY_SIZE(levels);i++) {
506 int level = levels[i];
507 DATA_BLOB blob;
508 uint32_t needed;
509 uint32_t count;
510 union spoolss_PrintProcessorInfo *info;
512 r.in.servername = "";
513 r.in.environment = "Windows NT x86";
514 r.in.level = level;
515 r.in.buffer = NULL;
516 r.in.offered = 0;
517 r.out.needed = &needed;
518 r.out.count = &count;
519 r.out.info = &info;
521 torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level);
523 status = dcerpc_spoolss_EnumPrintProcessors(p, ctx, &r);
524 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
525 if (W_ERROR_IS_OK(r.out.result)) {
526 /* TODO: do some more checks here */
527 continue;
529 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
530 "EnumPrintProcessors unexpected return code");
532 blob = data_blob_talloc(ctx, NULL, needed);
533 data_blob_clear(&blob);
534 r.in.buffer = &blob;
535 r.in.offered = needed;
537 status = dcerpc_spoolss_EnumPrintProcessors(p, ctx, &r);
538 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
540 torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
542 ctx->print_processor_count[level] = count;
543 ctx->print_processors[level] = info;
546 for (i=1;i<ARRAY_SIZE(levels);i++) {
547 int level = levels[i];
548 int old_level = levels[i-1];
549 torture_assert_int_equal(tctx, ctx->print_processor_count[level], ctx->print_processor_count[old_level],
550 "EnumPrintProcessors failed");
553 for (i=0;i<ARRAY_SIZE(levels);i++) {
554 int level = levels[i];
555 for (j=0;j<ctx->print_processor_count[level];j++) {
556 #if 0
557 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
558 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
559 #endif
560 switch (level) {
561 case 1:
562 /* level 1 is our reference, and it makes no sense to compare it to itself */
563 break;
568 return true;
571 static bool test_EnumPrintProcDataTypes(struct torture_context *tctx,
572 struct dcerpc_pipe *p,
573 struct test_spoolss_context *ctx)
575 NTSTATUS status;
576 struct spoolss_EnumPrintProcDataTypes r;
577 uint16_t levels[] = { 1 };
578 int i;
580 for (i=0;i<ARRAY_SIZE(levels);i++) {
581 int level = levels[i];
582 DATA_BLOB blob;
583 uint32_t needed;
584 uint32_t count;
585 union spoolss_PrintProcDataTypesInfo *info;
587 r.in.servername = "";
588 r.in.print_processor_name = "winprint";
589 r.in.level = level;
590 r.in.buffer = NULL;
591 r.in.offered = 0;
592 r.out.needed = &needed;
593 r.out.count = &count;
594 r.out.info = &info;
596 torture_comment(tctx, "Testing EnumPrintProcDataTypes level %u\n", r.in.level);
598 status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r);
599 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataType failed");
600 if (W_ERROR_IS_OK(r.out.result)) {
601 /* TODO: do some more checks here */
602 continue;
604 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
605 "EnumPrintProcDataTypes unexpected return code");
607 blob = data_blob_talloc(ctx, NULL, needed);
608 data_blob_clear(&blob);
609 r.in.buffer = &blob;
610 r.in.offered = needed;
612 status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r);
613 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
615 torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed");
618 return true;
622 static bool test_EnumPrinters(struct torture_context *tctx,
623 struct dcerpc_pipe *p,
624 struct test_spoolss_context *ctx)
626 struct spoolss_EnumPrinters r;
627 NTSTATUS status;
628 uint16_t levels[] = { 0, 1, 2, 4, 5 };
629 int i, j;
631 for (i=0;i<ARRAY_SIZE(levels);i++) {
632 int level = levels[i];
633 DATA_BLOB blob;
634 uint32_t needed;
635 uint32_t count;
636 union spoolss_PrinterInfo *info;
638 r.in.flags = PRINTER_ENUM_LOCAL;
639 r.in.server = "";
640 r.in.level = level;
641 r.in.buffer = NULL;
642 r.in.offered = 0;
643 r.out.needed = &needed;
644 r.out.count = &count;
645 r.out.info = &info;
647 torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
649 status = dcerpc_spoolss_EnumPrinters(p, ctx, &r);
650 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
651 if (W_ERROR_IS_OK(r.out.result)) {
652 /* TODO: do some more checks here */
653 continue;
655 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
656 "EnumPrinters unexpected return code");
658 blob = data_blob_talloc(ctx, NULL, needed);
659 data_blob_clear(&blob);
660 r.in.buffer = &blob;
661 r.in.offered = needed;
663 status = dcerpc_spoolss_EnumPrinters(p, ctx, &r);
664 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
666 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
668 ctx->printer_count[level] = count;
669 ctx->printers[level] = info;
672 for (i=1;i<ARRAY_SIZE(levels);i++) {
673 int level = levels[i];
674 int old_level = levels[i-1];
675 torture_assert_int_equal(tctx, ctx->printer_count[level], ctx->printer_count[old_level],
676 "EnumPrinters invalid value");
679 for (i=0;i<ARRAY_SIZE(levels);i++) {
680 int level = levels[i];
681 for (j=0;j<ctx->printer_count[level];j++) {
682 union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
683 union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
684 switch (level) {
685 case 0:
686 COMPARE_STRING(tctx, cur->info0, ref->info2, printername);
687 COMPARE_STRING(tctx, cur->info0, ref->info2, servername);
688 COMPARE_UINT32(tctx, cur->info0, ref->info2, cjobs);
689 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
690 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
691 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
692 COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
693 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
694 COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
695 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
696 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
697 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
698 COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
699 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
700 COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
701 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
702 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
703 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
704 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
705 COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
706 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
707 COMPARE_UINT32(tctx, cur->info0, ref->info2, status);
708 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
709 COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
710 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
711 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
712 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
713 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
714 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
715 break;
716 case 1:
717 /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
718 /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
719 /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
720 COMPARE_STRING(tctx, cur->info1, ref->info2, comment);
721 break;
722 case 2:
723 /* level 2 is our reference, and it makes no sense to compare it to itself */
724 break;
725 case 4:
726 COMPARE_STRING(tctx, cur->info4, ref->info2, printername);
727 COMPARE_STRING(tctx, cur->info4, ref->info2, servername);
728 COMPARE_UINT32(tctx, cur->info4, ref->info2, attributes);
729 break;
730 case 5:
731 COMPARE_STRING(tctx, cur->info5, ref->info2, printername);
732 COMPARE_STRING(tctx, cur->info5, ref->info2, portname);
733 COMPARE_UINT32(tctx, cur->info5, ref->info2, attributes);
734 /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
735 COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
736 break;
741 /* TODO:
742 * - verify that the port of a printer was in the list returned by EnumPorts
745 return true;
748 static bool test_GetPrinter(struct torture_context *tctx,
749 struct dcerpc_pipe *p,
750 struct policy_handle *handle)
752 NTSTATUS status;
753 struct spoolss_GetPrinter r;
754 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
755 int i;
756 uint32_t needed;
758 for (i=0;i<ARRAY_SIZE(levels);i++) {
759 r.in.handle = handle;
760 r.in.level = levels[i];
761 r.in.buffer = NULL;
762 r.in.offered = 0;
763 r.out.needed = &needed;
765 torture_comment(tctx, "Testing GetPrinter level %u\n", r.in.level);
767 status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
768 torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
770 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
771 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
772 data_blob_clear(&blob);
773 r.in.buffer = &blob;
774 r.in.offered = needed;
775 status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
778 torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
780 torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
783 return true;
787 static bool test_ClosePrinter(struct torture_context *tctx,
788 struct dcerpc_pipe *p,
789 struct policy_handle *handle)
791 NTSTATUS status;
792 struct spoolss_ClosePrinter r;
794 r.in.handle = handle;
795 r.out.handle = handle;
797 torture_comment(tctx, "Testing ClosePrinter\n");
799 status = dcerpc_spoolss_ClosePrinter(p, tctx, &r);
800 torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
802 return true;
805 static bool test_GetForm(struct torture_context *tctx,
806 struct dcerpc_pipe *p,
807 struct policy_handle *handle,
808 const char *form_name,
809 uint32_t level)
811 NTSTATUS status;
812 struct spoolss_GetForm r;
813 uint32_t needed;
815 r.in.handle = handle;
816 r.in.form_name = form_name;
817 r.in.level = level;
818 r.in.buffer = NULL;
819 r.in.offered = 0;
820 r.out.needed = &needed;
822 torture_comment(tctx, "Testing GetForm level %d\n", r.in.level);
824 status = dcerpc_spoolss_GetForm(p, tctx, &r);
825 torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
827 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
828 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
829 data_blob_clear(&blob);
830 r.in.buffer = &blob;
831 r.in.offered = needed;
832 status = dcerpc_spoolss_GetForm(p, tctx, &r);
833 torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
835 torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
837 torture_assert(tctx, r.out.info, "No form info returned");
840 torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
842 return true;
845 static bool test_EnumForms(struct torture_context *tctx,
846 struct dcerpc_pipe *p,
847 struct policy_handle *handle, bool print_server)
849 NTSTATUS status;
850 struct spoolss_EnumForms r;
851 bool ret = true;
852 uint32_t needed;
853 uint32_t count;
854 uint32_t levels[] = { 1, 2 };
855 int i;
857 for (i=0; i<ARRAY_SIZE(levels); i++) {
859 union spoolss_FormInfo *info;
861 r.in.handle = handle;
862 r.in.level = levels[i];
863 r.in.buffer = NULL;
864 r.in.offered = 0;
865 r.out.needed = &needed;
866 r.out.count = &count;
867 r.out.info = &info;
869 torture_comment(tctx, "Testing EnumForms level %d\n", levels[i]);
871 status = dcerpc_spoolss_EnumForms(p, tctx, &r);
872 torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
874 if ((r.in.level == 2) && (W_ERROR_EQUAL(r.out.result, WERR_UNKNOWN_LEVEL))) {
875 break;
878 if (print_server && W_ERROR_EQUAL(r.out.result, WERR_BADFID))
879 torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
881 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
882 int j;
883 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
884 data_blob_clear(&blob);
885 r.in.buffer = &blob;
886 r.in.offered = needed;
888 status = dcerpc_spoolss_EnumForms(p, tctx, &r);
890 torture_assert(tctx, info, "No forms returned");
892 for (j = 0; j < count; j++) {
893 if (!print_server)
894 ret &= test_GetForm(tctx, p, handle, info[j].info1.form_name, levels[i]);
898 torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
900 torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
903 return true;
906 static bool test_DeleteForm(struct torture_context *tctx,
907 struct dcerpc_pipe *p,
908 struct policy_handle *handle,
909 const char *form_name)
911 NTSTATUS status;
912 struct spoolss_DeleteForm r;
914 r.in.handle = handle;
915 r.in.form_name = form_name;
917 status = dcerpc_spoolss_DeleteForm(p, tctx, &r);
919 torture_assert_ntstatus_ok(tctx, status, "DeleteForm failed");
921 torture_assert_werr_ok(tctx, r.out.result, "DeleteForm failed");
923 return true;
926 static bool test_AddForm(struct torture_context *tctx,
927 struct dcerpc_pipe *p,
928 struct policy_handle *handle, bool print_server)
930 struct spoolss_AddForm r;
931 struct spoolss_AddFormInfo1 addform;
932 const char *form_name = "testform3";
933 NTSTATUS status;
934 bool ret = true;
936 r.in.handle = handle;
937 r.in.level = 1;
938 r.in.info.info1 = &addform;
939 addform.flags = SPOOLSS_FORM_USER;
940 addform.form_name = form_name;
941 addform.size.width = 50;
942 addform.size.height = 25;
943 addform.area.left = 5;
944 addform.area.top = 10;
945 addform.area.right = 45;
946 addform.area.bottom = 15;
948 status = dcerpc_spoolss_AddForm(p, tctx, &r);
950 torture_assert_ntstatus_ok(tctx, status, "AddForm failed");
952 torture_assert_werr_ok(tctx, r.out.result, "AddForm failed");
954 if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name, 1);
957 struct spoolss_SetForm sf;
958 struct spoolss_AddFormInfo1 setform;
960 sf.in.handle = handle;
961 sf.in.form_name = form_name;
962 sf.in.level = 1;
963 sf.in.info.info1= &setform;
964 setform.flags = addform.flags;
965 setform.form_name = addform.form_name;
966 setform.size = addform.size;
967 setform.area = addform.area;
969 setform.size.width = 1234;
971 status = dcerpc_spoolss_SetForm(p, tctx, &sf);
973 torture_assert_ntstatus_ok(tctx, status, "SetForm failed");
975 torture_assert_werr_ok(tctx, r.out.result, "SetForm failed");
978 if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name, 1);
980 if (!test_DeleteForm(tctx, p, handle, form_name)) {
981 ret = false;
984 return ret;
987 static bool test_EnumPorts_old(struct torture_context *tctx,
988 struct dcerpc_pipe *p)
990 NTSTATUS status;
991 struct spoolss_EnumPorts r;
992 uint32_t needed;
993 uint32_t count;
994 union spoolss_PortInfo *info;
996 r.in.servername = talloc_asprintf(tctx, "\\\\%s",
997 dcerpc_server_name(p));
998 r.in.level = 2;
999 r.in.buffer = NULL;
1000 r.in.offered = 0;
1001 r.out.needed = &needed;
1002 r.out.count = &count;
1003 r.out.info = &info;
1005 torture_comment(tctx, "Testing EnumPorts\n");
1007 status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
1009 torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
1011 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1012 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
1013 data_blob_clear(&blob);
1014 r.in.buffer = &blob;
1015 r.in.offered = needed;
1017 status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
1018 torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
1020 torture_assert(tctx, info, "No ports returned");
1023 return true;
1026 static bool test_AddPort(struct torture_context *tctx,
1027 struct dcerpc_pipe *p)
1029 NTSTATUS status;
1030 struct spoolss_AddPort r;
1032 r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
1033 dcerpc_server_name(p));
1034 r.in.unknown = 0;
1035 r.in.monitor_name = "foo";
1037 torture_comment(tctx, "Testing AddPort\n");
1039 status = dcerpc_spoolss_AddPort(p, tctx, &r);
1041 torture_assert_ntstatus_ok(tctx, status, "AddPort failed");
1043 /* win2k3 returns WERR_NOT_SUPPORTED */
1045 #if 0
1047 if (!W_ERROR_IS_OK(r.out.result)) {
1048 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1049 return false;
1052 #endif
1054 return true;
1057 static bool test_GetJob(struct torture_context *tctx,
1058 struct dcerpc_pipe *p,
1059 struct policy_handle *handle, uint32_t job_id)
1061 NTSTATUS status;
1062 struct spoolss_GetJob r;
1063 uint32_t needed;
1065 r.in.handle = handle;
1066 r.in.job_id = job_id;
1067 r.in.level = 1;
1068 r.in.buffer = NULL;
1069 r.in.offered = 0;
1070 r.out.needed = &needed;
1072 torture_comment(tctx, "Testing GetJob\n");
1074 status = dcerpc_spoolss_GetJob(p, tctx, &r);
1075 torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
1077 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1078 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
1079 data_blob_clear(&blob);
1080 r.in.buffer = &blob;
1081 r.in.offered = needed;
1083 status = dcerpc_spoolss_GetJob(p, tctx, &r);
1085 torture_assert(tctx, r.out.info, "No job info returned");
1088 return true;
1091 static bool test_SetJob(struct torture_context *tctx,
1092 struct dcerpc_pipe *p,
1093 struct policy_handle *handle, uint32_t job_id,
1094 enum spoolss_JobControl command)
1096 NTSTATUS status;
1097 struct spoolss_SetJob r;
1099 r.in.handle = handle;
1100 r.in.job_id = job_id;
1101 r.in.ctr = NULL;
1102 r.in.command = command;
1104 switch (command) {
1105 case SPOOLSS_JOB_CONTROL_PAUSE:
1106 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_PAUSE\n");
1107 break;
1108 case SPOOLSS_JOB_CONTROL_RESUME:
1109 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESUME\n");
1110 break;
1111 case SPOOLSS_JOB_CONTROL_CANCEL:
1112 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_CANCEL\n");
1113 break;
1114 case SPOOLSS_JOB_CONTROL_RESTART:
1115 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESTART\n");
1116 break;
1117 case SPOOLSS_JOB_CONTROL_DELETE:
1118 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_DELETE\n");
1119 break;
1120 case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER:
1121 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n");
1122 break;
1123 case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED:
1124 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n");
1125 break;
1126 case SPOOLSS_JOB_CONTROL_RETAIN:
1127 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RETAIN\n");
1128 break;
1129 case SPOOLSS_JOB_CONTROL_RELEASE:
1130 torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RELEASE\n");
1131 break;
1132 default:
1133 torture_comment(tctx, "Testing SetJob\n");
1134 break;
1137 status = dcerpc_spoolss_SetJob(p, tctx, &r);
1138 torture_assert_ntstatus_ok(tctx, status, "SetJob failed");
1139 torture_assert_werr_ok(tctx, r.out.result, "SetJob failed");
1141 return true;
1144 static bool test_AddJob(struct torture_context *tctx,
1145 struct dcerpc_pipe *p,
1146 struct policy_handle *handle)
1148 NTSTATUS status;
1149 struct spoolss_AddJob r;
1150 uint32_t needed;
1152 r.in.level = 0;
1153 r.in.handle = handle;
1154 r.in.offered = 0;
1155 r.out.needed = &needed;
1156 r.in.buffer = r.out.buffer = NULL;
1158 torture_comment(tctx, "Testing AddJob\n");
1160 status = dcerpc_spoolss_AddJob(p, tctx, &r);
1161 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "AddJob failed");
1163 r.in.level = 1;
1165 status = dcerpc_spoolss_AddJob(p, tctx, &r);
1166 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, "AddJob failed");
1168 return true;
1172 static bool test_EnumJobs(struct torture_context *tctx,
1173 struct dcerpc_pipe *p,
1174 struct policy_handle *handle)
1176 NTSTATUS status;
1177 struct spoolss_EnumJobs r;
1178 uint32_t needed;
1179 uint32_t count;
1180 union spoolss_JobInfo *info;
1182 r.in.handle = handle;
1183 r.in.firstjob = 0;
1184 r.in.numjobs = 0xffffffff;
1185 r.in.level = 1;
1186 r.in.buffer = NULL;
1187 r.in.offered = 0;
1188 r.out.needed = &needed;
1189 r.out.count = &count;
1190 r.out.info = &info;
1192 torture_comment(tctx, "Testing EnumJobs\n");
1194 status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
1196 torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
1198 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1199 int j;
1200 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
1201 data_blob_clear(&blob);
1202 r.in.buffer = &blob;
1203 r.in.offered = needed;
1205 status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
1207 torture_assert(tctx, info, "No jobs returned");
1209 for (j = 0; j < count; j++) {
1211 test_GetJob(tctx, p, handle, info[j].info1.job_id);
1212 test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1213 test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1216 } else {
1217 torture_assert_werr_ok(tctx, r.out.result, "EnumJobs failed");
1220 return true;
1223 static bool test_DoPrintTest(struct torture_context *tctx,
1224 struct dcerpc_pipe *p,
1225 struct policy_handle *handle)
1227 bool ret = true;
1228 NTSTATUS status;
1229 struct spoolss_StartDocPrinter s;
1230 struct spoolss_DocumentInfo1 info1;
1231 struct spoolss_StartPagePrinter sp;
1232 struct spoolss_WritePrinter w;
1233 struct spoolss_EndPagePrinter ep;
1234 struct spoolss_EndDocPrinter e;
1235 int i;
1236 uint32_t job_id;
1237 uint32_t num_written;
1239 torture_comment(tctx, "Testing StartDocPrinter\n");
1241 s.in.handle = handle;
1242 s.in.level = 1;
1243 s.in.info.info1 = &info1;
1244 s.out.job_id = &job_id;
1245 info1.document_name = "TorturePrintJob";
1246 info1.output_file = NULL;
1247 info1.datatype = "RAW";
1249 status = dcerpc_spoolss_StartDocPrinter(p, tctx, &s);
1250 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_StartDocPrinter failed");
1251 torture_assert_werr_ok(tctx, s.out.result, "StartDocPrinter failed");
1253 for (i=1; i < 4; i++) {
1254 torture_comment(tctx, "Testing StartPagePrinter: Page[%d]\n", i);
1256 sp.in.handle = handle;
1258 status = dcerpc_spoolss_StartPagePrinter(p, tctx, &sp);
1259 torture_assert_ntstatus_ok(tctx, status,
1260 "dcerpc_spoolss_StartPagePrinter failed");
1261 torture_assert_werr_ok(tctx, sp.out.result, "StartPagePrinter failed");
1263 torture_comment(tctx, "Testing WritePrinter: Page[%d]\n", i);
1265 w.in.handle = handle;
1266 w.in.data = data_blob_string_const(talloc_asprintf(tctx,"TortureTestPage: %d\nData\n",i));
1267 w.out.num_written = &num_written;
1269 status = dcerpc_spoolss_WritePrinter(p, tctx, &w);
1270 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_WritePrinter failed");
1271 torture_assert_werr_ok(tctx, w.out.result, "WritePrinter failed");
1273 torture_comment(tctx, "Testing EndPagePrinter: Page[%d]\n", i);
1275 ep.in.handle = handle;
1277 status = dcerpc_spoolss_EndPagePrinter(p, tctx, &ep);
1278 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndPagePrinter failed");
1279 torture_assert_werr_ok(tctx, ep.out.result, "EndPagePrinter failed");
1282 torture_comment(tctx, "Testing EndDocPrinter\n");
1284 e.in.handle = handle;
1286 status = dcerpc_spoolss_EndDocPrinter(p, tctx, &e);
1287 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed");
1288 torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed");
1290 ret &= test_AddJob(tctx, p, handle);
1291 ret &= test_EnumJobs(tctx, p, handle);
1293 ret &= test_SetJob(tctx, p, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1295 return ret;
1298 static bool test_PausePrinter(struct torture_context *tctx,
1299 struct dcerpc_pipe *p,
1300 struct policy_handle *handle)
1302 NTSTATUS status;
1303 struct spoolss_SetPrinter r;
1304 struct spoolss_SetPrinterInfoCtr info_ctr;
1305 struct spoolss_DevmodeContainer devmode_ctr;
1306 struct sec_desc_buf secdesc_ctr;
1308 info_ctr.level = 0;
1309 info_ctr.info.info0 = NULL;
1311 ZERO_STRUCT(devmode_ctr);
1312 ZERO_STRUCT(secdesc_ctr);
1314 r.in.handle = handle;
1315 r.in.info_ctr = &info_ctr;
1316 r.in.devmode_ctr = &devmode_ctr;
1317 r.in.secdesc_ctr = &secdesc_ctr;
1318 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1320 torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1322 status = dcerpc_spoolss_SetPrinter(p, tctx, &r);
1324 torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
1326 torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
1328 return true;
1331 static bool test_ResumePrinter(struct torture_context *tctx,
1332 struct dcerpc_pipe *p,
1333 struct policy_handle *handle)
1335 NTSTATUS status;
1336 struct spoolss_SetPrinter r;
1337 struct spoolss_SetPrinterInfoCtr info_ctr;
1338 struct spoolss_DevmodeContainer devmode_ctr;
1339 struct sec_desc_buf secdesc_ctr;
1341 info_ctr.level = 0;
1342 info_ctr.info.info0 = NULL;
1344 ZERO_STRUCT(devmode_ctr);
1345 ZERO_STRUCT(secdesc_ctr);
1347 r.in.handle = handle;
1348 r.in.info_ctr = &info_ctr;
1349 r.in.devmode_ctr = &devmode_ctr;
1350 r.in.secdesc_ctr = &secdesc_ctr;
1351 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1353 torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1355 status = dcerpc_spoolss_SetPrinter(p, tctx, &r);
1357 torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
1359 torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
1361 return true;
1364 static bool test_GetPrinterData(struct torture_context *tctx,
1365 struct dcerpc_pipe *p,
1366 struct policy_handle *handle,
1367 const char *value_name)
1369 NTSTATUS status;
1370 struct spoolss_GetPrinterData r;
1371 uint32_t needed;
1372 enum winreg_Type type;
1373 union spoolss_PrinterData data;
1375 r.in.handle = handle;
1376 r.in.value_name = value_name;
1377 r.in.offered = 0;
1378 r.out.needed = &needed;
1379 r.out.type = &type;
1380 r.out.data = &data;
1382 torture_comment(tctx, "Testing GetPrinterData\n");
1384 status = dcerpc_spoolss_GetPrinterData(p, tctx, &r);
1385 torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
1387 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1388 r.in.offered = needed;
1390 status = dcerpc_spoolss_GetPrinterData(p, tctx, &r);
1391 torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
1393 torture_assert_werr_ok(tctx, r.out.result, "GetPrinterData failed");
1396 return true;
1399 static bool test_GetPrinterDataEx(struct torture_context *tctx,
1400 struct dcerpc_pipe *p,
1401 struct policy_handle *handle,
1402 const char *key_name,
1403 const char *value_name)
1405 NTSTATUS status;
1406 struct spoolss_GetPrinterDataEx r;
1407 enum winreg_Type type;
1408 uint32_t needed;
1410 r.in.handle = handle;
1411 r.in.key_name = key_name;
1412 r.in.value_name = value_name;
1413 r.in.offered = 0;
1414 r.out.type = &type;
1415 r.out.needed = &needed;
1416 r.out.buffer = NULL;
1418 torture_comment(tctx, "Testing GetPrinterDataEx\n");
1420 status = dcerpc_spoolss_GetPrinterDataEx(p, tctx, &r);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1423 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1424 torture_skip(tctx, "GetPrinterDataEx not supported by server\n");
1426 torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
1429 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1430 r.in.offered = needed;
1431 r.out.buffer = talloc_array(tctx, uint8_t, needed);
1433 status = dcerpc_spoolss_GetPrinterDataEx(p, tctx, &r);
1434 torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
1436 torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDataEx failed");
1439 return true;
1442 static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pipe *p,
1443 struct policy_handle *handle)
1445 NTSTATUS status;
1446 struct spoolss_EnumPrinterData r;
1448 ZERO_STRUCT(r);
1449 r.in.handle = handle;
1450 r.in.enum_index = 0;
1452 do {
1453 uint32_t value_size = 0;
1454 uint32_t data_size = 0;
1455 enum winreg_Type type = 0;
1457 r.in.value_offered = value_size;
1458 r.out.value_needed = &value_size;
1459 r.in.data_offered = data_size;
1460 r.out.data_needed = &data_size;
1462 r.out.type = &type;
1463 r.out.data = talloc_zero_array(tctx, uint8_t, 0);
1465 torture_comment(tctx, "Testing EnumPrinterData\n");
1467 status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
1469 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
1471 r.in.value_offered = value_size;
1472 r.out.value_name = talloc_zero_array(tctx, const char, value_size);
1473 r.in.data_offered = data_size;
1474 r.out.data = talloc_zero_array(tctx, uint8_t, data_size);
1476 status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
1478 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
1480 test_GetPrinterData(tctx, p, handle, r.out.value_name);
1482 test_GetPrinterDataEx(tctx,
1483 p, handle, "PrinterDriverData",
1484 r.out.value_name);
1486 r.in.enum_index++;
1488 } while (W_ERROR_IS_OK(r.out.result));
1490 return true;
1493 static bool test_EnumPrinterDataEx(struct torture_context *tctx,
1494 struct dcerpc_pipe *p,
1495 struct policy_handle *handle)
1497 NTSTATUS status;
1498 struct spoolss_EnumPrinterDataEx r;
1499 struct spoolss_PrinterEnumValues *info;
1500 uint32_t needed;
1501 uint32_t count;
1503 r.in.handle = handle;
1504 r.in.key_name = "PrinterDriverData";
1505 r.in.offered = 0;
1506 r.out.needed = &needed;
1507 r.out.count = &count;
1508 r.out.info = &info;
1510 torture_comment(tctx, "Testing EnumPrinterDataEx\n");
1512 status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r);
1513 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed");
1515 r.in.offered = needed;
1517 status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r);
1519 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed");
1521 return true;
1525 static bool test_DeletePrinterData(struct torture_context *tctx,
1526 struct dcerpc_pipe *p,
1527 struct policy_handle *handle,
1528 const char *value_name)
1530 NTSTATUS status;
1531 struct spoolss_DeletePrinterData r;
1533 r.in.handle = handle;
1534 r.in.value_name = value_name;
1536 torture_comment(tctx, "Testing DeletePrinterData\n");
1538 status = dcerpc_spoolss_DeletePrinterData(p, tctx, &r);
1540 torture_assert_ntstatus_ok(tctx, status, "DeletePrinterData failed");
1542 return true;
1545 static bool test_SetPrinterData(struct torture_context *tctx,
1546 struct dcerpc_pipe *p,
1547 struct policy_handle *handle)
1549 NTSTATUS status;
1550 struct spoolss_SetPrinterData r;
1551 const char *value_name = "spottyfoot";
1553 r.in.handle = handle;
1554 r.in.value_name = value_name;
1555 r.in.type = REG_SZ;
1556 r.in.data.string = "dog";
1558 torture_comment(tctx, "Testing SetPrinterData\n");
1560 status = dcerpc_spoolss_SetPrinterData(p, tctx, &r);
1562 torture_assert_ntstatus_ok(tctx, status, "SetPrinterData failed");
1564 if (!test_GetPrinterData(tctx, p, handle, value_name)) {
1565 return false;
1568 if (!test_DeletePrinterData(tctx, p, handle, value_name)) {
1569 return false;
1572 return true;
1575 static bool test_SecondaryClosePrinter(struct torture_context *tctx,
1576 struct dcerpc_pipe *p,
1577 struct policy_handle *handle)
1579 NTSTATUS status;
1580 struct dcerpc_binding *b;
1581 struct dcerpc_pipe *p2;
1582 struct spoolss_ClosePrinter cp;
1584 /* only makes sense on SMB */
1585 if (p->conn->transport.transport != NCACN_NP) {
1586 return true;
1589 torture_comment(tctx, "testing close on secondary pipe\n");
1591 status = dcerpc_parse_binding(tctx, p->conn->binding_string, &b);
1592 torture_assert_ntstatus_ok(tctx, status, "Failed to parse dcerpc binding");
1594 status = dcerpc_secondary_connection(p, &p2, b);
1595 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
1597 status = dcerpc_bind_auth_none(p2, &ndr_table_spoolss);
1598 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
1600 cp.in.handle = handle;
1601 cp.out.handle = handle;
1603 status = dcerpc_spoolss_ClosePrinter(p2, tctx, &cp);
1604 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NET_WRITE_FAULT,
1605 "ERROR: Allowed close on secondary connection");
1607 torture_assert_int_equal(tctx, p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
1608 "Unexpected fault code");
1610 talloc_free(p2);
1612 return true;
1615 static bool test_OpenPrinter_badname(struct torture_context *tctx,
1616 struct dcerpc_pipe *p, const char *name)
1618 NTSTATUS status;
1619 struct spoolss_OpenPrinter op;
1620 struct spoolss_OpenPrinterEx opEx;
1621 struct policy_handle handle;
1622 bool ret = true;
1624 op.in.printername = name;
1625 op.in.datatype = NULL;
1626 op.in.devmode_ctr.devmode= NULL;
1627 op.in.access_mask = 0;
1628 op.out.handle = &handle;
1630 torture_comment(tctx, "\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1632 status = dcerpc_spoolss_OpenPrinter(p, tctx, &op);
1633 torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
1634 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1635 torture_comment(tctx, "OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1636 name, win_errstr(op.out.result));
1639 if (W_ERROR_IS_OK(op.out.result)) {
1640 ret &=test_ClosePrinter(tctx, p, &handle);
1643 opEx.in.printername = name;
1644 opEx.in.datatype = NULL;
1645 opEx.in.devmode_ctr.devmode = NULL;
1646 opEx.in.access_mask = 0;
1647 opEx.in.level = 1;
1648 opEx.in.userlevel.level1 = NULL;
1649 opEx.out.handle = &handle;
1651 torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1653 status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &opEx);
1654 torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
1655 if (!W_ERROR_EQUAL(WERR_INVALID_PARAM,opEx.out.result)) {
1656 torture_comment(tctx, "OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PARAM\n",
1657 name, win_errstr(opEx.out.result));
1660 if (W_ERROR_IS_OK(opEx.out.result)) {
1661 ret &=test_ClosePrinter(tctx, p, &handle);
1664 return ret;
1667 static bool test_OpenPrinter(struct torture_context *tctx,
1668 struct dcerpc_pipe *p,
1669 const char *name)
1671 NTSTATUS status;
1672 struct spoolss_OpenPrinter r;
1673 struct policy_handle handle;
1674 bool ret = true;
1676 r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1677 r.in.datatype = NULL;
1678 r.in.devmode_ctr.devmode= NULL;
1679 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1680 r.out.handle = &handle;
1682 torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
1684 status = dcerpc_spoolss_OpenPrinter(p, tctx, &r);
1686 torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
1688 torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
1690 if (!test_GetPrinter(tctx, p, &handle)) {
1691 ret = false;
1694 if (!torture_setting_bool(tctx, "samba3", false)) {
1695 if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
1696 ret = false;
1700 if (!test_ClosePrinter(tctx, p, &handle)) {
1701 ret = false;
1704 return ret;
1707 static bool call_OpenPrinterEx(struct torture_context *tctx,
1708 struct dcerpc_pipe *p,
1709 const char *name, struct policy_handle *handle)
1711 struct spoolss_OpenPrinterEx r;
1712 struct spoolss_UserLevel1 userlevel1;
1713 NTSTATUS status;
1715 if (name && name[0]) {
1716 r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s",
1717 dcerpc_server_name(p), name);
1718 } else {
1719 r.in.printername = talloc_asprintf(tctx, "\\\\%s",
1720 dcerpc_server_name(p));
1723 r.in.datatype = NULL;
1724 r.in.devmode_ctr.devmode= NULL;
1725 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1726 r.in.level = 1;
1727 r.in.userlevel.level1 = &userlevel1;
1728 r.out.handle = handle;
1730 userlevel1.size = 1234;
1731 userlevel1.client = "hello";
1732 userlevel1.user = "spottyfoot!";
1733 userlevel1.build = 1;
1734 userlevel1.major = 2;
1735 userlevel1.minor = 3;
1736 userlevel1.processor = 4;
1738 torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
1740 status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &r);
1742 torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
1744 torture_assert_werr_ok(tctx, r.out.result, "OpenPrinterEx failed");
1746 return true;
1749 static bool test_OpenPrinterEx(struct torture_context *tctx,
1750 struct dcerpc_pipe *p,
1751 const char *name)
1753 struct policy_handle handle;
1754 bool ret = true;
1756 if (!call_OpenPrinterEx(tctx, p, name, &handle)) {
1757 return false;
1760 if (!test_GetPrinter(tctx, p, &handle)) {
1761 ret = false;
1764 if (!test_EnumForms(tctx, p, &handle, false)) {
1765 ret = false;
1768 if (!test_AddForm(tctx, p, &handle, false)) {
1769 ret = false;
1772 if (!test_EnumPrinterData(tctx, p, &handle)) {
1773 ret = false;
1776 if (!test_EnumPrinterDataEx(tctx, p, &handle)) {
1777 ret = false;
1780 if (!test_PausePrinter(tctx, p, &handle)) {
1781 ret = false;
1784 if (!test_DoPrintTest(tctx, p, &handle)) {
1785 ret = false;
1788 if (!test_ResumePrinter(tctx, p, &handle)) {
1789 ret = false;
1792 if (!test_SetPrinterData(tctx, p, &handle)) {
1793 ret = false;
1796 if (!torture_setting_bool(tctx, "samba3", false)) {
1797 if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
1798 ret = false;
1802 if (!test_ClosePrinter(tctx, p, &handle)) {
1803 ret = false;
1806 return ret;
1809 static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pipe *p)
1811 struct spoolss_EnumPrinters r;
1812 NTSTATUS status;
1813 uint16_t levels[] = {1, 2, 4, 5};
1814 int i;
1815 bool ret = true;
1817 for (i=0;i<ARRAY_SIZE(levels);i++) {
1818 union spoolss_PrinterInfo *info;
1819 int j;
1820 uint32_t needed;
1821 uint32_t count;
1823 r.in.flags = PRINTER_ENUM_LOCAL;
1824 r.in.server = "";
1825 r.in.level = levels[i];
1826 r.in.buffer = NULL;
1827 r.in.offered = 0;
1828 r.out.needed = &needed;
1829 r.out.count = &count;
1830 r.out.info = &info;
1832 torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
1834 status = dcerpc_spoolss_EnumPrinters(p, tctx, &r);
1835 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
1837 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1838 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
1839 data_blob_clear(&blob);
1840 r.in.buffer = &blob;
1841 r.in.offered = needed;
1842 status = dcerpc_spoolss_EnumPrinters(p, tctx, &r);
1845 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
1847 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
1849 if (!info) {
1850 torture_comment(tctx, "No printers returned\n");
1851 return true;
1854 for (j=0;j<count;j++) {
1855 if (r.in.level == 1) {
1856 char *unc = talloc_strdup(tctx, info[j].info1.name);
1857 char *slash, *name;
1858 name = unc;
1859 if (unc[0] == '\\' && unc[1] == '\\') {
1860 unc +=2;
1862 slash = strchr(unc, '\\');
1863 if (slash) {
1864 slash++;
1865 name = slash;
1867 if (!test_OpenPrinter(tctx, p, name)) {
1868 ret = false;
1870 if (!test_OpenPrinterEx(tctx, p, name)) {
1871 ret = false;
1877 return ret;
1880 #if 0
1881 static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
1882 struct policy_handle *handle,
1883 const char *driver_name)
1885 NTSTATUS status;
1886 struct spoolss_GetPrinterDriver2 r;
1887 uint32_t needed;
1888 uint32_t server_major_version;
1889 uint32_t server_minor_version;
1891 r.in.handle = handle;
1892 r.in.architecture = "W32X86";
1893 r.in.level = 1;
1894 r.in.buffer = NULL;
1895 r.in.offered = 0;
1896 r.in.client_major_version = 0;
1897 r.in.client_minor_version = 0;
1898 r.out.needed = &needed;
1899 r.out.server_major_version = &server_major_version;
1900 r.out.server_minor_version = &server_minor_version;
1902 printf("Testing GetPrinterDriver2\n");
1904 status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
1905 if (!NT_STATUS_IS_OK(status)) {
1906 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1907 return false;
1910 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1911 r.in.offered = needed;
1912 status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
1915 if (!NT_STATUS_IS_OK(status)) {
1916 printf("GetPrinterDriver2 failed - %s\n",
1917 nt_errstr(status));
1918 return false;
1921 if (!W_ERROR_IS_OK(r.out.result)) {
1922 printf("GetPrinterDriver2 failed - %s\n",
1923 win_errstr(r.out.result));
1924 return false;
1927 return true;
1929 #endif
1931 static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
1932 struct dcerpc_pipe *p)
1934 struct spoolss_EnumPrinterDrivers r;
1935 NTSTATUS status;
1936 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1937 int i;
1939 for (i=0;i<ARRAY_SIZE(levels);i++) {
1941 uint32_t needed;
1942 uint32_t count;
1943 union spoolss_DriverInfo *info;
1945 r.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1946 r.in.environment = "Windows NT x86";
1947 r.in.level = levels[i];
1948 r.in.buffer = NULL;
1949 r.in.offered = 0;
1950 r.out.needed = &needed;
1951 r.out.count = &count;
1952 r.out.info = &info;
1954 torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
1956 status = dcerpc_spoolss_EnumPrinterDrivers(p, tctx, &r);
1958 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDrivers failed");
1960 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1961 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
1962 data_blob_clear(&blob);
1963 r.in.buffer = &blob;
1964 r.in.offered = needed;
1965 status = dcerpc_spoolss_EnumPrinterDrivers(p, tctx, &r);
1968 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDrivers failed");
1970 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
1972 if (!info) {
1973 torture_comment(tctx, "No printer drivers returned\n");
1974 break;
1978 return true;
1981 bool torture_rpc_spoolss(struct torture_context *torture)
1983 NTSTATUS status;
1984 struct dcerpc_pipe *p;
1985 bool ret = true;
1986 struct test_spoolss_context *ctx;
1988 status = torture_rpc_connection(torture, &p, &ndr_table_spoolss);
1989 if (!NT_STATUS_IS_OK(status)) {
1990 return false;
1993 ctx = talloc_zero(torture, struct test_spoolss_context);
1995 ret &= test_OpenPrinter_server(torture, p, ctx);
1997 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled");
1998 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled");
1999 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "EventLog");
2000 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopup");
2001 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopupToComputer");
2002 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MajorVersion");
2003 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MinorVersion");
2004 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DefaultSpoolDirectory");
2005 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "Architecture");
2006 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DsPresent");
2007 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersion");
2008 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersionEx");
2009 ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DNSMachineName");
2010 ret &= test_EnumForms(torture, p, &ctx->server_handle, true);
2011 ret &= test_AddForm(torture, p, &ctx->server_handle, true);
2012 ret &= test_EnumPorts(torture, p, ctx);
2013 ret &= test_GetPrinterDriverDirectory(torture, p, ctx);
2014 ret &= test_GetPrintProcessorDirectory(torture, p, ctx);
2015 ret &= test_EnumPrinterDrivers(torture, p, ctx);
2016 ret &= test_EnumMonitors(torture, p, ctx);
2017 ret &= test_EnumPrintProcessors(torture, p, ctx);
2018 ret &= test_EnumPrintProcDataTypes(torture, p, ctx);
2019 ret &= test_EnumPrinters(torture, p, ctx);
2020 ret &= test_OpenPrinter_badname(torture, p, "__INVALID_PRINTER__");
2021 ret &= test_OpenPrinter_badname(torture, p, "\\\\__INVALID_HOST__");
2022 ret &= test_OpenPrinter_badname(torture, p, "");
2023 ret &= test_OpenPrinter_badname(torture, p, "\\\\\\");
2024 ret &= test_OpenPrinter_badname(torture, p, "\\\\\\__INVALID_PRINTER__");
2025 ret &= test_OpenPrinter_badname(torture, p, talloc_asprintf(torture, "\\\\%s\\", dcerpc_server_name(p)));
2026 ret &= test_OpenPrinter_badname(torture, p,
2027 talloc_asprintf(torture, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p)));
2030 ret &= test_AddPort(torture, p);
2031 ret &= test_EnumPorts_old(torture, p);
2032 ret &= test_EnumPrinters_old(torture, p);
2033 ret &= test_EnumPrinterDrivers_old(torture, p);
2035 return ret;