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