s4-smbtorture: fix test_EnumPrinterDataEx.
[abartlet/samba.git/.git] / source4 / torture / rpc / spoolss.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for spoolss rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Stefan Metzmacher 2005
7    Copyright (C) Jelmer Vernooij 2007
8    
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.
13    
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.
18    
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/>.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "torture/rpc/rpc.h"
26 #include "librpc/gen_ndr/ndr_spoolss_c.h"
27
28 struct test_spoolss_context {
29         /* print server handle */
30         struct policy_handle server_handle;
31
32         /* for EnumPorts */
33         uint32_t port_count[3];
34         union spoolss_PortInfo *ports[3];
35
36         /* for EnumPrinterDrivers */
37         uint32_t driver_count[7];
38         union spoolss_DriverInfo *drivers[7];
39
40         /* for EnumMonitors */
41         uint32_t monitor_count[3];
42         union spoolss_MonitorInfo *monitors[3];
43
44         /* for EnumPrintProcessors */
45         uint32_t print_processor_count[2];
46         union spoolss_PrintProcessorInfo *print_processors[2];
47
48         /* for EnumPrinters */
49         uint32_t printer_count[6];
50         union spoolss_PrinterInfo *printers[6];
51 };
52
53 #define COMPARE_STRING(tctx, c,r,e) \
54         torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
55
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"); \
61         }\
62         if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
63                 torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
64         }\
65 } while(0)
66 #else
67 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
68 #endif
69
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)
74
75 #define COMPARE_STRING_ARRAY(tctx, c,r,e)
76
77 static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx)
78 {
79         NTSTATUS status;
80         struct spoolss_OpenPrinter op;
81
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;
87
88         torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
89
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"); 
93
94         return true;
95 }
96
97 static bool test_EnumPorts(struct torture_context *tctx, 
98                            struct dcerpc_pipe *p, 
99                            struct test_spoolss_context *ctx)
100 {
101         NTSTATUS status;
102         struct spoolss_EnumPorts r;
103         uint16_t levels[] = { 1, 2 };
104         int i, j;
105
106         for (i=0;i<ARRAY_SIZE(levels);i++) {
107                 int level = levels[i];
108                 DATA_BLOB blob;
109
110                 r.in.servername = "";
111                 r.in.level = level;
112                 r.in.buffer = NULL;
113                 r.in.offered = 0;
114
115                 torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
116
117                 status = dcerpc_spoolss_EnumPorts(p, ctx, &r);
118                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
119                 if (W_ERROR_IS_OK(r.out.result)) {
120                         /* TODO: do some more checks here */
121                         continue;
122                 }
123                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
124                         "EnumPorts unexpected return code");
125
126                 blob = data_blob_talloc(ctx, NULL, r.out.needed);
127                 data_blob_clear(&blob);
128                 r.in.buffer = &blob;
129                 r.in.offered = r.out.needed;
130
131                 status = dcerpc_spoolss_EnumPorts(p, ctx, &r);
132                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
133
134                 torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
135
136                 ctx->port_count[level]  = r.out.count;
137                 ctx->ports[level]       = r.out.info;
138         }
139
140         for (i=1;i<ARRAY_SIZE(levels);i++) {
141                 int level = levels[i];
142                 int old_level = levels[i-1];
143                 torture_assert_int_equal(tctx, ctx->port_count[level], ctx->port_count[old_level], 
144                         "EnumPorts invalid value");
145         }
146         /* if the array sizes are not the same we would maybe segfault in the following code */
147
148         for (i=0;i<ARRAY_SIZE(levels);i++) {
149                 int level = levels[i];
150                 for (j=0;j<ctx->port_count[level];j++) {
151                         union spoolss_PortInfo *cur = &ctx->ports[level][j];
152                         union spoolss_PortInfo *ref = &ctx->ports[2][j];
153                         switch (level) {
154                         case 1:
155                                 COMPARE_STRING(tctx, cur->info1, ref->info2, port_name);
156                                 break;
157                         case 2:
158                                 /* level 2 is our reference, and it makes no sense to compare it to itself */
159                                 break;
160                         }
161                 }
162         }
163
164         return true;
165 }
166
167 static bool test_GetPrinterDriverDirectory(struct torture_context *tctx, 
168                                            struct dcerpc_pipe *p, 
169                                            struct test_spoolss_context *ctx)
170 {
171         NTSTATUS status;
172         struct spoolss_GetPrinterDriverDirectory r;
173         struct {
174                 uint16_t level;
175                 const char *server;
176         } levels[] = {{
177                         .level  = 1,
178                         .server = NULL
179                 },{
180                         .level  = 1,
181                         .server = ""
182                 },{
183                         .level  = 78,
184                         .server = ""
185                 },{
186                         .level  = 1,
187                         .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
188                 },{
189                         .level  = 1024,
190                         .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p))
191                 }
192         };
193         int i;
194         uint32_t needed;
195
196         for (i=0;i<ARRAY_SIZE(levels);i++) {
197                 int level = levels[i].level;
198                 DATA_BLOB blob;
199
200                 r.in.server             = levels[i].server;
201                 r.in.environment        = SPOOLSS_ARCHITECTURE_NT_X86;
202                 r.in.level              = level;
203                 r.in.buffer             = NULL;
204                 r.in.offered            = 0;
205                 r.out.needed            = &needed;
206
207                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %u\n", r.in.level);
208
209                 status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r);
210                 torture_assert_ntstatus_ok(tctx, status, 
211                         "dcerpc_spoolss_GetPrinterDriverDirectory failed");
212                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
213                         "GetPrinterDriverDirectory unexpected return code");
214
215                 blob = data_blob_talloc(ctx, NULL, needed);
216                 data_blob_clear(&blob);
217                 r.in.buffer = &blob;
218                 r.in.offered = needed;
219
220                 status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r);
221                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
222
223                 torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
224         }
225
226         return true;
227 }
228
229 static bool test_EnumPrinterDrivers(struct torture_context *tctx, 
230                                     struct dcerpc_pipe *p,
231                                     struct test_spoolss_context *ctx)
232 {
233         NTSTATUS status;
234         struct spoolss_EnumPrinterDrivers r;
235         uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
236         int i, j;
237
238         for (i=0;i<ARRAY_SIZE(levels);i++) {
239                 int level = levels[i];
240                 DATA_BLOB blob;
241
242                 r.in.server             = "";
243                 r.in.environment        = SPOOLSS_ARCHITECTURE_NT_X86;
244                 r.in.level              = level;
245                 r.in.buffer             = NULL;
246                 r.in.offered            = 0;
247
248                 torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
249
250                 status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r);
251                 torture_assert_ntstatus_ok(tctx, status, 
252                                            "dcerpc_spoolss_EnumPrinterDrivers failed");
253                 if (W_ERROR_IS_OK(r.out.result)) {
254                         /* TODO: do some more checks here */
255                         continue;
256                 }
257                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
258                         "EnumPrinterDrivers failed");
259
260                 blob = data_blob_talloc(ctx, NULL, r.out.needed);
261                 data_blob_clear(&blob);
262                 r.in.buffer = &blob;
263                 r.in.offered = r.out.needed;
264
265                 status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r);
266                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinterDrivers failed");
267
268                 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
269
270                 ctx->driver_count[level]        = r.out.count;
271                 ctx->drivers[level]             = r.out.info;
272         }
273
274         for (i=1;i<ARRAY_SIZE(levels);i++) {
275                 int level = levels[i];
276                 int old_level = levels[i-1];
277                 torture_assert_int_equal(tctx, ctx->driver_count[level], ctx->driver_count[old_level],
278                         "EnumPrinterDrivers invalid value");
279         }
280
281         for (i=0;i<ARRAY_SIZE(levels);i++) {
282                 int level = levels[i];
283                 for (j=0;j<ctx->driver_count[level];j++) {
284                         union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
285                         union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
286                         switch (level) {
287                         case 1:
288                                 COMPARE_STRING(tctx, cur->info1, ref->info6, driver_name);
289                                 break;
290                         case 2:
291                                 COMPARE_UINT32(tctx, cur->info2, ref->info6, version);
292                                 COMPARE_STRING(tctx, cur->info2, ref->info6, driver_name);
293                                 COMPARE_STRING(tctx, cur->info2, ref->info6, architecture);
294                                 COMPARE_STRING(tctx, cur->info2, ref->info6, driver_path);
295                                 COMPARE_STRING(tctx, cur->info2, ref->info6, data_file);
296                                 COMPARE_STRING(tctx, cur->info2, ref->info6, config_file);
297                                 break;
298                         case 3:
299                                 COMPARE_UINT32(tctx, cur->info3, ref->info6, version);
300                                 COMPARE_STRING(tctx, cur->info3, ref->info6, driver_name);
301                                 COMPARE_STRING(tctx, cur->info3, ref->info6, architecture);
302                                 COMPARE_STRING(tctx, cur->info3, ref->info6, driver_path);
303                                 COMPARE_STRING(tctx, cur->info3, ref->info6, data_file);
304                                 COMPARE_STRING(tctx, cur->info3, ref->info6, config_file);
305                                 COMPARE_STRING(tctx, cur->info3, ref->info6, help_file);
306                                 COMPARE_STRING_ARRAY(tctx, cur->info3, ref->info6, dependent_files);
307                                 COMPARE_STRING(tctx, cur->info3, ref->info6, monitor_name);
308                                 COMPARE_STRING(tctx, cur->info3, ref->info6, default_datatype);
309                                 break;
310                         case 4:
311                                 COMPARE_UINT32(tctx, cur->info4, ref->info6, version);
312                                 COMPARE_STRING(tctx, cur->info4, ref->info6, driver_name);
313                                 COMPARE_STRING(tctx, cur->info4, ref->info6, architecture);
314                                 COMPARE_STRING(tctx, cur->info4, ref->info6, driver_path);
315                                 COMPARE_STRING(tctx, cur->info4, ref->info6, data_file);
316                                 COMPARE_STRING(tctx, cur->info4, ref->info6, config_file);
317                                 COMPARE_STRING(tctx, cur->info4, ref->info6, help_file);
318                                 COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, dependent_files);
319                                 COMPARE_STRING(tctx, cur->info4, ref->info6, monitor_name);
320                                 COMPARE_STRING(tctx, cur->info4, ref->info6, default_datatype);
321                                 COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, previous_names);
322                                 break;
323                         case 5:
324                                 COMPARE_UINT32(tctx, cur->info5, ref->info6, version);
325                                 COMPARE_STRING(tctx, cur->info5, ref->info6, driver_name);
326                                 COMPARE_STRING(tctx, cur->info5, ref->info6, architecture);
327                                 COMPARE_STRING(tctx, cur->info5, ref->info6, driver_path);
328                                 COMPARE_STRING(tctx, cur->info5, ref->info6, data_file);
329                                 COMPARE_STRING(tctx, cur->info5, ref->info6, config_file);
330                                 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/
331                                 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/
332                                 /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_version); */
333                                 break;
334                         case 6:
335                                 /* level 6 is our reference, and it makes no sense to compare it to itself */
336                                 break;
337                         }
338                 }
339         }
340
341         return true;
342 }
343
344 static bool test_EnumMonitors(struct torture_context *tctx, 
345                               struct dcerpc_pipe *p, 
346                               struct test_spoolss_context *ctx)
347 {
348         NTSTATUS status;
349         struct spoolss_EnumMonitors r;
350         uint16_t levels[] = { 1, 2 };
351         int i, j;
352
353         for (i=0;i<ARRAY_SIZE(levels);i++) {
354                 int level = levels[i];
355                 DATA_BLOB blob;
356
357                 r.in.servername = "";
358                 r.in.level = level;
359                 r.in.buffer = NULL;
360                 r.in.offered = 0;
361
362                 torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
363
364                 status = dcerpc_spoolss_EnumMonitors(p, ctx, &r);
365                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
366                 if (W_ERROR_IS_OK(r.out.result)) {
367                         /* TODO: do some more checks here */
368                         continue;
369                 }
370                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
371                         "EnumMonitors failed");
372
373                 blob = data_blob_talloc(ctx, NULL, r.out.needed);
374                 data_blob_clear(&blob);
375                 r.in.buffer = &blob;
376                 r.in.offered = r.out.needed;
377
378                 status = dcerpc_spoolss_EnumMonitors(p, ctx, &r);
379                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
380
381                 torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
382
383                 ctx->monitor_count[level]       = r.out.count;
384                 ctx->monitors[level]            = r.out.info;
385         }
386
387         for (i=1;i<ARRAY_SIZE(levels);i++) {
388                 int level = levels[i];
389                 int old_level = levels[i-1];
390                 torture_assert_int_equal(tctx, ctx->monitor_count[level], ctx->monitor_count[old_level], 
391                                          "EnumMonitors invalid value");
392         }
393
394         for (i=0;i<ARRAY_SIZE(levels);i++) {
395                 int level = levels[i];
396                 for (j=0;j<ctx->monitor_count[level];j++) {
397                         union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
398                         union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
399                         switch (level) {
400                         case 1:
401                                 COMPARE_STRING(tctx, cur->info1, ref->info2, monitor_name);
402                                 break;
403                         case 2:
404                                 /* level 2 is our reference, and it makes no sense to compare it to itself */
405                                 break;
406                         }
407                 }
408         }
409
410         return true;
411 }
412
413 static bool test_EnumPrintProcessors(struct torture_context *tctx, 
414                                      struct dcerpc_pipe *p,
415                                      struct test_spoolss_context *ctx)
416 {
417         NTSTATUS status;
418         struct spoolss_EnumPrintProcessors r;
419         uint16_t levels[] = { 1 };
420         int i, j;
421
422         for (i=0;i<ARRAY_SIZE(levels);i++) {
423                 int level = levels[i];
424                 DATA_BLOB blob;
425
426                 r.in.servername = "";
427                 r.in.environment = "Windows NT x86";
428                 r.in.level = level;
429                 r.in.buffer = NULL;
430                 r.in.offered = 0;
431
432                 torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level);
433
434                 status = dcerpc_spoolss_EnumPrintProcessors(p, ctx, &r);
435                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
436                 if (W_ERROR_IS_OK(r.out.result)) {
437                         /* TODO: do some more checks here */
438                         continue;
439                 }
440                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
441                         "EnumPrintProcessors unexpected return code");
442
443                 blob = data_blob_talloc(ctx, NULL, r.out.needed);
444                 data_blob_clear(&blob);
445                 r.in.buffer = &blob;
446                 r.in.offered = r.out.needed;
447
448                 status = dcerpc_spoolss_EnumPrintProcessors(p, ctx, &r);
449                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
450
451                 torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
452
453                 ctx->print_processor_count[level]       = r.out.count;
454                 ctx->print_processors[level]            = r.out.info;
455         }
456
457         for (i=1;i<ARRAY_SIZE(levels);i++) {
458                 int level = levels[i];
459                 int old_level = levels[i-1];
460                 torture_assert_int_equal(tctx, ctx->print_processor_count[level], ctx->print_processor_count[old_level],
461                         "EnumPrintProcessors failed");
462         }
463
464         for (i=0;i<ARRAY_SIZE(levels);i++) {
465                 int level = levels[i];
466                 for (j=0;j<ctx->print_processor_count[level];j++) {
467 #if 0
468                         union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
469                         union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
470 #endif
471                         switch (level) {
472                         case 1:
473                                 /* level 1 is our reference, and it makes no sense to compare it to itself */
474                                 break;
475                         }
476                 }
477         }
478
479         return true;
480 }
481
482 static bool test_EnumPrinters(struct torture_context *tctx, 
483                               struct dcerpc_pipe *p,
484                               struct test_spoolss_context *ctx)
485 {
486         struct spoolss_EnumPrinters r;
487         NTSTATUS status;
488         uint16_t levels[] = { 0, 1, 2, 4, 5 };
489         int i, j;
490
491         for (i=0;i<ARRAY_SIZE(levels);i++) {
492                 int level = levels[i];
493                 DATA_BLOB blob;
494
495                 r.in.flags      = PRINTER_ENUM_LOCAL;
496                 r.in.server     = "";
497                 r.in.level      = level;
498                 r.in.buffer     = NULL;
499                 r.in.offered    = 0;
500
501                 torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
502
503                 status = dcerpc_spoolss_EnumPrinters(p, ctx, &r);
504                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
505                 if (W_ERROR_IS_OK(r.out.result)) {
506                         /* TODO: do some more checks here */
507                         continue;
508                 }
509                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, 
510                         "EnumPrinters unexpected return code");
511
512                 blob = data_blob_talloc(ctx, NULL, r.out.needed);
513                 data_blob_clear(&blob);
514                 r.in.buffer = &blob;
515                 r.in.offered = r.out.needed;
516
517                 status = dcerpc_spoolss_EnumPrinters(p, ctx, &r);
518                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
519
520                 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
521
522                 ctx->printer_count[level]       = r.out.count;
523                 ctx->printers[level]            = r.out.info;
524         }
525
526         for (i=1;i<ARRAY_SIZE(levels);i++) {
527                 int level = levels[i];
528                 int old_level = levels[i-1];
529                 torture_assert_int_equal(tctx, ctx->printer_count[level], ctx->printer_count[old_level],
530                                          "EnumPrinters invalid value");
531         }
532
533         for (i=0;i<ARRAY_SIZE(levels);i++) {
534                 int level = levels[i];
535                 for (j=0;j<ctx->printer_count[level];j++) {
536                         union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
537                         union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
538                         switch (level) {
539                         case 0:
540                                 COMPARE_STRING(tctx, cur->info0, ref->info2, printername);
541                                 COMPARE_STRING(tctx, cur->info0, ref->info2, servername);
542                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, cjobs);
543                                 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
544                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
545                                 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);                
546                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
547                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
548                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
549                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
550                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
551                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
552                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
553                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
554                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
555                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
556                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
557                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
558                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
559                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
560                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
561                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, status);
562                                 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
563                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
564                                 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
565                                 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
566                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
567                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
568                                 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
569                                 break;
570                         case 1:
571                                 /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
572                                 /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
573                                 /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
574                                 COMPARE_STRING(tctx, cur->info1, ref->info2, comment);
575                                 break;
576                         case 2:
577                                 /* level 2 is our reference, and it makes no sense to compare it to itself */
578                                 break;
579                         case 4:
580                                 COMPARE_STRING(tctx, cur->info4, ref->info2, printername);
581                                 COMPARE_STRING(tctx, cur->info4, ref->info2, servername);
582                                 COMPARE_UINT32(tctx, cur->info4, ref->info2, attributes);
583                                 break;
584                         case 5:
585                                 COMPARE_STRING(tctx, cur->info5, ref->info2, printername);
586                                 COMPARE_STRING(tctx, cur->info5, ref->info2, portname);
587                                 COMPARE_UINT32(tctx, cur->info5, ref->info2, attributes);
588                                 /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
589                                 COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
590                                 break;
591                         }
592                 }
593         }
594
595         /* TODO:
596          *      - verify that the port of a printer was in the list returned by EnumPorts
597          */
598
599         return true;
600 }
601
602 static bool test_GetPrinter(struct torture_context *tctx, 
603                             struct dcerpc_pipe *p, 
604                      struct policy_handle *handle)
605 {
606         NTSTATUS status;
607         struct spoolss_GetPrinter r;
608         uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
609         int i;
610         uint32_t needed;
611         
612         for (i=0;i<ARRAY_SIZE(levels);i++) {
613                 r.in.handle = handle;
614                 r.in.level = levels[i];
615                 r.in.buffer = NULL;
616                 r.in.offered = 0;
617                 r.out.needed = &needed;
618
619                 torture_comment(tctx, "Testing GetPrinter level %u\n", r.in.level);
620
621                 status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
622                 torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
623                 
624                 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
625                         DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
626                         data_blob_clear(&blob);
627                         r.in.buffer = &blob;
628                         r.in.offered = needed;
629                         status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
630                 }
631                 
632                 torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
633
634                 torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
635         }
636
637         return true;
638 }
639
640
641 static bool test_ClosePrinter(struct torture_context *tctx, 
642                               struct dcerpc_pipe *p, 
643                               struct policy_handle *handle)
644 {
645         NTSTATUS status;
646         struct spoolss_ClosePrinter r;
647
648         r.in.handle = handle;
649         r.out.handle = handle;
650
651         torture_comment(tctx, "Testing ClosePrinter\n");
652
653         status = dcerpc_spoolss_ClosePrinter(p, tctx, &r);
654         torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
655
656         return true;
657 }
658
659 static bool test_GetForm(struct torture_context *tctx, 
660                          struct dcerpc_pipe *p, 
661                          struct policy_handle *handle, 
662                          const char *form_name)
663 {
664         NTSTATUS status;
665         struct spoolss_GetForm r;
666         uint32_t needed;
667
668         r.in.handle = handle;
669         r.in.form_name = form_name;
670         r.in.level = 1;
671         r.in.buffer = NULL;
672         r.in.offered = 0;
673         r.out.needed = &needed;
674
675         torture_comment(tctx, "Testing GetForm\n");
676
677         status = dcerpc_spoolss_GetForm(p, tctx, &r);
678         torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
679
680         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
681                 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
682                 data_blob_clear(&blob);
683                 r.in.buffer = &blob;
684                 r.in.offered = needed;
685                 status = dcerpc_spoolss_GetForm(p, tctx, &r);
686                 torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
687
688                 torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
689
690                 torture_assert(tctx, r.out.info, "No form info returned");
691         }
692
693         torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
694
695         return true;
696 }
697
698 static bool test_EnumForms(struct torture_context *tctx, 
699                            struct dcerpc_pipe *p, 
700                            struct policy_handle *handle, bool print_server)
701 {
702         NTSTATUS status;
703         struct spoolss_EnumForms r;
704         bool ret = true;
705
706         r.in.handle = handle;
707         r.in.level = 1;
708         r.in.buffer = NULL;
709         r.in.offered = 0;
710
711         torture_comment(tctx, "Testing EnumForms\n");
712
713         status = dcerpc_spoolss_EnumForms(p, tctx, &r);
714         torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
715
716         if (print_server && W_ERROR_EQUAL(r.out.result, WERR_BADFID))
717                 torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
718
719         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
720                 union spoolss_FormInfo *info;
721                 int j;
722                 DATA_BLOB blob = data_blob_talloc(tctx, NULL, r.out.needed);
723                 data_blob_clear(&blob);
724                 r.in.buffer = &blob;
725                 r.in.offered = r.out.needed;
726
727                 status = dcerpc_spoolss_EnumForms(p, tctx, &r);
728
729                 torture_assert(tctx, r.out.info, "No forms returned");
730
731                 info = r.out.info;
732
733                 for (j = 0; j < r.out.count; j++) {
734                         if (!print_server) 
735                                 ret &= test_GetForm(tctx, p, handle, info[j].info1.form_name);
736                 }
737         }
738
739         torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
740
741         torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
742
743         return true;
744 }
745
746 static bool test_DeleteForm(struct torture_context *tctx, 
747                             struct dcerpc_pipe *p, 
748                             struct policy_handle *handle, 
749                             const char *form_name)
750 {
751         NTSTATUS status;
752         struct spoolss_DeleteForm r;
753
754         r.in.handle = handle;
755         r.in.form_name = form_name;
756
757         status = dcerpc_spoolss_DeleteForm(p, tctx, &r);
758
759         torture_assert_ntstatus_ok(tctx, status, "DeleteForm failed");
760
761         torture_assert_werr_ok(tctx, r.out.result, "DeleteForm failed");
762
763         return true;
764 }
765
766 static bool test_AddForm(struct torture_context *tctx, 
767                          struct dcerpc_pipe *p, 
768                          struct policy_handle *handle, bool print_server)
769 {
770         struct spoolss_AddForm r;
771         struct spoolss_AddFormInfo1 addform;
772         const char *form_name = "testform3";
773         NTSTATUS status;
774         bool ret = true;
775
776         r.in.handle     = handle;
777         r.in.level      = 1;
778         r.in.info.info1 = &addform;
779         addform.flags           = SPOOLSS_FORM_USER;
780         addform.form_name       = form_name;
781         addform.size.width      = 50;
782         addform.size.height     = 25;
783         addform.area.left       = 5;
784         addform.area.top        = 10;
785         addform.area.right      = 45;
786         addform.area.bottom     = 15;
787
788         status = dcerpc_spoolss_AddForm(p, tctx, &r);
789
790         torture_assert_ntstatus_ok(tctx, status, "AddForm failed");
791
792         torture_assert_werr_ok(tctx, r.out.result, "AddForm failed");
793
794         if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name);
795
796         {
797                 struct spoolss_SetForm sf;
798                 struct spoolss_AddFormInfo1 setform;
799
800                 sf.in.handle    = handle;
801                 sf.in.form_name = form_name;
802                 sf.in.level     = 1;
803                 sf.in.info.info1= &setform;
804                 setform.flags           = addform.flags;
805                 setform.form_name       = addform.form_name;
806                 setform.size            = addform.size;
807                 setform.area            = addform.area;
808
809                 setform.size.width      = 1234;
810
811                 status = dcerpc_spoolss_SetForm(p, tctx, &sf);
812
813                 torture_assert_ntstatus_ok(tctx, status, "SetForm failed");
814
815                 torture_assert_werr_ok(tctx, r.out.result, "SetForm failed");
816         }
817
818         if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name);
819
820         if (!test_DeleteForm(tctx, p, handle, form_name)) {
821                 ret = false;
822         }
823
824         return ret;
825 }
826
827 static bool test_EnumPorts_old(struct torture_context *tctx, 
828                                struct dcerpc_pipe *p)
829 {
830         NTSTATUS status;
831         struct spoolss_EnumPorts r;
832
833         r.in.servername = talloc_asprintf(tctx, "\\\\%s", 
834                                           dcerpc_server_name(p));
835         r.in.level = 2;
836         r.in.buffer = NULL;
837         r.in.offered = 0;
838
839         torture_comment(tctx, "Testing EnumPorts\n");
840
841         status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
842
843         torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
844
845         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
846                 DATA_BLOB blob = data_blob_talloc(tctx, NULL, r.out.needed);
847                 data_blob_clear(&blob);
848                 r.in.buffer = &blob;
849                 r.in.offered = r.out.needed;
850
851                 status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
852                 torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
853
854                 torture_assert(tctx, r.out.info, "No ports returned");
855         }
856
857         return true;
858 }
859
860 static bool test_AddPort(struct torture_context *tctx, 
861                          struct dcerpc_pipe *p)
862 {
863         NTSTATUS status;
864         struct spoolss_AddPort r;
865
866         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", 
867                                            dcerpc_server_name(p));
868         r.in.unknown = 0;
869         r.in.monitor_name = "foo";
870
871         torture_comment(tctx, "Testing AddPort\n");
872
873         status = dcerpc_spoolss_AddPort(p, tctx, &r);
874
875         torture_assert_ntstatus_ok(tctx, status, "AddPort failed");
876
877         /* win2k3 returns WERR_NOT_SUPPORTED */
878
879 #if 0
880
881         if (!W_ERROR_IS_OK(r.out.result)) {
882                 printf("AddPort failed - %s\n", win_errstr(r.out.result));
883                 return false;
884         }
885
886 #endif
887
888         return true;
889 }
890
891 static bool test_GetJob(struct torture_context *tctx, 
892                         struct dcerpc_pipe *p, 
893                         struct policy_handle *handle, uint32_t job_id)
894 {
895         NTSTATUS status;
896         struct spoolss_GetJob r;
897         uint32_t needed;
898
899         r.in.handle = handle;
900         r.in.job_id = job_id;
901         r.in.level = 1;
902         r.in.buffer = NULL;
903         r.in.offered = 0;
904         r.out.needed = &needed;
905
906         torture_comment(tctx, "Testing GetJob\n");
907
908         status = dcerpc_spoolss_GetJob(p, tctx, &r);
909         torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
910
911         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
912                 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
913                 data_blob_clear(&blob);
914                 r.in.buffer = &blob;
915                 r.in.offered = needed;
916
917                 status = dcerpc_spoolss_GetJob(p, tctx, &r);
918
919                 torture_assert(tctx, r.out.info, "No job info returned");
920         }
921
922         return true;
923 }
924
925 static bool test_SetJob(struct torture_context *tctx, 
926                         struct dcerpc_pipe *p, 
927                         struct policy_handle *handle, uint32_t job_id, 
928                         enum spoolss_JobControl command)
929 {
930         NTSTATUS status;
931         struct spoolss_SetJob r;
932
933         r.in.handle     = handle;
934         r.in.job_id     = job_id;
935         r.in.ctr        = NULL;
936         r.in.command    = command;
937
938         torture_comment(tctx, "Testing SetJob\n");
939
940         status = dcerpc_spoolss_SetJob(p, tctx, &r);
941         torture_assert_ntstatus_ok(tctx, status, "SetJob failed");
942         torture_assert_werr_ok(tctx, r.out.result, "SetJob failed");
943
944         return true;
945 }
946
947 static bool test_EnumJobs(struct torture_context *tctx, 
948                           struct dcerpc_pipe *p, 
949                           struct policy_handle *handle)
950 {
951         NTSTATUS status;
952         struct spoolss_EnumJobs r;
953
954         r.in.handle = handle;
955         r.in.firstjob = 0;
956         r.in.numjobs = 0xffffffff;
957         r.in.level = 1;
958         r.in.buffer = NULL;
959         r.in.offered = 0;
960
961         torture_comment(tctx, "Testing EnumJobs\n");
962
963         status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
964
965         torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
966
967         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
968                 union spoolss_JobInfo *info;
969                 int j;
970                 DATA_BLOB blob = data_blob_talloc(tctx, NULL, r.out.needed);
971                 data_blob_clear(&blob);
972                 r.in.buffer = &blob;
973                 r.in.offered = r.out.needed;
974
975                 status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
976
977                 torture_assert(tctx, r.out.info, "No jobs returned");
978
979                 info = r.out.info;
980
981                 for (j = 0; j < r.out.count; j++) {
982                         test_GetJob(tctx, p, handle, info[j].info1.job_id);
983                         test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
984                         test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
985                 }
986
987         } else {
988                 torture_assert_werr_ok(tctx, r.out.result, "EnumJobs failed");
989         }
990
991         return true;
992 }
993
994 static bool test_DoPrintTest(struct torture_context *tctx, 
995                              struct dcerpc_pipe *p, 
996                              struct policy_handle *handle)
997 {
998         bool ret = true;
999         NTSTATUS status;
1000         struct spoolss_StartDocPrinter s;
1001         struct spoolss_DocumentInfo1 info1;
1002         struct spoolss_StartPagePrinter sp;
1003         struct spoolss_WritePrinter w;
1004         struct spoolss_EndPagePrinter ep;
1005         struct spoolss_EndDocPrinter e;
1006         int i;
1007         uint32_t job_id;
1008         uint32_t num_written;
1009
1010         torture_comment(tctx, "Testing StartDocPrinter\n");
1011
1012         s.in.handle             = handle;
1013         s.in.level              = 1;
1014         s.in.info.info1         = &info1;
1015         s.out.job_id            = &job_id;
1016         info1.document_name     = "TorturePrintJob";
1017         info1.output_file       = NULL;
1018         info1.datatype          = "RAW";
1019
1020         status = dcerpc_spoolss_StartDocPrinter(p, tctx, &s);
1021         torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_StartDocPrinter failed");
1022         torture_assert_werr_ok(tctx, s.out.result, "StartDocPrinter failed");
1023
1024         for (i=1; i < 4; i++) {
1025                 torture_comment(tctx, "Testing StartPagePrinter: Page[%d]\n", i);
1026
1027                 sp.in.handle            = handle;
1028
1029                 status = dcerpc_spoolss_StartPagePrinter(p, tctx, &sp);
1030                 torture_assert_ntstatus_ok(tctx, status, 
1031                                            "dcerpc_spoolss_StartPagePrinter failed");
1032                 torture_assert_werr_ok(tctx, sp.out.result, "StartPagePrinter failed");
1033
1034                 torture_comment(tctx, "Testing WritePrinter: Page[%d]\n", i);
1035
1036                 w.in.handle             = handle;
1037                 w.in.data               = data_blob_string_const(talloc_asprintf(tctx,"TortureTestPage: %d\nData\n",i));
1038                 w.out.num_written       = &num_written;
1039
1040                 status = dcerpc_spoolss_WritePrinter(p, tctx, &w);
1041                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_WritePrinter failed");
1042                 torture_assert_werr_ok(tctx, w.out.result, "WritePrinter failed");
1043
1044                 torture_comment(tctx, "Testing EndPagePrinter: Page[%d]\n", i);
1045
1046                 ep.in.handle            = handle;
1047
1048                 status = dcerpc_spoolss_EndPagePrinter(p, tctx, &ep);
1049                 torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndPagePrinter failed");
1050                 torture_assert_werr_ok(tctx, ep.out.result, "EndPagePrinter failed");
1051         }
1052
1053         torture_comment(tctx, "Testing EndDocPrinter\n");
1054
1055         e.in.handle = handle;
1056
1057         status = dcerpc_spoolss_EndDocPrinter(p, tctx, &e);
1058         torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed");
1059         torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed");
1060
1061         ret &= test_EnumJobs(tctx, p, handle);
1062
1063         ret &= test_SetJob(tctx, p, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1064
1065         return ret;
1066 }
1067
1068 static bool test_PausePrinter(struct torture_context *tctx, 
1069                               struct dcerpc_pipe *p, 
1070                               struct policy_handle *handle)
1071 {
1072         NTSTATUS status;
1073         struct spoolss_SetPrinter r;
1074
1075         r.in.handle             = handle;
1076         r.in.level              = 0;
1077         r.in.info.info1         = NULL;
1078         r.in.devmode_ctr.devmode= NULL;
1079         r.in.secdesc_ctr.sd     = NULL;
1080         r.in.command            = SPOOLSS_PRINTER_CONTROL_PAUSE;
1081
1082         torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1083
1084         status = dcerpc_spoolss_SetPrinter(p, tctx, &r);
1085
1086         torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
1087
1088         torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
1089
1090         return true;
1091 }
1092
1093 static bool test_ResumePrinter(struct torture_context *tctx, 
1094                                struct dcerpc_pipe *p, 
1095                                struct policy_handle *handle)
1096 {
1097         NTSTATUS status;
1098         struct spoolss_SetPrinter r;
1099
1100         r.in.handle             = handle;
1101         r.in.level              = 0;
1102         r.in.info.info1         = NULL;
1103         r.in.devmode_ctr.devmode= NULL;
1104         r.in.secdesc_ctr.sd     = NULL;
1105         r.in.command            = SPOOLSS_PRINTER_CONTROL_RESUME;
1106
1107         torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1108
1109         status = dcerpc_spoolss_SetPrinter(p, tctx, &r);
1110
1111         torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
1112
1113         torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
1114
1115         return true;
1116 }
1117
1118 static bool test_GetPrinterData(struct torture_context *tctx, 
1119                                 struct dcerpc_pipe *p, 
1120                                 struct policy_handle *handle, 
1121                                 const char *value_name)
1122 {
1123         NTSTATUS status;
1124         struct spoolss_GetPrinterData r;
1125
1126         r.in.handle = handle;
1127         r.in.value_name = value_name;
1128         r.in.offered = 0;
1129
1130         torture_comment(tctx, "Testing GetPrinterData\n");
1131
1132         status = dcerpc_spoolss_GetPrinterData(p, tctx, &r);
1133         torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
1134
1135         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1136                 r.in.offered = r.out.needed;
1137
1138                 status = dcerpc_spoolss_GetPrinterData(p, tctx, &r);
1139                 torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
1140
1141                 torture_assert_werr_ok(tctx, r.out.result, "GetPrinterData failed");
1142         }
1143
1144         return true;
1145 }
1146
1147 static bool test_GetPrinterDataEx(struct torture_context *tctx, 
1148                                   struct dcerpc_pipe *p, 
1149                                   struct policy_handle *handle, 
1150                                   const char *key_name,
1151                                   const char *value_name)
1152 {
1153         NTSTATUS status;
1154         struct spoolss_GetPrinterDataEx r;
1155         uint32_t type;
1156         uint32_t needed;
1157
1158         r.in.handle = handle;
1159         r.in.key_name = key_name;
1160         r.in.value_name = value_name;
1161         r.in.offered = 0;
1162         r.out.type = &type;
1163         r.out.needed = &needed;
1164
1165         torture_comment(tctx, "Testing GetPrinterDataEx\n");
1166
1167         status = dcerpc_spoolss_GetPrinterDataEx(p, tctx, &r);
1168         if (!NT_STATUS_IS_OK(status)) {
1169                 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1170                     p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1171                         torture_skip(tctx, "GetPrinterDataEx not supported by server\n");
1172                 }
1173                 torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
1174         }
1175
1176         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1177                 r.in.offered = needed;
1178                 r.out.buffer = talloc_array(tctx, uint8_t, needed);
1179
1180                 status = dcerpc_spoolss_GetPrinterDataEx(p, tctx, &r);
1181                 torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
1182
1183                 torture_assert_werr_ok(tctx, r.out.result,  "GetPrinterDataEx failed");
1184         }
1185
1186         return true;
1187 }
1188
1189 static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pipe *p, 
1190                                  struct policy_handle *handle)
1191 {
1192         NTSTATUS status;
1193         struct spoolss_EnumPrinterData r;
1194
1195         ZERO_STRUCT(r);
1196         r.in.handle = handle;
1197         r.in.enum_index = 0;
1198
1199         do {
1200                 uint32_t value_size = 0;
1201                 uint32_t data_size = 0;
1202                 uint32_t printerdata_type = 0;
1203                 DATA_BLOB data = data_blob(NULL,0);
1204
1205                 r.in.value_offered = value_size;
1206                 r.out.value_needed = &value_size;
1207                 r.in.data_offered = data_size;
1208                 r.out.data_needed = &data_size;
1209
1210                 r.out.printerdata_type = &printerdata_type;
1211                 r.out.buffer = &data;
1212
1213                 torture_comment(tctx, "Testing EnumPrinterData\n");
1214
1215                 status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
1216
1217                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
1218
1219                 r.in.value_offered = value_size;
1220                 r.in.data_offered = data_size;
1221
1222                 status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
1223
1224                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
1225                 
1226                 test_GetPrinterData(tctx, p, handle, r.out.value_name);
1227
1228                 test_GetPrinterDataEx(tctx, 
1229                         p, handle, "PrinterDriverData", 
1230                         r.out.value_name);
1231
1232                 r.in.enum_index++;
1233
1234         } while (W_ERROR_IS_OK(r.out.result));
1235
1236         return true;
1237 }
1238
1239 static bool test_EnumPrinterDataEx(struct torture_context *tctx, 
1240                                    struct dcerpc_pipe *p, 
1241                                    struct policy_handle *handle)
1242 {
1243         NTSTATUS status;
1244         struct spoolss_EnumPrinterDataEx r;
1245         uint32_t needed;
1246         uint32_t count;
1247
1248         r.in.handle = handle;
1249         r.in.key_name = "PrinterDriverData";
1250         r.in.offered = 0;
1251         r.out.needed = &needed;
1252         r.out.count = &count;
1253
1254         torture_comment(tctx, "Testing EnumPrinterDataEx\n");
1255
1256         status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r);
1257         torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed");
1258
1259         r.in.offered = needed;
1260         r.out.buffer = talloc_array(tctx, uint8_t, needed);
1261
1262         status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r);
1263
1264         torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed");
1265
1266         return true;
1267 }
1268
1269
1270 static bool test_DeletePrinterData(struct torture_context *tctx, 
1271                                    struct dcerpc_pipe *p, 
1272                                    struct policy_handle *handle, 
1273                                    const char *value_name)
1274 {
1275         NTSTATUS status;
1276         struct spoolss_DeletePrinterData r;
1277
1278         r.in.handle = handle;
1279         r.in.value_name = value_name;
1280
1281         torture_comment(tctx, "Testing DeletePrinterData\n");
1282
1283         status = dcerpc_spoolss_DeletePrinterData(p, tctx, &r);
1284
1285         torture_assert_ntstatus_ok(tctx, status, "DeletePrinterData failed");
1286
1287         return true;
1288 }
1289
1290 static bool test_SetPrinterData(struct torture_context *tctx, 
1291                                 struct dcerpc_pipe *p, 
1292                                 struct policy_handle *handle)
1293 {
1294         NTSTATUS status;
1295         struct spoolss_SetPrinterData r;
1296         const char *value_name = "spottyfoot";
1297         
1298         r.in.handle = handle;
1299         r.in.value_name = value_name;
1300         r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1301         r.in.data.string = "dog";
1302
1303         torture_comment(tctx, "Testing SetPrinterData\n");
1304
1305         status = dcerpc_spoolss_SetPrinterData(p, tctx, &r);
1306
1307         torture_assert_ntstatus_ok(tctx, status, "SetPrinterData failed");
1308
1309         if (!test_GetPrinterData(tctx, p, handle, value_name)) {
1310                 return false;
1311         }
1312
1313         if (!test_DeletePrinterData(tctx, p, handle, value_name)) {
1314                 return false;
1315         }
1316
1317         return true;
1318 }
1319
1320 static bool test_SecondaryClosePrinter(struct torture_context *tctx, 
1321                                        struct dcerpc_pipe *p, 
1322                                        struct policy_handle *handle)
1323 {
1324         NTSTATUS status;
1325         struct dcerpc_binding *b;
1326         struct dcerpc_pipe *p2;
1327         struct spoolss_ClosePrinter cp;
1328
1329         /* only makes sense on SMB */
1330         if (p->conn->transport.transport != NCACN_NP) {
1331                 return true;
1332         }
1333
1334         torture_comment(tctx, "testing close on secondary pipe\n");
1335
1336         status = dcerpc_parse_binding(tctx, p->conn->binding_string, &b);
1337         torture_assert_ntstatus_ok(tctx, status, "Failed to parse dcerpc binding");
1338
1339         status = dcerpc_secondary_connection(p, &p2, b);
1340         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
1341
1342         status = dcerpc_bind_auth_none(p2, &ndr_table_spoolss);
1343         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
1344
1345         cp.in.handle = handle;
1346         cp.out.handle = handle;
1347
1348         status = dcerpc_spoolss_ClosePrinter(p2, tctx, &cp);
1349         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NET_WRITE_FAULT,
1350                         "ERROR: Allowed close on secondary connection");
1351
1352         torture_assert_int_equal(tctx, p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, 
1353                                  "Unexpected fault code");
1354
1355         talloc_free(p2);
1356
1357         return true;
1358 }
1359
1360 static bool test_OpenPrinter_badname(struct torture_context *tctx, 
1361                                      struct dcerpc_pipe *p, const char *name)
1362 {
1363         NTSTATUS status;
1364         struct spoolss_OpenPrinter op;
1365         struct spoolss_OpenPrinterEx opEx;
1366         struct policy_handle handle;
1367         bool ret = true;
1368
1369         op.in.printername       = name;
1370         op.in.datatype          = NULL;
1371         op.in.devmode_ctr.devmode= NULL;
1372         op.in.access_mask       = 0;
1373         op.out.handle           = &handle;
1374
1375         torture_comment(tctx, "\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1376
1377         status = dcerpc_spoolss_OpenPrinter(p, tctx, &op);
1378         torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
1379         if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1380                 torture_comment(tctx, "OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1381                         name, win_errstr(op.out.result));
1382         }
1383
1384         if (W_ERROR_IS_OK(op.out.result)) {
1385                 ret &=test_ClosePrinter(tctx, p, &handle);
1386         }
1387
1388         opEx.in.printername             = name;
1389         opEx.in.datatype                = NULL;
1390         opEx.in.devmode_ctr.devmode     = NULL;
1391         opEx.in.access_mask             = 0;
1392         opEx.in.level                   = 1;
1393         opEx.in.userlevel.level1        = NULL;
1394         opEx.out.handle                 = &handle;
1395
1396         torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1397
1398         status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &opEx);
1399         torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
1400         if (!W_ERROR_EQUAL(WERR_INVALID_PARAM,opEx.out.result)) {
1401                 torture_comment(tctx, "OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PARAM\n",
1402                         name, win_errstr(opEx.out.result));
1403         }
1404
1405         if (W_ERROR_IS_OK(opEx.out.result)) {
1406                 ret &=test_ClosePrinter(tctx, p, &handle);
1407         }
1408
1409         return ret;
1410 }
1411
1412 static bool test_OpenPrinter(struct torture_context *tctx, 
1413                              struct dcerpc_pipe *p, 
1414                              const char *name)
1415 {
1416         NTSTATUS status;
1417         struct spoolss_OpenPrinter r;
1418         struct policy_handle handle;
1419         bool ret = true;
1420
1421         r.in.printername        = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1422         r.in.datatype           = NULL;
1423         r.in.devmode_ctr.devmode= NULL;
1424         r.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
1425         r.out.handle            = &handle;
1426
1427         torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
1428
1429         status = dcerpc_spoolss_OpenPrinter(p, tctx, &r);
1430
1431         torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
1432
1433         torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
1434
1435         if (!test_GetPrinter(tctx, p, &handle)) {
1436                 ret = false;
1437         }
1438
1439         if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
1440                 ret = false;
1441         }
1442
1443         if (!test_ClosePrinter(tctx, p, &handle)) {
1444                 ret = false;
1445         }
1446
1447         return ret;
1448 }
1449
1450 static bool call_OpenPrinterEx(struct torture_context *tctx, 
1451                                struct dcerpc_pipe *p, 
1452                                const char *name, struct policy_handle *handle)
1453 {
1454         struct spoolss_OpenPrinterEx r;
1455         struct spoolss_UserLevel1 userlevel1;
1456         NTSTATUS status;
1457
1458         if (name && name[0]) {
1459                 r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s", 
1460                                                    dcerpc_server_name(p), name);
1461         } else {
1462                 r.in.printername = talloc_asprintf(tctx, "\\\\%s", 
1463                                                    dcerpc_server_name(p));
1464         }
1465
1466         r.in.datatype           = NULL;
1467         r.in.devmode_ctr.devmode= NULL;
1468         r.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
1469         r.in.level              = 1;
1470         r.in.userlevel.level1   = &userlevel1;
1471         r.out.handle = handle;
1472
1473         userlevel1.size = 1234;
1474         userlevel1.client = "hello";
1475         userlevel1.user = "spottyfoot!";
1476         userlevel1.build = 1;
1477         userlevel1.major = 2;
1478         userlevel1.minor = 3;
1479         userlevel1.processor = 4;
1480
1481         torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
1482
1483         status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &r);
1484
1485         torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
1486         
1487         torture_assert_werr_ok(tctx, r.out.result, "OpenPrinterEx failed");
1488
1489         return true;
1490 }
1491
1492 static bool test_OpenPrinterEx(struct torture_context *tctx, 
1493                                struct dcerpc_pipe *p, 
1494                                const char *name)
1495 {
1496         struct policy_handle handle;
1497         bool ret = true;
1498
1499         if (!call_OpenPrinterEx(tctx, p, name, &handle)) {
1500                 return false;
1501         }
1502
1503         if (!test_GetPrinter(tctx, p, &handle)) {
1504                 ret = false;
1505         }
1506
1507         if (!test_EnumForms(tctx, p, &handle, false)) {
1508                 ret = false;
1509         }
1510
1511         if (!test_AddForm(tctx, p, &handle, false)) {
1512                 ret = false;
1513         }
1514
1515         if (!test_EnumPrinterData(tctx, p, &handle)) {
1516                 ret = false;
1517         }
1518
1519         if (!test_EnumPrinterDataEx(tctx, p, &handle)) {
1520                 ret = false;
1521         }
1522
1523         if (!test_PausePrinter(tctx, p, &handle)) {
1524                 ret = false;
1525         }
1526
1527         if (!test_DoPrintTest(tctx, p, &handle)) {
1528                 ret = false;
1529         }
1530
1531         if (!test_ResumePrinter(tctx, p, &handle)) {
1532                 ret = false;
1533         }
1534
1535         if (!test_SetPrinterData(tctx, p, &handle)) {
1536                 ret = false;
1537         }
1538
1539         if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
1540                 ret = false;
1541         }
1542
1543         if (!test_ClosePrinter(tctx, p, &handle)) {
1544                 ret = false;
1545         }
1546         
1547         return ret;
1548 }
1549
1550 static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pipe *p)
1551 {
1552         struct spoolss_EnumPrinters r;
1553         NTSTATUS status;
1554         uint16_t levels[] = {1, 2, 4, 5};
1555         int i;
1556         bool ret = true;
1557
1558         for (i=0;i<ARRAY_SIZE(levels);i++) {
1559                 union spoolss_PrinterInfo *info;
1560                 int j;
1561
1562                 r.in.flags      = PRINTER_ENUM_LOCAL;
1563                 r.in.server     = "";
1564                 r.in.level      = levels[i];
1565                 r.in.buffer     = NULL;
1566                 r.in.offered    = 0;
1567
1568                 torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
1569
1570                 status = dcerpc_spoolss_EnumPrinters(p, tctx, &r);
1571                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
1572
1573                 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1574                         DATA_BLOB blob = data_blob_talloc(tctx, NULL, r.out.needed);
1575                         data_blob_clear(&blob);
1576                         r.in.buffer = &blob;
1577                         r.in.offered = r.out.needed;
1578                         status = dcerpc_spoolss_EnumPrinters(p, tctx, &r);
1579                 }
1580
1581                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
1582
1583                 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
1584
1585                 if (!r.out.info) {
1586                         torture_comment(tctx, "No printers returned\n");
1587                         return true;
1588                 }
1589
1590                 info = r.out.info;
1591
1592                 for (j=0;j<r.out.count;j++) {
1593                         if (r.in.level == 1) {
1594                                 /* the names appear to be comma-separated name lists? */
1595                                 char *name = talloc_strdup(tctx, info[j].info1.name);
1596                                 char *comma = strchr(name, ',');
1597                                 if (comma) *comma = 0;
1598                                 if (!test_OpenPrinter(tctx, p, name)) {
1599                                         ret = false;
1600                                 }
1601                                 if (!test_OpenPrinterEx(tctx, p, name)) {
1602                                         ret = false;
1603                                 }
1604                         }
1605                 }
1606         }
1607
1608         return ret;
1609 }
1610
1611 #if 0
1612 static bool test_GetPrinterDriver2(struct dcerpc_pipe *p, 
1613                                    struct policy_handle *handle, 
1614                                    const char *driver_name)
1615 {
1616         NTSTATUS status;
1617         struct spoolss_GetPrinterDriver2 r;
1618         uint32_t needed;
1619         uint32_t server_major_version;
1620         uint32_t server_minor_version;
1621
1622         r.in.handle = handle;
1623         r.in.architecture = "W32X86";
1624         r.in.level = 1;
1625         r.in.buffer = NULL;
1626         r.in.offered = 0;
1627         r.in.client_major_version = 0;
1628         r.in.client_minor_version = 0;
1629         r.out.needed = &needed;
1630         r.out.server_major_version = &server_major_version;
1631         r.out.server_minor_version = &server_minor_version;
1632
1633         printf("Testing GetPrinterDriver2\n");
1634
1635         status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
1636         if (!NT_STATUS_IS_OK(status)) {
1637                 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1638                 return false;
1639         }
1640
1641         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1642                 r.in.offered = needed;
1643                 status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
1644         }
1645                 
1646         if (!NT_STATUS_IS_OK(status)) {
1647                 printf("GetPrinterDriver2 failed - %s\n", 
1648                        nt_errstr(status));
1649                 return false;
1650         }
1651
1652         if (!W_ERROR_IS_OK(r.out.result)) {
1653                 printf("GetPrinterDriver2 failed - %s\n", 
1654                        win_errstr(r.out.result));
1655                 return false;
1656         }
1657
1658         return true;
1659 }
1660 #endif
1661
1662 static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, 
1663                                         struct dcerpc_pipe *p)
1664 {
1665         struct spoolss_EnumPrinterDrivers r;
1666         NTSTATUS status;
1667         uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1668         int i;
1669
1670         for (i=0;i<ARRAY_SIZE(levels);i++) {
1671
1672                 r.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1673                 r.in.environment = "Windows NT x86";
1674                 r.in.level = levels[i];
1675                 r.in.buffer = NULL;
1676                 r.in.offered = 0;
1677
1678                 torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
1679
1680                 status = dcerpc_spoolss_EnumPrinterDrivers(p, tctx, &r);
1681
1682                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDrivers failed");
1683
1684                 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1685                         DATA_BLOB blob = data_blob_talloc(tctx, NULL, r.out.needed);
1686                         data_blob_clear(&blob);
1687                         r.in.buffer = &blob;
1688                         r.in.offered = r.out.needed;
1689                         status = dcerpc_spoolss_EnumPrinterDrivers(p, tctx, &r);
1690                 }
1691
1692                 torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDrivers failed");
1693
1694                 torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
1695
1696                 if (!r.out.info) {
1697                         torture_comment(tctx, "No printer drivers returned\n");
1698                         break;
1699                 }
1700         }
1701
1702         return true;
1703 }
1704
1705 /** Test that makes sure that calling ReplyOpenPrinter()
1706  * on Samba 4 will cause an irpc broadcast call.
1707  */
1708 static bool test_ReplyOpenPrinter(struct torture_context *tctx, 
1709                                   struct dcerpc_pipe *pipe)
1710 {
1711         struct spoolss_ReplyOpenPrinter r;
1712         struct spoolss_ReplyClosePrinter s;
1713         struct policy_handle h;
1714
1715         r.in.server_name = "earth";
1716         r.in.printer_local = 2;
1717         r.in.type = REG_DWORD;
1718         r.in.unknown1 = 0;
1719         r.in.unknown2 = 0;
1720         r.out.handle = &h;
1721
1722         torture_assert_ntstatus_ok(tctx, 
1723                         dcerpc_spoolss_ReplyOpenPrinter(pipe, tctx, &r),
1724                         "spoolss_ReplyOpenPrinter call failed");
1725
1726         torture_assert_werr_ok(tctx, r.out.result, "error return code");
1727
1728         s.in.handle = &h;
1729         s.out.handle = &h;
1730
1731         torture_assert_ntstatus_ok(tctx,
1732                         dcerpc_spoolss_ReplyClosePrinter(pipe, tctx, &s),
1733                         "spoolss_ReplyClosePrinter call failed");
1734
1735         torture_assert_werr_ok(tctx, r.out.result, "error return code");
1736
1737         return true;
1738 }
1739
1740 bool torture_rpc_spoolss(struct torture_context *torture)
1741 {
1742         NTSTATUS status;
1743         struct dcerpc_pipe *p;
1744         bool ret = true;
1745         struct test_spoolss_context *ctx;
1746
1747         status = torture_rpc_connection(torture, &p, &ndr_table_spoolss);
1748         if (!NT_STATUS_IS_OK(status)) {
1749                 return false;
1750         }
1751
1752         ctx = talloc_zero(torture, struct test_spoolss_context);
1753
1754         ret &= test_OpenPrinter_server(torture, p, ctx);
1755
1756         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled");
1757         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled");
1758         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "EventLog");
1759         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopup");
1760         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopupToComputer");
1761         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MajorVersion");
1762         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MinorVersion");
1763         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DefaultSpoolDirectory");
1764         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "Architecture");
1765         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DsPresent");
1766         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersion");
1767         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersionEx");
1768         ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DNSMachineName");
1769         ret &= test_EnumForms(torture, p, &ctx->server_handle, true);
1770         ret &= test_AddForm(torture, p, &ctx->server_handle, true);
1771         ret &= test_EnumPorts(torture, p, ctx);
1772         ret &= test_GetPrinterDriverDirectory(torture, p, ctx);
1773         ret &= test_EnumPrinterDrivers(torture, p, ctx);
1774         ret &= test_EnumMonitors(torture, p, ctx);
1775         ret &= test_EnumPrintProcessors(torture, p, ctx);
1776         ret &= test_EnumPrinters(torture, p, ctx);
1777         ret &= test_OpenPrinter_badname(torture, p, "__INVALID_PRINTER__");
1778         ret &= test_OpenPrinter_badname(torture, p, "\\\\__INVALID_HOST__");
1779         ret &= test_OpenPrinter_badname(torture, p, "");
1780         ret &= test_OpenPrinter_badname(torture, p, "\\\\\\");
1781         ret &= test_OpenPrinter_badname(torture, p, "\\\\\\__INVALID_PRINTER__");
1782         ret &= test_OpenPrinter_badname(torture, p, talloc_asprintf(torture, "\\\\%s\\", dcerpc_server_name(p)));
1783         ret &= test_OpenPrinter_badname(torture, p, 
1784                                         talloc_asprintf(torture, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p)));
1785
1786
1787         ret &= test_AddPort(torture, p);
1788         ret &= test_EnumPorts_old(torture, p);
1789         ret &= test_EnumPrinters_old(torture, p);
1790         ret &= test_EnumPrinterDrivers_old(torture, p);
1791         ret &= test_ReplyOpenPrinter(torture, p);
1792
1793         return ret;
1794 }